Redis学习:Redis哨兵(Sentinel)、Redis集群(Cluster)

Redis学习:Redis哨兵(Sentinel)、Redis集群(Cluster)

1. Redis哨兵(Sentinel)

1. 是什么

  1. 哨兵和主从复制结合使用,来提高可用性
  2. 在Redis主从复制时,当主机宕机时,则此时从机也会原地待命等待主机恢复,不会选举一个新的主机,此时就无法保证高可用
  3. 引入哨兵对整个主从集群进行监控,当主机宕机时,由哨兵根据选举算法选举一个从机作为新的主机,实现主从互换和高容错备份
  4. 哨兵监控redis的状态,当master宕机时,会根据投票数自动选举一个从机作为新的主机
  5. 哨兵的作用就是监控redis的状态(包括master和slave),当master宕机时,选举一个slave变成新的哨兵

2. 能干嘛

  1. 每个客户端只是一个master或者一个slave,而哨兵要监控主从redis,即一个哨兵要监控多个redis服务器和客户端
  2. 主从监控:监控主从redis库运行是否正常
  3. 消息通知:可以将故障转移的结果发给客户端
  4. 故障转移(自动容错):如果master异常,会自动进行主从切换,将其中一个slave转换为master
  5. 配置中心:客户端(master或者slave)通过连接哨兵来获得当前Redis服务的主节点地址

3. 怎么玩

  1. 架构
    1. 三台哨兵,自动监控和维护集群,不存放数据,只监控redis服务器
    2. 哨兵不存放数据,只监控redis服务器,也是个redis服务器,故也需要端口号进行启动
    3. 之所以要有哨兵集群,是为了防止哨兵和master都宕机,故多设置几个哨兵,并且当master宕机后,由多台哨兵进行投票来选举新的master
    4. 并且master宕机必须多台哨兵都认为master宕机时才会认为是宕机
    5. 哨兵不存放数据,只起到监控作用,并在发现master出现错误后进行故障转移
    6. 哨兵不存放数据,只进行监控
  2. 配置(会被动态修改
    1. 将redis中自带的sentinel.conf配置文件拷贝出来,并对自己的哨兵进行配置,然后根据该配置文件对哨兵进行启动
    2. sentinel.conf配置文件基础配置和redis服务器一样,但要对sentinel的配置进行单独配置,指定要监控的redis_master主服务器和quorum客观最少下线次数以及所监控的master的密码
    3. 在sentinel.conf中对 sentinel monitor配置项进行配置,来指定该哨兵所监控的redis主从服务器以及指定quorum:确认客观下线的最少哨兵数量,即对于监控的该master,只有当至少quorum个哨兵认为master挂掉才是真正的挂掉
    4. 因为网络原因,某个哨兵可能误以为master挂掉,此时是主观下线,但不是真的挂掉,故要配置quorum配置项,指定客观下线的最少哨兵数量
    5. 也可以配置主观下线的时间,当超过这个时间,该哨兵就会认为当前监控的主机master发生了宕机当有quorum个哨兵认为master主观下线,则该master会被认为客观下线
  3. 启动主从redis
    1. 哨兵的默认端口号是26379,和redis服务器的6379不一样
    2. 对每个哨兵均要创建一个配置文件,并设置基础配置以及与哨兵有关的配置项,然后对该配置文件启动服务器就可开启哨兵
    3. redis主从复制配从不配主,只对slave服务器进行配置来指定master的IP和PORT,如果有密码也要设置密码权限,此时就可开启主从复制
    4. master主机不需要进行配置,配从不配主,但要对master设置密码配置项masterauth “password”,以防止该服务器变为从机,故要设置访问新主机的密码
    5. 虽然是配从不配主,但也要对主机的conf文件中配置masterauth配置项,以防止该主机后续变为从机后要访问新的主机
    6. 配置完成后根据conf配置文件来启动对应的redis主从服务器以及哨兵服务器,然后使用 info replication来查看主从信息从机不可写入只可读取,只有主机才可以写入
  4. 启动哨兵集群
    1. 为了防止master和哨兵全部宕机,故要设置多个哨兵进行监控
  5. 实战
    1. 去官网查看使用方法出现错误先看日志
    2. 指定哨兵所监控的master,然后哨兵会通过master来自动获得其slave的信息,指定哨兵所监控的master服务器
    3. 且启动哨兵后会自动对哨兵的配置文件添加一些配置项,配置文件会动态修改
    4. 当master宕机时,所有的从机会先断开连接,此时由哨兵先选举出leader,然后从slave中选举出新的master,然后发送心跳包重新连接,当选举结束后,从机就都会连接,此时会选择对应的从机变为新的master,并修改配置文件
    5. 而且会对已经宕机的master修改配置文件,使其变为新的master的slave此时就算原来的master重新连接,依旧不会变为master而是作为新的master的slave
    6. 当master宕机后,哨兵会先认为是主观下线(可以通过配置项来设置客观下线的时间),当有quorum个哨兵认为是主观下线时,该master就会被认为是客观下线
    7. master宕机后会变为新选举的master的slave,此时就算重新恢复也不会变为master
    8. 可以查看log文件来查看执行过程
  6. 问题及总结
    1. Broken Pipe:断开的管道,当master宕机后,此时主从之间的管道会断开,数据会中断,如果访问过快就会出现该错误,只需要等待一会就会恢复
    2. 当master宕机时,哨兵Sentinel会先认为主观下线(通过配置项配置最大连接时间,超过就会认为是主观下线),然后进行投票,当有quorum个哨兵都认为是主观下线时就会对该master认为是客观下线,此时就会从slave中选举新的master,然后会对所有的master和slave的配置进行修改此时原来的master会变为新master的slave原来的slave会变为新的master的slave
    3. 因为原来的master如果恢复后会变为新的master的slave,故必须在原来的master的配置文件中设置masterauth配置项
    4. 当重新选举后,所有sentinel的配置文件conf均会被动态修改,此时配置文件中的master会变为新选举的master的IP和PORT,其他配置项也会物理修改;所有的master和slave的redis服务器的配置文件也会被修改!!!
    5. 当主从切换时候,master和slave已经sentinel的配置文件均会被动态修改
    6. 很少出现所有的sentinel全部宕机失效的情况
    7. 一个哨兵可以同时监控多个master,对每组指定一个name,并对相应的name进行配置,一个哨兵可以监控多个master

4. 运行流程和选举原理

  1. 当哨兵监控的master发生故障失效后,会由sentinel投票选举出新的master,并对master、slave以及sentinel修改配置文件;哨兵数量一般采取奇数台
  2. SDown(Subjectively Down)主观下线
    1. 主观下线是该sentinel所监控的master超过设置的时间未响应而认为是主观下线
    2. 主观下线SDown时单个sentinel主观上检测到的master的状态,可以在配置文件中进行配置超时时间,当sentinel发出了PING心跳包后,master超时未响应就会认为是主观下线
    3. 一个哨兵认为主观下线不可以认为master就是宕机
    4. 只有当认为该master主观下线的sentinel的个数大于等于配置的quorum个时该master才会被认为客观下线
  3. ODown(Objectively Down)客观下线
    1. 只有多个哨兵都认为该master主观下线后,才可以认为该master客观下线
    2. 只有master客观下线后才会重新进行选举新的master
    3. 通过在sentinel monitor配置项中设置对该master的quorum,即只有当主观下线的个数大于等于quorum后才会被认为是客观下线
    4. quorum是客观下线的依据
  4. 通过Raft算法选举出**领导者哨兵leader
    1. 第一个发现master主观下线的sentinel会成为leader,然后由leader来选举新的slave成为master
    2. 先通过Raft算法选举出leader领导者哨兵后再由leader哨兵选举出master
    3. 当master认为客观下线(ODown)后,会选举新的master,此时会先选举出领导者哨兵由领导者哨兵来选举新的master,并不是所有的哨兵来选举新的master,而是先选举领导者哨兵,然后由领导者哨兵来选举新的master(failover故障迁移)
    4. 通过Raft算法来选举出leader哨兵Raft算法是先到先得(早起的鸟儿有虫吃),某个哨兵向别的哨兵发送leader申请,别的哨兵只会同意第一个申请
    5. 判断主观下线的哨兵节点向其他哨兵节点发送master宕机如果超过半数的哨兵节点判断master节点进入客观下线的状态,那么率先判断进入主观下线的哨兵将成为领头sentinel
    6. 某个哨兵认为当前的master发生宕机后,就会向监控该master的其他哨兵发送信号如果认为主观下线的哨兵数量大于quorum时,就会认为该master客观下线,此时第一个发现主观下线的哨兵就会被认定为leader哨兵,由其来进行新的master的选举
  5. 由leader哨兵选举新的master进行failover故障迁移
    1. 新主登基:选举新的master
      1. 根据优先级priority越高offset大的以及RUNID小的来从健康的slave中选举出新的master
      2. 从剩余的健康的slave中选举出新的masterpriority(高) -> replication offset(大) -> Run ID(小)!
      3. 先根据slave的priority来选举,谁的priority高就选举谁为新的master,priority可以在配置文件中进行配置,越小优先级越高
      4. 如果priority一样的话,则谁的replication offset(复制偏移量,越大则数据越多)大选举谁为新的master,replication offset是当前slave的数据同步位置,因为延迟所有不一定同步
      5. 如果replication offset一样时,则根据Run ID最小的作为新的master
    2. 群臣俯首:slave改变master
      1. 选举出新的master后,sentinel会对新master执行 slaveof no one 命令使其变为master并通过slaveof命令使得其余的slave变为新master的slave,且原来的master也会变为新master的slave
      2. 在master切换过程中,会动态的修改sentinel、master和slave的配置文件
      3. 故障迁移过程中会动态修改slave、master和sentinel的配置文件,当选举出新的master后,会修改该服务器的配置文件变为master,然后对所有的slave修改配置文件使其成为新master的slave,并修改sentinel的配置文件监控新的master
    3. 旧主拜服:原master变为slave
      1. 在选举出新的master后,原来的master也会变为新master的slave
      2. 此时原来master重新连接时,就会变为slave,故要在master中也要设置访问master密码的参数项masterauth
    4. 上述流程均由sentinel独立完成,无需人工干预

5. 使用建议

  1. 哨兵集群+主从复制不可以保证数据零丢失!!
  2. 哨兵集群+主从复制,并不可以保证数据零丢失!!!,因为当宕机到选举新的master会用很长时间,此时就不可以写入新数据。使用集群!!
  3. 哨兵应该设置多个且为奇数,应该为集群来保证高可用
  4. 各个哨兵节点的硬件配置应该一致

2. Redis集群(Cluster)

1. 是什么

  1. 由于数据量过大,单个master复制集难以承担,因此对多个复制集进行集群,形成水平扩展,每个复制集只负责存储整个数据的一部分,这就是redis集群
  2. 重点是集群的算法和架构
  3. redis集群就是对外一个整体,内部包含多个实例
  4. redis集群就是一个提供在多个redis之间共享数据的程序集,允许有多个master,redis集群就是多个master构成的共享数据集

2. 能干嘛

  1. 集群允许多个master每个master可以多个slave,且这些master共享数据集
  2. 集群cluster内置了sentinel,可以自动实现故障转移,不需要再使用哨兵(先通过Raft算法得到leader,然后再选举新的master)
  3. 集群cluster自带sentinel的故障转移机制,内置了高可用支持,无需再使用sentinel
  4. 一个集群中有多个master共享数据,所以客户端不需要连接集群中的所有节点,只需要连接一个可用节点即可,但要使用 -c 集群模式(路由分发)开启客户端

3. 集群算法:分片、槽位slot

  1. 分布式key模式介绍
    1. redis集群共有16384个slot槽位,且最多配置1000个master节点,每个节点均匀管理着部分槽位
    2. redis槽位slot有16384个集群节点master最大1000个
    3. 集群的每个master节点处理槽位的一部分子集
  2. redis集群的槽位slot
    1. redis一共有16384个槽位slot每个槽位均可以存放数据,且每个master节点(最多1000个)管理一部分槽位
    2. redis没有使用一致性hash,而是使用了hash槽概念,对于每一个key,先通过算法得到其存放的槽位
  3. redis集群的分片
    1. 每个master服务器就是一个分片,每个分片管理着一部分slot槽位
    2. redis集群会将存储的数据分散到多个master_redis机器上,这就成为分片,即集群中的每个master_redis节点实例都被认为是一个分片每个分片管理集群槽位slot的一个子集
    3. 当读写数据时,根据key通过哈希槽算法找到对应槽位slot,然后取模找到管理该槽位的分片(master_redis节点),对该redis服务器进行读写操作即可
  4. 优势
    1. 方便扩缩容数据分派查找
    2. 需要扩缩容时,只需要将槽位移动到新增的节点上,或者移出去即可,此时并不会停止服务,不会造成集群不可用,不需要重新洗牌,不会对已经存放的数据造成影响
  5. slot槽位映射方式
    将数据的key映射到对应的槽位slot的算法
    1. 哈希取余分区
      1. 直接对集群中master_redis节点的数量进行取余来确定将key存放到哪个redis中
      2. 优势:容易进行计算映射关系
      3. 缺点:不易扩缩容,此时需要重新进行映射,且原来的数据的映射关系会发生错误,要重新洗牌
    2. 一致性哈希算法分区
      1. 为了解决分布式缓存数据变动和映射问题,固定值取模,使得每个key的hash值不会发生改变
      2. 目的是当服务器个数变动时尽量减少影响客户端到服务器的映射关系,对于哈希取余算法,当扩缩容时,会导致映射分母改变,此时原来的映射关系均发生
      3. 即使用固定值进行取模形成哈希环,此时每个key的哈希值是不变的,然后对每个节点根据ip找到对应的位置,然后对key找到对应的位置后顺时针寻找最近的节点进行存储,此时当扩缩容时,只会对对应节点附近的数据有影响,但可能会造成数据切斜
      4. 三大步骤
        1. 算法构建一致性哈希环
          1. 形成一个首尾相连的环形全量哈希空间使得key的哈希值的范围不受分母的影响(对全量集进行取模)
        2. 服务器IP节点映射
          1. 将各个服务器根据某个规则进行哈希映射确定在哈希环中的位置
        3. key落到服务器的落键规则
          1. 先对key根据hash函数确定在节点中的位置,然后顺时针行走遇到的第一台服务器就是存储的节点![[Pasted image 20241028130334.png]]
      5. 优点:容错和扩展
        1. 具有容错性,当某一个节点宕机的时候,只会影响某一段的数据,而且可以继续寻找下一个服务器进行存储
        2. 具有扩展性,当扩展一个节点时,不需要对所有的数据进行重新洗牌
      6. 缺点:数据倾斜(分布不均匀)
        1. 当节点很少时,可能会导致大部分数据全落到一个节点上
    3. 哈希槽分区
      1. 是什么
        1. 因为一致性哈希算法存在数据倾斜问题,故引入哈希槽算法,设置固定数量的hash槽16384个,让每个key求hash后%16384得到对应的槽位(固定的,不会被节点影响),而且对每个节点均匀分配所管理的哈希槽,此时当扩缩容时,只需要修改节点所对应的哈希槽即可,不需要修改数据
        2. 哈希槽的是指就是一个数组,共2^14个槽slot共有16384个哈希槽slot
        3. 在数据和节点之间加了一层哈希槽(没有什么是加一层解决不了的),用于管理数据和节点之间的映射关系,相当于节点上放的是槽slot,槽中放的是数据
        4. 哈希槽数目是固定的故每个key对应的哈希槽也是固定的),对每个节点都分配一定数量的哈希槽(大致均匀),此时只需要在对应的哈希槽中找数据即可
      2. 哈希槽的计算
        1. 对数据的key进行哈希函数得到哈希值,然后对16384取模得到映射的哈希槽位置,然后根据槽和节点的映射就可以得到对应的节点,此时就得到了key和节点的映射关系
      3. 为什么redis集群的最大槽数是16384?
        1. 可以节省大量的空间来存储,使得心跳包(包含完整配置信息)的大小变得更小,不需要那么多(最多1000个节点,每个平均16个槽就够了);用bitmap存储压缩比高,传输容易
        2. redis心跳包中会包含节点的完整配置,如果使用2^16 个槽,此时槽的配置项的大小会很大(每个节点的槽要8k,共65k个槽),而如果使用2^14 个槽,此时空间为2k * 16k ,会大量节省空间消耗
        3. 而且规定的redis集群中节点的个数不超过1000个节点太多时会导致网络拥堵),所以不需要太多的插槽,故16384个就足够了,均匀分配每个节点16个左右
        4. redis底层对于节点对应的哈希槽是通过bitmap来存储的,在传输过程中会压缩,槽位越少,空间越小,压缩比越高,传输越容易
  6. redis集群不保证强一致性(cp),在特定情况下会写丢失,如果某个master宕机后还未来得及同步时,此时就会写丢失,加一层会解决大部分问题,但也会出现新的问题,redis集群不保证强一致性,redis集群也会造成数据丢失,不保证强一致性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值