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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 如何让redis 迁移大key的restore性能提升6倍 redis支持migrate key的命令,支持从源redis节点迁移key到目标节点上,目标节点再执行restore命令,将数据加载进内存中。

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

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

1. 原生redis restore的性能瓶颈

通过扁鹊工具分析,可以看到cpu的运行情况如下:
before.jpg
查看源码可知,migrate 遍历出来的zset 中的hashtable值和score,序列化之后打包给目标节点。
目标节点在反序列后重新构造了zset的结构,包括zslinsert, dictadd 等操作。当数据量越大时,重构的代价也就越大。

2. 优化方法

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

2.1 zset的数据结构

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

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 有多层结构
zsl.jpg

描述的难点在于每一层上的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实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 缓存 NoSQL
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
|
26天前
|
消息中间件 缓存 NoSQL
Redis 高并发竞争 key ,如何解决这个难点?
本文主要探讨 Redis 在高并发场景下的并发竞争 Key 问题,以及较为常用的两种解决方案(分布式锁+时间戳、利用消息队列)。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Redis 高并发竞争 key ,如何解决这个难点?
|
27天前
|
存储 NoSQL PHP
PHP与Redis结合使用,提升数据存储性能
随着互联网应用的发展,PHP与Redis的结合成为提升数据存储性能的重要手段。PHP作为流行的服务器端语言,常用于网站开发;Redis作为高性能内存数据库,以其快速读写能力,有效优化数据访问速度,减轻数据库压力。两者结合通过缓存机制显著提升应用响应速度,支持高并发场景下的稳定性和可扩展性。
|
2月前
|
NoSQL Unix Redis
Redis 键(key)
10月更文挑战第15天
33 1
|
2月前
|
缓存 监控 负载均衡
如何解决Redis热点Key问题?技术干货分享
【10月更文挑战第2天】在Redis的使用过程中,热点Key问题是一个常见的性能瓶颈。热点Key指的是那些被频繁访问的Key,它们可能导致Redis服务器的负载不均衡,进而影响整体性能。本文将深入探讨热点Key问题的成因、影响以及多种解决方案,帮助读者在实际工作中有效应对这一挑战。
85 3
|
2月前
|
NoSQL Redis
redis 的 key 过期策略是怎么实现的(经典面试题)超级通俗易懂的解释!
本文解释了Redis实现key过期策略的方式,包括定期删除和惰性删除两种机制,并提到了Redis的内存淘汰策略作为补充,以确保过期的key能够被及时删除。
56 1
|
3月前
|
存储 缓存 NoSQL
Redis 大 Key 对持久化的影响及解决方案
Redis 大 Key 对持久化的影响及解决方案
47 1
|
2月前
|
NoSQL 安全 Redis
AWS迁移教程,Redis迁移到Elasticache
AWS迁移教程,Redis迁移到Elasticache
|
3月前
|
存储 缓存 NoSQL
Redis中大Key与热Key的解决方案
在工作中,Redis作为一款高性能缓存数据库被广泛应用,但常遇到“大key”和“热key”问题。“大key”指单个键包含大量数据,导致内存消耗高、性能下降及持久化效率降低;“热key”则是频繁访问的键,会引起CPU占用率高、请求阻塞等问题。本文详细分析了这些问题的定义、影响、原因,并提供了相应的解决方案,如合理设置缓存时间和数据结构、拆分大key、采用热点数据分片等方法。
258 4
Redis中大Key与热Key的解决方案
|
3月前
|
缓存 NoSQL PHP
使用PHP-redis实现键空间通知监听key失效事件的技术与代码示例
通过上述方法,你可以有效地在PHP中使用Redis来监听键空间通知,特别是针对键失效事件。这可以帮助你更好地管理缓存策略,及时响应键的变化。
98 3