作者:羽洵
众所周知,Redis是一款广受欢迎的内存数据库,广泛应用在多种业务场景中。开源Redis提供了分布式的Redis集群方案,可用于提升内存容量存储和扩展高速性能。集群架构必不可免涉及到数据节点分片的弹性扩缩容、分片间的数据迁移。而Redis社区版集群的数据迁移能力却一直以来是开发者、运维者们多有诟病的地方。
社区Redis集群版迁移数据有诸多不足,Tair推出的新一代以Slot复制为原理的无感迁移数据架构,已在阿里云上提供长期稳定的服务。
Tair是阿里云国产自研的云原生内存数据库,在完全兼容Redis的基础上,提供了丰富的数据模型和企业级能力来帮助客户构建实时在线场景。其中兼容Redis这块的能力,我们称之为Tair for Redis。同时,Tair与新型存储介质——持久内存的高效结合,相比内存,成本降低30%以上,并能做到数据持久化和提供近似于内存的性能。目前,Tair已广泛应用于政务、金融、制造、医疗和泛互联网等各行业客户,满足客户的高速查询和计算场景。
本文将阐述社区开源版本集群数据迁移的技术,阿里云Tair for Redis集群早期对社区迁移数据的增强改进以及演进到新一代基于Slot复制的无感数据迁移原理。
1、开源Redis Cluster的数据迁移技术
开源Redis Cluster(7.0)采用的是无中心控制节点的分布式架构。节点间通过gossip协议传递集群拓扑结构等元信息,集群拓扑结构以Slot单位作为数据的最小集合,各个节点独自归属一部分的Slot。数据迁移即是在节点间移动Slot。
开源Redis Cluster以Per Key的方式迁移Slot。Per Key是指在迁移过程中通过遍历迁移部分key的方式完成单个Slot的迁移。
Per Key迁移的流程具体的流程:
1、在目的分片上设置importing状态。
2、在源分片上设置migrating状态。
3、从源分片上获取到被迁移的Slot的key列表。
4、给源分片发送migrate命令,带上需要被迁移的部分key列表。migrate命令是一个同步阻塞命令,触发源分片将key发送给目标分片restore后,源分片上将key删除。如此反复直至源分片上被迁移的Slot的key列表为空。
5、通过setslot命令将被迁移的Slot归属于目标节点。
Per Key迁移的痛点
这套流程带来的问题也很明显:
- migrate命令执行过程中因同步阻塞的特性,所以无法再处理其他业务请求。迁移大key则会造成长时间的阻塞,进一步放大服务的可用性问题。
- 如果在源分片访问的key不存在,则会被重定向到目标分片,多一次路由转发。
- 多key命令请求在重定向到目标分片后,如果目标分片上有key不存在,目标分片将返回TryAgain错误给客户端,此次请求失败。
- 在迁移过程中,单个Slot的数据分散在两个分片上,如果迁移出现异常,将无法平稳回滚整个迁移流程。
- 早期阿里云Tair for Redis集群也针对Per Key数据迁移技术做了增强改进。
2、Tair for Redis集群早期Per Key数据迁移增强技术
Tair for Redis Per Key数据迁移增强改进主要集中在改进同步阻塞、改进大key迁移阻塞、缩短迁移交互时长,以此提升迁移速度从而降低业务的有损感知影响。具体的改进点以下阐述。
同步流程改成异步化
源节点在执行原生的migrate命令时,进行以下三个操作:
1、dump key,序列化打包key的payload。
2、将打包好的payload通过restore的命令发送给目标节点。
3、收到目标节点回复后删除key。
三个操作在一个同步阻塞的命令中执行,因此造成执行期间其他业务请求较长时间不可访问。
Tair for Redis则借助自研的内核迁移状态机将这三个步骤拆解成三个异步流程,减少同步阻塞的时长。
大key拆分成chunk迁移
如果Per Key迁移到大key,dump key、传输payload、restore key三个阶段耗时都会相应增长,即便异步化也不能降低单个操作的耗时影响。
Tair for Redis迁移前先判断被迁移的key是否属于大key,大key则被分解成chunk,按chunk为单位完成dump key、传输payload、restore key三个阶段,每个阶段的耗时减少,可有效减少对其他key的访问阻塞影响,但整体延长了对该大key的迁移耗时。
尚未解决的痛点
这些优化改进并不能解决掉全部的痛点问题,依然存在的痛点有:
1、贯穿迁移过程中的moved和ask重定向路由语义。
2、带有空key的多key请求,返回客户端TryAgain错误。
3、无法一键稳定回滚。
在持续的探索和演进后,阿里云Tair for Redis集群推出了基于Slot复制的新一代数据迁移技术。
3、Tair for Redis集群基于Slot复制的无感数据迁移技术
Redis主备通过数据复制的方式进行数据同步。Tair for Redis在借鉴主备复制的技术基础上,内核衍生出了Slot复制技术(Slot Mig),概括的说即是在两个节点间通过复制一部分Slot进行数据同步,并且加上中心控制器(CS)精准动态控制毫秒级别的Slot Wait禁写技术,在集群拓扑结构切换时通过moved语义让客户端请求重定向到新的数据节点上,从而做到对业务读写请求无损,迁移过程对用户业务无感知。
Slot Mig迁移的流程
具体的流程:
1、CS对目标分片发起数据迁移命令slotRepl。
2、目标节点对源节点发起slotPsync命令。
3、源节点生成被迁移的Slot的存量快照数据。
4、目标节点接收被迁移的Slot的存量快照数据。
5、源节点同步给目标节点被迁移的Slot的增量数据。
6、CS动态评估增量同步差值,控制在毫秒级别的差值范围内向源节点发起slotReplWait禁写被迁移的Slot。如禁写时长超过阈值,将自动触发回滚禁写状态,恢复业务正常可写状态。
7、CS等待同步完成后切换集群拓扑结构。客户端旧请求根据moved语义被重定向到新的集群拓扑节点。
8、删除源节点的已迁移完成的Slot数据。
Slot Mig迁移的优势
如上所述,整个迁移过程的优势:
- 无只读错误,客户端链接无闪断。
- 只在切换集群拓扑结构后对旧链接请求返回moved语义。
- 大key、多key请求无影响。
- 单个Slot的数据不再分散在两个节点上,流程可一键回滚恢复。
4、对比总结
文末总结下阿里云Tair for Redis集群新一代无感数据迁移和社区开源版Redis集群数据迁移的特性对比。
阿里云 Tair for Redis 集群Slot Mig |
社区开源Redis 集群(7.0)Per Key |
|
迁移过程中命中被迁移Slot的业务请求状态 |
出现两种状态: 1、切换集群拓扑结构前可正常访问 2、切换集群拓扑结构后根据moved语义重定向到目标节点,无ask语义 |
出现三种状态: 1、key在源节点上不存在时根据moved以及ask语义重定向到目标节点 2、带有空key的多key请求,返回客户端TryAgain错误 3、正在执行migrate命令,其他请求被block住 |
迁移过程是否出现只读错误 |
否 |
否 |
迁移过程中是否出现禁写 |
毫秒级别的Slot禁写 |
分两种情况禁写: 1、多key写请求中有空key 2、被migrate命令阻塞住 |
迁移过程中客户端链接是否有闪断 |
无 |
无 |
迁移未结束是否可以回滚 |
可 |
否 |
阿里云Tair for Redis集群的无感数据迁移技术已服务于阿里云上的变配功能(扩缩容节点),欢迎大家购买体验。