当前位置:   article > 正文

Redis的几种集群模式和工作原理_redis 集群模式的工作原理

redis 集群模式的工作原理

目录

 

主从模式

哨兵模式

介绍

开发配置方式

哨兵模式的工作机制

监控Master是否宕机下线

      down-after-milliseconds和flags参数

      quorum参数

Master节点宕机下线后进行故障转移

哨兵模式的缺点

Cluster模式

Master提供读写Salve只做备份

高可用的实现

子集群中Master的选举机制

数据分布式存储  

什么情况下Cluster集群不再可用

开发配置方式


主从模式

之前的文章: https://blog.csdn.net/qq_29569183/article/details/103101286

主节点提供读写,从节点提供读服务,最简单的集群模式。

优点:读写分离,提高性能

缺点:master节点挂了以后,redis就不能对外提供写服务了,因为剩下的slave不能成为master

哨兵模式

基于主从模式的缺点,哨兵模式的优点之一就是高可用。

介绍

主从模式中,当master节点挂了以后,slave节点不能主动选举一个master节点出来,那么我就安排一个或多个sentinel来做这件事,当sentinel发现master节点挂了以后,sentinel就会从slave中重新选举一个master。一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个master主节点服务和从节点服务,发现某个master主节点服务下线时,自动从下线主节点服务下的从节点中挑一个将其转换为master节点

开发配置方式

  1. redis:
  2. sentinel:
  3. nodes: 127.0.0.1:16379,127.0.0.1:16380,127.0.0.1:16381 # 哨兵的IP:Port列表
  4. master: mymaster #自定义名称
  5. timeout: 1000 # 连接超时时间(毫秒)
  6. password: passwd123
  7. lettuce:
  8. pool:
  9. max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
  10. max-idle: 8 # 连接池中的最大空闲连接 ,默认值也是8
  11. max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
  12. min-idle: 2 # 连接池中的最小空闲连接 ,默认值也是0
  13. shutdown-timeout: 100ms

哨兵模式的工作机制

哨兵模式主要解决了高可用的问题,在单Master多Slave的集群中,通过哨兵集群来监控redis集群的可用性。

监控Master是否宕机下线

Sentinel集群中的每个节点默认以 每10秒一次 的频率向各Redis服务节点发送PING命令,如果在down-after-milliseconds配置值(单位是毫秒内都没有收到有效回复,当前Sentinel 节点会将该服务器的flags属性标记为SRI_S_DOWN标识,SDOWN状态即主观下线;当前Sentinel 节点会通知其他的 Sentinel 节点去确认这个节点是否下线,如果有足够多(quorum参数配置的)数量的Sentinel 节点都认为 master 下线,则该master 节点真正被Sentinal集群确认被ODOWN状态客观下线之后Sentinel 节点会更改对下线节点发送PING命令的频率,改为1秒一次,直到宕机节点恢复后移除客观下线状态,但是宕机的master节点重新启动后将不再是master,而是做为slave接收新的master节点的同步数据。

      down-after-milliseconds和flags参数

这个参数是redis.conf文件中配置的判断SDOWN状态的时间参数,如果指定时间内没有收到有效回复就更改Flags属性标记为SDOWN状态

      quorum参数

这个参数是在redis.conf文件中配置的sentinel monitor语句中的参数,是判断ODOWN状态的条件,sentinel monitor语句参数的含义如下

sentinel monitor <master-group-name> <ip> <port> <quorum>

例如下面的配置,表示 quorum参数为2,也就是说下面配置作用的节点判断Master节点进入ODOWN状态的条件是 包含自身在内至少2个 sentinel节点认为master下线了。如果多个Sentinel的配置如果不一致,那每个Sentinel判断ODOWN的依据也就不相同。

sentinel monitor mymaster 127.0.0.1 6379 2

Master节点宕机下线后进行故障转移

在Sentinel集群确认集群的Master客观下线后,Sentinel集群中通过Raft协议算法在Sentinel集群中选取出一个临时Sentinel Leader来对下线的master进行故障转移:

1.在slave中选择一个节点修改配置文件成为新的master节点。选举算法依次根据断开连接时长、优先级排序、复制数量、进程 id几个条件进行选举。

  • 如果与哨兵连接断开的比较久,超过了某个阈值,该节点就不能参与选举了;
  • 在拥有选举权的节点中,判断哪个优先级高(在配置文件redis.conf里可以设置(replica-priority 100),数值越小优先级越高)谁可以成为Master节点。
  • 如果优先级相同,判断谁从 master 中复制的数据最多(复制偏移量最大),选最多的那个成为Master;
  • 如果多个节点的复制数量也相同,就选择进程 id 最小的那个。

2.修改其他slave的配置文件的slaveof属性,指向新的master。 

哨兵模式的缺点

无法实现动态扩容每台 Redis 服务器仍然存储相同的数据,当系统中的数据量增多后只能垂直扩展即增加单机内存空间和性能,所以就有了下面要说的Cluster模式。

Cluster模式

随着redis的应用场景越来越多,数据量越来越大,在主从节点同步时fork子进程会阻塞主线程,而且reids数据量越大,阻塞越长。于是从3.0开始,官方提供了一个名为Redis Cluster的方案,用于实现切片分布式存储的redis集群,这种模式会将Redis的数据根据一定的规则分配到集群中的多个Master节点上,这种模式可以很好地实现水平扩展,适合数据量巨大的缓存要求,当数据量不是很大使用sentinel即可。 

Master提供读写Salve只做备份

cluster模式下默认存储数据使用的都是db0数据库。在cluster集群下,默认情况下master用于接收读写而slave则用于备份当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。但如果不介意读取的是redis-cluster中有可能过期的数据并且对写请求不感兴趣时,则亦可在salve节点执行readonly命令,将slave设置成可读,然后在slave执行get获取相关的key实现salve节点读请求。不过在连接断开后该节点就会关闭读功能。

高可用的实现

在cluster集群模式下,客户端与服务节点直接连接,不需要通过中介(哨兵)这种东西,而且只需要连接集群中的某一个节点就可以无需连接多个节点。那么没有哨兵是如何保证高可用的呢

cluster中的每一个节点都可以与其他节点进行连接通信,不在通过专用的监视服务来判断节点的健康状况。Cluster集群中通过下面的机制实现哨兵的作用

  1. 1.它们之间通过互相的ping-pong判断是否节点可以连接上。
  2. 2.如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。
  3. 3.如果集群中某个Master节点宕机,会根据选举机制从其从节点中选举出主节点提供读写操作

子集群中Master的选举机制

因为集群中每个节点都是可以互相通信的,如果集群中某一个master节点宕机,那么会在该master的所有从节点中重新选举产生新的master节点出来

在master宕机后,该master节点的salve节点不会立刻进行选举,而是在各自的延迟时间(根据延迟计算公式计算出来的)后发起选举,选举流程如下:

  1. slave发现自己的master变为FAIL;
  2. 等待延迟时间后开始发起选举,将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST信息;
  3. 其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
  4. 收集FAILOVER_AUTH_ACK,如果超过半数则选举成功该从节点会成为新的Master节点
  5. 广播Pong通知其他集群节点。

为什么要在延迟时间后发起选举? 

一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票。

延迟时间计算公式  

DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms 

SLAVE_RANK表示此slave已经从master复制数据的总量的rank,根据公式可以推断出,理论上(random随机事件存在不确定)持有最新数据的slave的延迟时间越短,就越先发起选举。

而公式中random随机时间应该是避免众多salve同一时间发起选举,类似于缓存雪崩的错时机制

数据分布式存储  

Redis Cluster方案采用哈希槽来处理数据和实例之间的映射关系。这里有两个映射关系:键值对与哈希槽的映射关系和哈希槽与实例的映射关系。

Cluster群集至少需要3主3从,且每个实例使用不同的配置文件。Cluster集群中共分16384个hash slot。每个master分得一部分slot,其算法为:hash_slot = crc16(key) mod 16384 ,这就找到对应slot。多个master节点采用hash slot的算法实现数据的分布式存储,Cluster模式其实牺牲了强一致性,从分布式角度分析符合AP理论,同时与哨兵和主从模式相比,更有效的防止了数据丢失(分布式存储降低了节点故障造成的数据丢失概率),而且易于实现水平扩容。

可能会有疑问:为什么不直接把键值对映射到实例呢,这样维护一个映射关系看起来更简单??原因如下:

1.由于整个集群存储key的数量是无法预估的,key的数量非常多时,直接记录每个key对应的实例映射关系,这个映射表会非常庞大,这个映射表无论是存储在服务端还是客户端都占用了非常大的内存空间;

2.在集群中,实例和哈希槽的对应关系不是一成不变的,例如当实例有新增或删除时,Redis需要重新分配哈希槽;为了负载均衡,Redis需要把哈希槽在所有实例上重新分布一遍。

而使用上面说的 键值对与哈希槽的映射关系和哈希槽与实例的映射关系这种方式,再结合Redis Cluster提供的重定向机制,最终要维护的关联关系数量就少得多而且维护起来也简单。

客户端和集群实例建立连接后,实例就会把哈希槽的分配信息发给客户端。客户端把一个键值对操作请求发给一个实例,如果这个实例没有这个键值对映射的哈希槽,这个实例就会给客户端返回MOVED命令的响应结果,包含新实例的访问地址。如下,MOVED命令表示,客户端请求的键值对所在的哈希槽12356,实际是在192.168.9.66这个实例上。

  1. GET hello:key (error)
  2. MOVED 12356 192.168.9.66:6379

什么情况下Cluster集群不再可用

  1. 如果某个节点和所有从节点全部挂掉,我们集群就进入faill状态。这个很好理解,由于是分布式存储,当某一个主从集群全部宕机时整合集群中就无法提供该集群节点存储的数据了。
  2. 如果有一半以上的主节点宕机,那么我们集群同样进入fail状态。 

开发配置方式

  1. redis:
  2. cluster:
  3. nodes: 31.20.145.52:6378,20.20.150.52:6376,35.20.120.52:6379,33.20.160.53:6374,80.20.910.53:6372
  4. timeout: 1000 # 连接超时时间(毫秒)
  5. password: passwd123
  6. lettuce:
  7. pool:
  8. max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
  9. max-idle: 8 # 连接池中的最大空闲连接 ,默认值也是8
  10. max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
  11. min-idle: 2 # 连接池中的最小空闲连接 ,默认值也是0
  12. shutdown-timeout: 100ms

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/684417
推荐阅读
相关标签
  

闽ICP备14008679号