Redis 的三种集群模式
Redis 的常用的集群方式主要有以下三种,分别是主从复制模式、哨兵模式、Redis-Cluster集群模式,那么下面我们就分别了解一下这三种集群模式的优点与缺点。
主从复制模式
主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(Master),后者称为从节点(Slave),数据的复制是单向的,只能由主节点到从节点。Redis 的主从复制模式一般是由一主一从(一个主节点+一个从节点)或一主多从(一个主节点+多个从节点)的形式来构成。主节点负责写操作,从节点负责读操作,从节点从主节点复制数据,通过这种方式也可以实现读写分离。
下面我们一起看看主从复制的原理
- 从服务器连接主服务器,发送 SYNC 命令(即 sync command 命令),请求同步链接
- 主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令
- 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令
- 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照
- 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
- 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;(从服务器初始化完成)
- 主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令(从服务器初始化完成后的操作)
了解了主从复制模式的概念和原理后,我们一起总结一下主从复制模式的优缺点:
优点
1、支持主从复制,主机会自动将数据同步到从机,可以进行读写分离,同时缓解了主库的压力。
2、Master Server 是以非阻塞的方式为 Slaves 提供服务。所以在 Master-Slave 同步期间,客户端仍然可以提交查询或修改请求;Slave Server 同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。
缺点
1、由于 Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致部分读写请求失败,需要等待机器重启或者手动将某台从节点升级为主节点才能解决。而且在主机宕机时,宕机前部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
我们看完主从复制模式后,可能有些小伙伴就发现了一些问题:主从复制模式下,当主节点宕机后,需要手动将某台从节点切换为主节点,这需要人工干预,不仅费时费力,而且还会造成一段时间内服务不可用,这个问题该如何解决呢 接下来就需要请哨兵模式登场了....
哨兵模式
为了解决我们刚刚谈到的问题,Redis 2.8 中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。其实哨兵模式也是一种主从复制模式,只不过增加了哨兵的功能,哨兵的功能主要有两点:第一是监控主服务器和从服务器是否正常运行;第二是当主节点出现故障时自动将从节点转换为主节点。
哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式,所有节点上都需要部署哨兵模式,哨兵模式会监控所有的 Redis 工作节点是否正常,当 Master (主节点)出现问题的时候,因为其他节点与主节点失去联系,因此会进行投票,投票过半就认为这个 Master (主节点)的确出现问题,然后会通知其他哨兵,并从 Slaves (从节点)中选取一个作为新的 Master(主节点)。既然涉及到了投票过半的要求,那么参与投票的哨兵就必须为单数,即整个运行哨兵的集群的数量不得少于3个节点。在选取新的主节点的过程中,我们又可以将整个过程细分为两步,分别为“选哨兵领导”和“由哨兵领导推举主节点”。
第一步:选哨兵领导
哨兵A: 哎哎哎!!!兄弟们,我发现主节点掉了啊!!!你们赶紧选我当头,我去选一个新的子节点来做主节点!!!
哨兵B: 额...行吧,我选你当头,虽然我很想当领导,但是也没啥经验呢,还是你来吧。
哨兵C: 不行!!我不支持你,我才是当领导的材料!!
哨兵A: 哨兵C你去一边子的,咱们就三个兄弟,我和哨兵B都支持,那我就是领导了
P.S. 如果此时有多个哨兵同时参选,则在等待任意时间后重新发起投票,直到选出了领头的
第二步:哨兵领导选择主节点
哨兵A: 我来看看以前的领导留下来的《如何选择主节点》里是怎么写的...翻书ing... 根据书里的记载,我需要按照健康性(哨兵发送ping命令后的响应时间长短,时间越短则越健康)、完整性(选择复制偏移量最大,也就是复制最完整的从节点)、优先级高低(选择配置文件中从节点优先级配置最高的,即replica-priority,其默认值为100)来进行主节点的挑选工作,如果有两个从节点都具备这三个条件的话,那就根据节点启动时分配的 run id 来决定谁做主节点(runid越小越有可能被选择为主节点)...
哨兵A: 还是查书有用啊,要不我还真不知道怎么干,我去选主节点啦~~
P.S. 选择主节点的过程又称为故障转移的过程
这里有一点是需要注意的,哨兵的下线分为两种,分别是主观下线(我认为你掉线了)和客观下线(我们认为你掉线了)。每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次 ping 命令做一次心跳检测。如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。客观下线是针对于主节点来说的概念,也就是说只有发生了客观下线,才会执行我们上面所说的两个步骤;如果从节点和哨兵节点发生故障,被哨兵主观下线后,则不会再有后续的客观下线和故障转移操作。
通过上面的讲解,我们也就可以总结出哨兵模式的优点了:哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有,同时使用哨兵模式后主从节点可以自动切换,可以让系统更健壮,可用性更高。
Redis-Cluster集群模式
Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在 Redis3.0 上加入了 Cluster 模式,实现的 Redis 的分布式存储,即每台 Redis 节点(Node)上存储不同的内容,很大程度上节约了内容。需要注意的是,集群中的节点也是分为主节点和从节点的,只有主节点负责读写请求和集群信息的维护,而从节点只进行主节点数据和状态信息的复制。Redis-Cluster采用无中心结构,它有以下三个特点
① 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
②节点的失效(下线)是通过集群中超过半数的节点检测失效时才生效。
③ 客户端与 Redis 节点直连,不需要中间代理层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
接下来我们一起看看 Redis-Cluster 集群模式的工作流程:
在 Redis 的每一个节点上,都有这么两个小东西,一个是插槽(slot),它的的取值范围是:0-16383,另一个就是cluster,可以理解为是一个集群管理的插件。当 Redis 拿到了需要存取的 key 时,Redis 会根据 CRC16 算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。为了保证高可用,Redis-Cluster 集群引入了主从模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。
虽说 Redis-Cluster 集群引入了主从模式,但是也带来了一个问题:如果集群中具有A、B、C三个节点,如果节点B失败了,整个集群就会因缺少5461-10922这个范围的插槽而不可使用;如果为每个节点添加一个从节点A1、B1、C1整个集群便有三个Master节点和三个slave节点组成,当在节点B失败后,那么集群选举B1位为主节点继续服务。但是当B和B1都失败后,集群将不可用。
有些小伙伴看到这里可能会产生一个疑问:为什么插槽数是16384个呢?为什么不能是65535或者是其他数值呢?其实关于这个问题,作者已经给了我们一个回复
The reason is:
- Normal heartbeat packets carry the full configuration of a node, that can be replaced in an idempotent way with the old in order to update an old config. This means they contain the slots configuration for a node, in raw form, that uses 2k of space with16k slots, but would use a prohibitive 8k of space using 65k slots.
- At the same time it is unlikely that Redis Cluster would scale to more than 1000 mater nodes because of other design tradeoffs.
So 16k was in the right range to ensure enough slots per master with a max of 1000 maters, but a small enough number to propagate the slot configuration as a raw bitmap easily. Note that in small clusters the bitmap would be hard to compress because when N is small the bitmap would have slots/N bits set that is a large percentage of bits set.
用一句话总结出来就是:由于 Redis 节点之间通讯会相互交换槽信息,那如果槽过多(意味着网络包会变大),网络包变大,就意味着会过度占用网络的带宽,同时作者认为 Redis 集群中节点数不会超过1000个,所以作者就取了16384这个数,即可以将数据合理打散至 Redis 集群中的不同实例,又不会在交换数据时导致带宽占用过多。
小结
本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨
以上就是一文带你了解Redis的三种集群模式的详细内容,更多关于Redis集群模式的资料请关注我们其它相关文章!