如何让redis 迁移大key的restore性能提升6倍

redis支持migrate key的命令,支持从源redis节点迁移key到目标节点上,目标节点再执行restore命令,将数据加载进内存中。以800MB,数据类型为zset(skiplist) 的 key为例,测试环境为本地开发机上两台redis,忽略网络的影响。原生的redis 在restore时执行需要163s,优化后的redis执行需要27s。

1. 原生redis restore的性能瓶颈

通过扁鹊工具分析,可以看到cpu的运行情况如下:

查看源码可知,migrate 遍历出来的zset 中的hashtable值和score,序列化之后打包给目标节点。
目标节点在反序列后重新构造了zset的结构,包括zslinsert, dictadd 等操作。当数据量越大时,重构的代价也就越大。

2. 优化方法

已知瓶颈在重构数据模型,所以优化的思路就是将源节点的数据模型也一并序列化打包给目标节点。目标节点解析后预构造出内存,再按解析后的member填鸭进去即可。
zset 可以说是redis中最为复杂的数据结构,以zset为例,阐述如何优化。

2.1 zset的数据结构

zset 由两个数据结构组成,一个是hashtable 结构的dict,存储的是每个member的值及对应的score,另一个是skiplist的zsl,按序排列每个member。如图所示:

2.2 序列化zset结构模型

redis中,zset的dict 和 zsl 中member 和score的内存是共享的,两种结构,一份内存。如果在序列化中描述一份数据两种索引成本反而更高。

2.2.1 序列化dict模型

再细看cpu的性能消耗,hashtable部分更多消耗在计算index, rehash(即预分配的hash table的size不满足时,需要使用一个更大size的hashtable,将旧的table挪到新的table中),compare key(在链表中遍历判断key是否已经存在)。
基于此,在序列化时带上最大的hashtable的size,restore时指定生成size大小的dict table,去掉rehash。
restore zsl 结构,反序列化出member,score,重新计算member的index,插入指定index的table中,因为遍历出来的zsl不会有出现key冲突的情况,省去compare key,直接将相同index的member接入到链表中。

2.2.2 序列化zsl模型

zsl 有多层结构

描述的难点在于每一层上的zskiplistNode总共的level层不知道,并且需要描述每一层的前后节点关系,同时需要考虑兼容性。
综合以上考虑,决定从整个zsl最高的level层次遍历,序列化的格式是:
level | header span | level_len | [ span ( | member | score ... ) ]
level : 第几层的数据
header span : header 节点在该层上的span值
level_len : 该层上总的节点数
span : 节点在该层上的span值
member | socre :因为在0层以上的level 有冗余的节点,通过span值相加可以判断是否是冗余节点,冗余节点则不序列化member | score, 非冗余节点带上member | score。反序列时的算法亦然。

结束语

如此zset的数据模型描述完成。对restore的性能更快,但是同时会消耗更多的带宽,多出来的带宽是描述节点的字段。800MB的数据,优化后比优化前多出20MB数据。

云数据库Redis版(ApsaraDB for Redis)是一种稳定可靠、性能卓越、可弹性伸缩的数据库服务。基于飞天分布式系统和全SSD盘高性能存储,支持主备版和集群版两套高可用架构。提供了全套的容灾切换、故障迁移、在线扩容、性能优化的数据库解决方案。欢迎各位购买使用:云数据库 Redis 版

时间: 2024-10-26 20:37:00

如何让redis 迁移大key的restore性能提升6倍的相关文章

iPhone4十大特色解析:分辨率提升4倍升级iOS4

比特网(ChinaByte)6月8日消息 美国旧金山当地时间6月7日上午10点(北京时间8日凌晨1点),苹果全球开发者年度盛会WWDC2010拉开帷幕.苹果CEO乔布斯在开幕演讲中发布新一代iPhone手机"iPhone 4". iPhone 4在功能上远超iPhone 3GS,升级之处多达百项,很多方面超出之前的预期.乔布斯在主题演讲中重点讲到了8项最主要的改进,其中硬件方面包括全新的外观设计.革命性的Retina显示屏幕.以及3轴陀螺仪.A4处理器.全新的拍摄系统等. 系统和软件方

【沉淀】实例迁移、Insert和写入性能——数倍,甚至数十倍提升,HybridDB for MySQL负责人王骞谈自己经历和收获

<沉淀>是展示专家风采的人物栏目.它呈现每个专家独一无二的人生经历.认识和感悟的同时,也能帮助你沉淀技术,收获对技术和人生的判断.我们的想法是:"若你想精进为一个很厉害的人,不妨细细品味这些技术牛人背后的沉淀."如果你想了解这些云栖专家更多分享时,请点击云栖专家频道,当然我们也欢迎你往前走一步,成为我们的云栖专家(https://yq.aliyun.com/expert),与技术大牛一起"煮酒论英雄". 技术人是怎样的一群人?一千个人,或许有一千个答案.

阿里云redis大key搜索工具

Redis提供了list.hash.zset等复杂类型的数据结构,业务在使用的时候可能由于key设计不合理导致某个key过大,由于redis简单的单线程模型,业务在获取或者删除大key的时候都会有一定的影响,另外在集群模式下由于大key的产生还很容易导致某个子节点的内存满,综上所述我们需要提供大key的搜索工具. 初始化环境 安装python客户端 下载python客户端 wget "https://pypi.python.org/packages/68/44/5efe9e98ad83ef5b7

添加到redis里的key乱码

问题描述 添加到redis里的key乱码 使用spring-data-redis往redis中添加数据,按照官方文档要求注入redistemplate模板, @Autowired private RedisTemplate<String, String> redisTemplate = null; 此时调用不会有问题, public void put(String key, String hashKey, String value) { redisTemplate.opsForHash().p

有人做过把项目中log4j迁移到logback吗,我迁移后做了性能对比,好像logback似乎没有什么性能提升啊?

问题描述 有人做过把项目中log4j迁移到logback吗,我迁移后做了性能对比,好像logback似乎没有什么性能提升啊? 解决方案 都差不多,楼主不必劳费心力了

大数据征信如何提升金融机构风控能力

近年来,互联网金融的迅猛发展,对线上线下金融机构的风险控制都带来了较大的挑战.一方面,以商业银行为代表的传统金融机构,其主流风控策略主要以央行征信报告为主要数据源,以专家经验或专家规则为评判策略.过于定性的风控方法,虽然降低了坏账率,但是不利于业务发展,容易错失很多有效客户:另一方面,许多新兴的互联网金融机构,由于所掌握的客户信息有限,风控经验的薄弱和风控执行手段不够专业,其逾期率和坏账率远超于银行. 好在随着移动互联网时代的来临,从电子商务到互联网金融,人们在网络上产生的数据"足迹"

[20171102]测试大量子光标对性能影响2.txt

[20171102]测试大量子光标对性能影响2.txt --//跟开发讲关于绑定变量的问题,总有人讲不是有一个参数cursor_sharing能快捷简单地解决问题,设置cursor_sharing=force, --//实际上合理的使用绑定变量才是王道. --//许多开发人员设置这个参数带来的各种bug,我第一次在8i下使用差点到处服务器cpu资源耗尽,好在我知道我当时的改动,修改回来一些正常. --//我当时还记得设置这个参数报ora-00600错误. --//我想起以前10g下遇到设置cur

[20171028]测试大量子光标对性能影响.txt

[20171028]测试大量子光标对性能影响.txt --//做一个测试例子说明存在大量子光标对性能影响. 1.环境: SCOTT@test01p> @ ver1 PORT_STRING                    VERSION        BANNER                                                                               CON_ID ------------------------------

数据库迁移大字段问题

问题描述 现在我们的项目让我做这样一个功能:把SqlServer,DB2,Oracle的数据迁移到新的Oracle数据库中,其他字段都好说,就是大字段我不知道怎么解决,请各位大虾给个思路,尽量详细些,先谢谢了! 解决方案 解决方案二:各位帮帮我啊解决方案三:为什么不直接迁移库导出库再导进新库,还要做功能?有什么特别的理由么