zoukankan      html  css  js  c++  java
  • Redis 内存优化方式

    内存优化方式与参数

    关闭 Redis 的虚拟内存[VM]功能,即 redis.conf 中 vm-enabled = no
    设置 redis.conf 中 maxmemory ,用于告知 Redis 当使用了多少物理内存后拒绝继续写入的请求,可防止 Redis 性能降低甚至崩溃
    可为指定的数据类型设置内存使用规则,从而提高对应数据类型的内存使用效率
    Hash 在 redis.conf 中有以下两个属性,任意一个超出设定值,则会使用 HashMap 存值
    hash-max-zipmap-entires 64 表示当 value 中的 map 数量在 64 个以下时,实际使用 zipmap 存储值
    hash-max-zipmap-value 512 表示当 value 中的 map 每个成员值长度小于 512 字节时,实际使用 zipmap 存储值
    List 在 redis.conf 中也有以下两个属性
    list-max-ziplist-entires 64
    list-max-ziplist-value 512
    在 Redis 的源代码中有一行宏定义 REDIS-SHARED-INTEGERS = 10000 ,修改该值可以改变 Redis 存储数值类型的内存开销

    ------------转载------------------------------------

    业务场景:Redis 作为目前主流的key-value 内存数据库,因为其高并发,存储查询速率快,我们很多的热点数据均会存储到Redis 中,如果数据量较大的话,昂贵的内存消耗也是一笔很大的支出,因此Redis 内存优化是很有必要的。
    以下是笔者所在公司的Redis 服务的内存使用情况

    Redis内存使用率.jpg

    上图可以看到:Redis内部的对象数高达:1,599,098,020(15亿),其内存使用高达 371G ,并且持续的增多,需要我们尽快优化,释放多余的空间。
    目前存储的现状
    • 目前Redis 存储使用的数据类型为:string
    • key 的构成为: type:business_tag:user_id:item_id:item_detail_id
    • value 的组成为:
      {
        "expireTime": "253402271999000",
        "value": "test_test_test_test"
      }
    主要优化手段如下
    • 存储结构变更 由string 变更为 hash

    主要内存优化依据是:
    Redis 内部Hash 数据结构的编码方式主要有两种:

    • OBJ_ENCODING_ZIPLIST(压缩列表)
    • OBJ_ENCODING_HT(哈希表)

    Redis 内部会根据数量的情况自适应的选择这两种编码方式中 最优 的一种,这种操作完全对用户透明,选择压缩列表存储的依据主要是:

    • 数据条目较少(hash-max-ziplist-entries)即 Hash 的filed 较少 field 个数 默认小于 512
    • 数据值较少(hash-max-ziplist-value)即Hash的value 值较少 value 值的长度小于64

    即默认存储为压缩列表存储的条件为

    field_num < hash-max-ziplist-entries && value.length < hash-max-ziplist-value

    综上所述:根据前面看到的业务场景,完全满足此种场景,这是选择由string存储变为 Hash存储的一个原因

    OBJ_ENCODING_ZIPLIST 编码的主要思想是:空间换时间,适应于字段个数比较少,字段值也比较小的场景。
    • key的优化

    为了全方位的对内存进行优化,那么key 以及 hash 的field 进行必要的压缩

    • 如果是字符串的话可以进行分段优化,针对数据进行16进制转换
    • 字符串使用简写方式

    key_value.png

    迁移后Redis 实例存储对比

    为保证测试的准确性,私有服务器安装Redis 进行优化前与优化后内存空间测试
    以下为整个测试过程:

    • docker 安装 Redis
    docker pull redis

    clipboard.png

    docker ps # 查询当前容器

    clipboard.png

    docker exec -it ****** /bin/bash # 进入容器内部
    redis-cli -a 123456 #打开Redis-cli连接Redis 
    info memory  # 查询安装完成后Redis 的内存使用情况

    clipboard.png

    以上为Redis 服务搭建过程的简单记录

    • 数据存储测试(未优化前)

    优化前 存储 1000000 string 类型数据如下:

    -- string key
    0:1:201155:100:545953888100
    -- string value
    {
      "value": "3.6230093077568726-0.3630194103106919100",
      "expireTime": "2147483647"
    }

    clipboard.png
    由上图内存存储可知:未优化前 1000000 条 string 消耗内存:200.12M
    执行完测试,将此前存入的数据删除

    clipboard.png

    • (1)数据存储测试(优化key value)

      • 压缩key的长度:将最后的无业务标识的字符串转换为:16进制
      • 压缩value 的长度:压缩value的数据

    clipboard.png
    优化后 存储1000000数据使用内存:139.10M 相比较优化前优化内存:30%
    偷偷窃喜下,如果进行此次优化:节省内存:115G

    • (2)数据存储测试(优化key value)

      • 压缩key的长度:将最后的无业务标识的字符串转换为:64 进制
      • 压缩value 的长度:压缩value的数据

    clipboard.png
    此次优化变化不明显,仅仅降低了 不到1M ,疑惑脸。。。
    于是乎对于key的长度不进行压缩,只对value值进行压缩进行测试结果如下:

    clipboard.png
    由以上测试可得:1000000数据,内存使用率为 146.59M ,故此 16/64 进制对key的压缩影响并不明显。

    • (3)数据存储测试(优化key value)

      • 压缩key的长度:将最后的无业务标识的字符串转换为:64 进制
      • 压缩value 的长度:压缩value的数据,不在存储json,只存储,attr1:value,attr2:value2

    clipboard.png

    以上优化后,存储1000000数据使用内存:123.86M,优化达到:38%

    • (4)数据存储测试(优化key value)

      • 压缩key的长度:将最后的无业务标识的字符串转换为:64 进制
      • 压缩value 的长度:压缩value的数据,不在存储json,只存储,attr1:value

    clipboard.png
    经过第4次进行优化,内存的占用依旧与第三次相差很小,但是仍然在减少,此次内存占用为 123.71M,继续对value值做压缩

    • (5)数据存储测试(优化key value)

      • 压缩key的长度:将最后的无业务标识的字符串转换为:64 进制
      • 压缩value 的长度:压缩value的数据,只存储,attr1:value, exp(过期时间戳)压缩为64进制

    clipboard.png
    经过第5次进行优化,内存占用达到了 116.27M ,优化达到:42%

    • 数据存储测试(优化key value的基础上进行 数据结构变更:变更为HASH)

    clipboard.png

    见证奇迹的时刻到了,变更HASH 结构后,1000000数据内存占用 100.49M,优化50%

    思考:

    Redis 的内存优化,需要配合业务场景进行针对性的优化,并不是一味的已减少内存为主要的优化目标,我们也应该在空间和时间上找到一个平衡点进行恰当的优化,就那此次优化来说,虽然内存减少了 50% ,但是在实际应用中考虑到,该数据对于效率要求比较高,所以在进行编码解码过程中也存在时间的消耗,最终并不是采用内存优化度最大的那种方案。

  • 相关阅读:
    CodingTrip
    CodingTrip
    Linux下面查找含有特定的字符的文件
    Linux下TCP/IP协议的Socket编程
    显示Apache服务器里面访问量排在前10的ip地址
    c语言的详细编译过程
    WebStorm设置编辑器中的字体大小
    Sublime多行编辑快捷键
    Aptana 中去掉“Missing semicolon”提醒
    公认的媒体类型
  • 原文地址:https://www.cnblogs.com/weigy/p/12677458.html
Copyright © 2011-2022 走看看