首页 > 数据库 > 数据库开发技术 > Redis Cluster去中心化设计的思考

大家好,我是石页兄;少年莫悲白发,赤心当映满江
欢迎关注微信公众号「架构染色」交流和学习
分布式存储⼀般都是通过多副本的形式保证数据可靠,多副本之间使⽤⼀致性协议保证数据⼀致,所以⼀般都需要⼀个 Leader 节点负责协调写⼊,常见的分布式存储如Zookeeper的工作模式即是 Leader 协调写入,⾼并发场景下 Leader 单节点会成为系统的瓶颈,单节点的瓶颈本质就是中心化的问题。解决的办法可考虑采用去中心化的设计,比如 Redis 的 Cluster 模式。
Redis Cluster 模式 采用了去中心化的设计并且具备以下能力:
1) 可扩展性
2) 高可用
3)负载均衡
4) 错误恢复
本质就是数据和请求落在哪个节点上,或者说是一个节点都负责哪些数据的问题,即分布式存储,需要通过 数据分区策略(算法)来解决,并且需考虑以下问题:
在以下分区算法中,个人比较偏好 Redis cluster 的虚拟槽分区
同一范围内的数据聚集连续,节点跨度小
实现简单,扩缩容时需迁移的数据量大,整倍扩容时,相对迁移的数据量少
将数据散落在 2 的 32 次方个 token(槽点更容易理解),节点随机分配到不同的 token,即每个节点管理一定连续范围的 token,数据 key 通过 hash 得到 token 后,即可知自己所属的节点
它能够在添加/移除一台缓存服务器的时候,尽可能小的改变已存在 key 的与节点映射关系,避免大量 key 的重新映射
服务节点太少时,容易因为节点分布不均匀而造成数据倾斜问题,然后引入虚拟节点的方式来解决数据散落的平衡性问题,增加的这一层跟下边的虚拟槽有异曲同工之处
即使如此,一致性 hash 对数据分布和节点位置的控制依然不够友好
《一切皆是映射:代码的本质》一致性哈希算法(consistent hashing)[1]一致性 hash 的一些问题[2]
因为一致性哈希算法的数据分布不均匀的问题,Google 在 2017 年提出了带有限负载的一致性哈希算法来解决这个问题,带有限负载的一致性哈希算法思想比较简单,给每个存储节点设置了一个存储上限值来控制存储节点添加或移除造成的数据不均匀,当数据按照一致性哈希算法找到相应的存储节点时,要先判断该存储节点是否达到了存储上限;如果已经达到了上限,则需要继续寻找该存储节点顺时针方向之后的节点进行存储
通过引入一层(槽),解耦数据和节点的关系 key 和槽的映射不变,槽在哪个节点的关系可变,槽成为集群内数据管理和迁移的基本单位,而槽的粒度小、边界清晰,简化了节点扩容和收缩难度,只需要关注数据在哪个槽,并不需要关心数据在哪个节点上。
固定映射关系,放大分布空间,数据均匀分布 虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,Redis Cluster 槽范围是 0~16383。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽
虚拟槽分区可以说比较好的兼容了数据均匀分布和扩展性的问题。
通过 redis 虚拟槽分区的实现,基于分治原则每个节点都具备了独立的读写能力,并且管理一部分数据, 那么客户端可以与每个节点独立建立链接,并做池化处理;这就从根本上解决了需要 leader 单点受限的问题。
重定向是高频操作,会带来性能损耗,而且在 slot 跟节点的关系不变更的情况下这个重定向也是重复的。数据 slot 的变更是低频的,如果这个 slot 和节点的映射关系,能够在向节点发起请求前明确,那么就会避免重定向的问题。那么通过同步 slot 和节点的映射关系(拓扑信息),即可实现智能寻址路由。
难免会遇到扩缩容的场景,优雅轻便的在线的方式将是我们的诉求。参考 redis cluster 的方式
缩容的情况下会有额外的节点下线逻辑。
特别注意:
数据迁移未完成前,并没有通知 slot 和 节点映射的变更,那么智能客户端依然会去原节点访问数据,此时需要另外一种重定向机制告诉客户端,数据正在迁移,新节点在哪里,你去新节点看看,这种机制就优雅的解决了在线迁移并保证了数据一致性;但需清楚这是有一定的性能损耗的,能否在系统高负载的时候做,需要压测演练。
我是石页兄,如果这篇文章对您有帮助,或者有所启发的话,欢迎关注笔者的微信公众号【架构染色】进行交流和学习,您的支持是我坚持写作最大的动力。
另外技术群中也有许多热心的大佬时常交流互助;可通过点击【架构染色】公众号主页右下角【交流探讨】获得笔者微信二维码,加微时备注“加群”即可,期待并欢迎您的加入。
《一切皆是映射:代码的本质》一致性哈希算法(consistent hashing): https://www.jianshu.com/p/8a608bc87680
[2]一致性 hash 的一些问题: https://www.jianshu.com/p/15697cafe487
[3]【原创】为什么 Redis 集群有 16384 个槽 : https://www.cnblogs.com/rjzheng/p/11430592.html
原文作者:架构染色;如有侵权,请联系管理员删除。