Redis 内存优化(1)

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

以下是笔者所在公司的Redis 服务的内存使用情况
image.png

上图可以看到: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进制转换
  • 字符串使用简写方式


    image.png
迁移后Redis 实例存储对比

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

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

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

  • 数据存储测试(未优化前)
    优化前 存储 1000000 string 类型数据如下:
-- string key
0:1:201155:100:545953888100
-- string value
{
"value": "3.6230093077568726-0.3630194103106919100",
 "expireTime": "2147483647"
}
image.png

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


image.png
  • 数据存储测试(优化key value)
    • 压缩key的长度:将最后的无业务标识的字符串转换为:16进制
    • 压缩value 的长度:压缩key的数据
      image.png

      优化后 存储1000000数据使用内存:139.10M 相比较优化前优化内存:30%
      偷偷窃喜下,如果进行此次优化:节省内存:115G
  • 数据存储测试(优化key value)
    • 压缩key的长度:将最后的无业务标识的字符串转换为:64 进制
    • 压缩value 的长度:压缩key的数据


      image.png

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


      image.png

      由以上测试可得:1000000数据,内存使用率为 146.59M ,故此 16/64 进制对key的压缩影响并不明显。
  • 数据存储测试(优化key value的基础上进行 数据结构变更:变更为HASH)
    image.png

    见证奇迹的时刻到了,变更HASH 结构后,1000000数据内存占用 100.49M,优化近50%
    此次测试的代码均可在github 传送门:[项目测试][1]
    [1]: https://github.com/zhaolg/DemoProject

详情可查看:https://segmentfault.com/a/1190000020483794

你可能感兴趣的:(Redis 内存优化(1))