Redis的三种集群模式
Redis的三种集群模式
概要
通过持久化功能(详情请参考文章《Redis的持久化方式》),Redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,因为持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据。 但是由于数据是存储在一台服务器上的,如果这台服务器出现硬盘故障等问题,也会导致数据丢失(单点故障)。
因此redis除了支持单机数据库的实现以外,还支持多机数据库(集群)的实现。
Redis支持三种集群方案
- 主从复制模式
- Sentinel(哨兵)模式
- Cluster模式
一、主从复制模式
1. 什么是主从复制?
单向复制:
将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。简单的说就是主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。
2. 主从复制的目的
读写分离、方便做容灾恢复
3. 主从复制的优缺点
优点:
1)避免单点故障:将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。
2)读写分离:master能自动将数据同步到slave,可以进行读写分离,分担master的读压力
3)同步非阻塞:master、slave之间的同步是以非阻塞的方式进行的,同步期间,客户端仍然可以提交查询或更新请求。
缺点:
1)不具备自动容错与恢复功能:master或slave的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端IP才能恢复。
2)数据不一致:如果master宕机前数据没有同步完,则切换IP后会存在数据不一致的问题。
3)难以支持在线扩容:Redis的容量受限于单机配置。
二、Sentinel(哨兵)模式
1. 什么是哨兵模式?
第一种主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。
哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。
原理:哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个 Redis 实例。
2. 哨兵模式的作用
1)通过发送命令,让 Redis 服务器返回监控其运行状态,包括主服务器和从服务器;
2)当哨兵监测到 master 宕机,会自动将 slave 切换成 master ,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
3. 多哨兵模式
然而一个哨兵进程对Redis服务器进行监控,也可能会出现问题(哨兵进程出现故障、错误的故障判定等),为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
4. 故障切换的过程
假设主服务器宕机,哨兵1首先检测到并认为主服务器不可用,此时仅为哨兵1的主观判断,称为主观下线。当其他哨兵也检测到主服务器不可用,且超过半数哨兵同意下线时,通过投票确认主服务器处于客观下线状态,并由一个哨兵发起故障转移(Failover)操作。切换成功后,通过发布订阅机制通知其他哨兵更新主从关系,实现主从切换。整个过程对客户端是透明的。
5. 哨兵模式的优缺点
优点:
1)哨兵模式是基于主从复制模式的,所有主从的优点,哨兵模式都具有。
2)主从可以自动切换,系统更健壮,可用性更高(可以看作自动版的主从复制)。
缺点:较难支持在线扩容:在集群容量达到上限时在线扩容会变得很复杂。
三、Cluster集群模式(Redis官方)
详细请参考文章《《Redis设计与实现》学习笔记-集群》
1. 什么是集群模式?
Redis Cluster是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能,从Redis3.0版本开始正式提供。
Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在 redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容。
在这个图中,每一个蓝色的圈都代表着一个 redis 的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
2. 集群的数据分片
1)槽指派
Redis集群通过分片的方式来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),数据库中的每个键都属于这个16384个槽的其中一个,集群中的每个节点可以处理0个或最多16384个槽。
当数据库中的16384个槽都有节点在处理时,集群处于上线状态(ok);相反地,如果数据库中有任何一个槽没有得到处理,那么集群处于下线状态(fail)。
2)哈希槽
Redis 集群没有使用一致性 hash,而是引入了哈希槽【hash slot】的概念。
Redis 集群有16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽。
计算键属于哪个槽:CRC16(key) & 16383
集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
- 节点 A 包含 0 到 5460 号哈希槽
- 节点 B 包含 5461 到 10922 号哈希槽
- 节点 C 包含 10923 到 16383 号哈希槽
3)支持在线扩容
Redis Cluster支持在线扩容,新增节点后通过槽迁移将数据分散到新节点,从而提高集群的可扩展性和负载均衡能力。整个过程对客户端透明且不中断服务,是Redis Cluster的一大优势。
Redis Cluster这种结构很容易添加或者删除节点:比如如果我想新添加个节点 D , 我需要将节点 A, B, C 中的部分槽移动到 节点D 上。如果我想移除节点 A ,需要将 A 中的槽移到 B 和 C 节点上,然后将没有任何槽的 A 节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
4)在 Redis 的每一个节点上,都有:插槽(slot)和 cluster ,
插槽(slot):取值范围是0-16383。
cluster:可以理解为是一个集群管理的插件。当我们的存取的 Key到达的时候,Redis 会根据 CRC16 的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
3. Redis集群的主从复制模型
为了保证高可用,Redis Cluster采用主从复制模型,每个主节点负责一个分片,并配置一个或多个从节点作为备份。当主节点宕机时,从节点通过选举接管成为新主节点。如果超过半数主节点检测到某主节点通信超时,则标记其为下线(fail);如果该主节点及其所有从节点都宕机,导致分片不可用,集群将进入下线状态(fail)状态(因为集群要求所有槽数据必须可用)
4. 集群的特点
1)所有的 redis 节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
2)节点的 fail 是通过集群中超过半数的节点检测失效时才生效。
3)客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
参考链接:
https://segmentfault.com/a/1190000022808576