Redis 7内存优化--2.优化slot-key
Redis Cluster需要保存slot-key的映射关系,在7.0之前使用Radix tree实现,它同时是实现Redis 5.0的Stream功能的基础。在新的7.0中,放弃了这种存储方式,巧妙地对DictEntry进行改造,从而实现内存优化,本文进行简单介绍,详细pr如下:
一、改造方法:
其整体思路就是,防止key名存在多个地方,把key相关的放到原始结构体中,可以有效防止键值较多时候的浪费(radix tree需要额外存储key)。
1. DictEntry改造
在dictEntry中加了一个void *metadata[]属性
改造前:
改造后:
2. 重新定义slot to keys
定义一个16384长度的slotToKeys数组
每个slotToKeys会将相同slot的DictEntry利用如下数据结构连接一起:
示意图如下:
3. 以添加key为例:
(1) 添加k-v(db.c)
(2) 添加映射关系(cluster.h cluster.c)
• 计算key对应的slot
• dictEntryNextInSlot和dictEntryPrevInSlot是定义clusterDictEntryMetadata中的prev和next
二、优化效果
这里偷懒发下PR中的数据,包括内存优化和性能变化两个方面
1. 内存优化
(1) 测试数据:前缀是key:NNNNNN
(2) 结果
(3) 结论
优化效果:在小value场景,优化了20%的空间(键名越长越明显)
2. 性能变化
(1) 压测命令
(2) 压测集群
(3) 压测结果
(4) 结论:
性能上写入提升明显,读取和更新下降5-10%
三、总结:
该优化思路清晰明了(不让key存多份,注:pr中有关expire dict的讨论),在小value、大量key的场景下在内存优化上能取得不错的效果。
文章转自公众号:Redis开发运维实战