一、redis的集群模式
redis的模式有以下几种:
- 单机模式(最简单的模式)
- 主从复制(最基础的模式)
- 哨兵模式(过渡模式)
- 集群模式(当前主流模式)
二、演变历史
redis的创始人antirez 早年是系统管理员,2007 年和朋友共同创建一个网站 LLOOGG.com,为了解决LLOOGG.com 网站的大量负载,决定自己写一个具有列表结构的内存数据库原型。于是redis诞生了。最早的redis很简单,只能单机运行,且支持的数据结构只有列表。
翻了很多资料,并没有找到主从复制是从那个版本提供出来的。不过这是一个很重要的功能,是其他模式的实现基础。
哨兵模式从redis 2.6开始,一开始并不是那么稳定。一直到redis2.8版本才稳定下来。于此同时,还有各种redis分片中间件,也作为redis集群的解决方案。
Redis3.0 是redis一个里程碑的版本,因为它有了集群模式(Redis Cluster)。在此之前,民间有很多Redis分布式方案,比较有名气的3种有Redis客户端分片、 twemproxy、 codis(豌豆荚)。尽管一开始人们对于redis的集群模式并不完全信赖,现在却是redis的主流集群解决方案。
三、技术揭秘
技术都是演化出来的,redis cluster模式其实是集成了单机、主从、哨兵的大成模式。单机自然不必说,集群都是有单机组成。主从模式核心是一种数据同步机制。
数据同步使得redis的数据可以在多个节点进行备份,这为Redis Cluster模式提供了异常恢复能力。原理是在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。
如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。同时,也可以通过redis命令主动进行同步,redis 2.8 之前使用sync [runId] [offset]同步命令进行数据同步,redis2.8之后使用psync [runId]命令进行数据同步。
实现了数据同步之后,哨兵模式的核心在于制定了主从切换的机制,实现了自动主从切换。数据同步后,主节点和从节点都有数据,在master宕机的情况下,原来是可以通过手动操作去切换slave为master,这种操作最大的问题在于需要人工介入,手动操作。哨兵模式提供了自动主从切换的能力。
哨兵模式下,区别于redis存储节点,会启动哨兵节点。哨兵是一个独立的进程,主要负责监控和通知。同时,可能会启动多个哨兵节点,以防止其中一个哨兵出现问题。
主从切换的事件机制,是一种选举算法。选举分4步:主观下线、客观下线、哨兵集群选举Leader、Leader选举主节点。第一步,主观下线:哨兵集群的每一个哨兵节点会定时对redis集群的所有节点发心跳包检测节点是否正常。如果一个节点在一定时间内没有回复哨兵节点的心跳包,则该redis节点被该Sentinel节点主观下线。第二步,客观下线:当redis节点被一个哨兵节点记为主观下线时,并不意味着该节点肯定故障了,还需要哨兵集群的其他哨兵节点共同判断为主观下线才行。该哨兵节点会询问其他哨兵节点,如果哨兵集群中超过一定数量的哨兵节点认为该redis节点主观下线,则该redis节点客观下线。如果客观下线的redis节点是从节点或者仅仅是哨兵节点,则操作到此为止,没有后续的操作了;如果客观下线的redis节点为主节点,则开始故障转移,从从节点中选举一个节点升级为主节点。第三步,哨兵集群选举Leader:如果需要从redis集群选举一个节点为主节点,首先需要从哨兵集群中选举一个哨兵节点作为Leader,以防止脑裂。每一个哨兵节点都可以成为Leader,当一个哨兵节点确认redis集群的主节点主观下线后,会请求其他哨兵节点要求将自己选举为Leader。被请求的哨兵节点如果没有同意过其他哨兵节点的选举请求,则同意该请求(选举票数+1),否则不同意。如果一个哨兵节点获得的选举票数达到Leader最低票数(quorum和哨兵节点数/2+1的最大值),则该哨兵节点选举为Leader;否则重新进行选举。第四步,决定新主节点:哨兵Leader会从redis从节点中选择一个redis节点作为主节点,选择过程先过滤故障的节点,再选择优先级最大的从节点作为主节点,如不存在则继续选择复制偏移量最大的从节点作为主节点,如不存在则继续选择runid最小的从节点作为主节点。至此,选举redis的master节点的过程就算完成了。
单机模式实现数据存储,主从模式解决了数据同步,哨兵模式提高了容灾能力。但是redis集群还有一个问题需要解决。就是水平扩展能力。随着redis应用越来越广泛,储存的数据量越来越大,单节点的redis的存储能力远远不足。主从模式在同一时间也只能有一个master,大大限制了redis的能力。于是redis3.0加入了Cluster。
相对于哨兵模式,集群模式没有了哨兵节点,也可以说每一个redis节点都是哨兵节点,实现了去中心化。尽管这是一种变革,可是并不是集群模式的核心。集群模式真正的核心是数据的分布式储存。
分布式存储就是将整块数据,按照规则分配到多个缓存节点。如果要将这些数据进行拆分,并且存放必须有一个算法。Redis Cluster 则采用的是CRC16一致性哈希算法。除此以外,为了让数据的拆分尽可能均匀,引入另一个重要的概念,虚拟节点机制。
在 Redis 中将存储空间分成了 16384 个槽,即16384个虚拟节点。缓存信息是用 Key-Value 的方式来存放的,在存储信息的时候,集群会对 Key 进行 CRC16 校验并对 16384 取(slot = CRC16(key)%16383)。得到的结果就是 Key-Value 所放入的槽,从而实现自动分割数据到不同的节点上。然后再将这些槽分配到不同的缓存节点中保存。
因为如果节点数量过少,可能出现CRC16计算后的数据不均衡地存到某个节点。节点数量越多,不均衡的可能行越小。
至于为什么是虚拟出16384个节点。后面再补充吧。
至此,redis的高可用机制就很完善了,集群模式也成为大型项目的主流模式。
本文介绍了Redis的集群模式,包括单机、主从复制、哨兵和集群模式的演变历程。Redis Cluster作为主流模式,结合了数据同步和主从切换,采用CRC16一致性哈希进行数据分布,实现分布式存储和高可用性。
1577

被折叠的 条评论
为什么被折叠?



