[Redis][哨兵][下]具体讲解

守听  论坛元老 | 2024-10-16 07:26:40 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 2027|帖子 2027|积分 6081


1.安装部署(基于Docker)

1.编排Redis主从节点



  • 编写docker-compose.yml

    • 创建/root/redis/docker-compose.yml,同时cd到yml所在⽬录中
    • 分析:docker中可以通过容器名字作为ip地址,进⾏相互之间的访问
    1. version: '3.7'
    2. services:
    3.         master:
    4.                 image: 'redis:5.0.9'
    5.                 container_name: redis-master
    6.                 restart: always
    7.                 command: redis-server --appendonly yes
    8.                 ports:
    9.                         - 6379:6379
    10.         slave1:
    11.                 image: 'redis:5.0.9'
    12.                 container_name: redis-slave1
    13.                 restart: always
    14.                 command: redis-server --appendonly yes --slaveof redis-master 6379
    15.                 ports:
    16.                         - 6380:6379
    17.         slave2:
    18.                 image: 'redis:5.0.9'
    19.                 container_name: redis-slave2
    20.                 restart: always
    21.                 command: redis-server --appendonly yes --slaveof redis-master 6379
    22.                 ports:
    23.                         - 6381:6379
    复制代码

  • 启动所有容器:docker-compose up -d
  • 查看运行日志:docker-compose logs

2.编排Redis-Sentinel节点



  • 分析:可以把redis-sentinel放到和上⾯的Redis的同⼀个yml中进⾏容器编排,但此处分成两组,主要是为了两⽅⾯

    • 观察⽇志⽅便
    • 确保Redis主从节点启动之后才启动redis-sentinel

      • 假如先启动redis-sentinel的话,可能触发额外的推举过程,混淆视听
      • 不是说先启动哨兵不⾏,⽽是观察的效果可能存在⼀定随机性


  • 编写docker-compose.yml

    • 创建/root/redis-sentinel/docker-compose.yml ,同时cd到yml所在⽬录中
    1. version: '3.7'
    2. services:
    3.         sentinel1:
    4.                 image: 'redis:5.0.9'
    5.                 container_name: redis-sentinel-1
    6.                 restart: always
    7.                 command: redis-sentinel /etc/redis/sentinel.conf
    8.                 volumes:
    9.                         - ./sentinel1.conf:/etc/redis/sentinel.conf
    10.                 ports:
    11.                         - 26379:26379
    12.         sentinel2:
    13.                 image: 'redis:5.0.9'
    14.                 container_name: redis-sentinel-2
    15.                 restart: always
    16.                 command: redis-sentinel /etc/redis/sentinel.conf
    17.                 volumes:
    18.                         - ./sentinel2.conf:/etc/redis/sentinel.conf
    19.                 ports:
    20.                         - 26380:26379
    21.         sentinel3:
    22.                 image: 'redis:5.0.9'
    23.                 container_name: redis-sentinel-3
    24.                 restart: always
    25.                 command: redis-sentinel /etc/redis/sentinel.conf
    26.                 volumes:
    27.                         - ./sentinel3.conf:/etc/redis/sentinel.conf
    28.                 ports:
    29.                         - 26381:26379
    30. networks:
    31.         default:
    32.         external:
    33.         name: redis-data_default
    复制代码

  • 创建配置文件:创建sentinel1.conf、sentinel2.conf、sentinel3.conf,三分文件的内容是完全类似的,都放在/root/redis-sentinel/⽬录中
    1. bind 0.0.0.0
    2. port 26379
    3. sentinel monitor redis-master redis-master 6379 2
    4. sentinel down-after-milliseconds redis-master 1000
    复制代码

    • 理解sentinel monitor

      • 主节点名:这个是哨兵内部⾃⼰起的名字
      • 主节点ip:部署redis-master的设备ip

        • 此处由于是使⽤docker,可以直接写docker的容器名,会被⾃动DNS成对应的容器ip

      • 法定票数:哨兵需要判定主节点是否挂了,但是有的时候可能由于特殊情况

        • ⽐如主节点仍然⼯作正常,但是哨兵节点⾃⼰⽹络出问题了,⽆法访问到主节点了
        • 此时就可能会使该哨兵节点以为主节点下线,出现误判
        • 使⽤投票的⽅式来确定主节点是否真的挂了是更稳妥的做法
        • 需要多个哨兵都以为主节点挂了,票数 >= 法定票数之后,才会真的以为主节点是挂了

      1. sentinel monitor 主节点名 主节点 ip 主节点端⼝ 法定票数
      复制代码

    • 理解sentinel down-after-milliseconds

      • 主节点和哨兵之间通过⼼跳包来进⾏沟通
      • 假如⼼跳包在指定的时间内还没回来,就视为是节点出现故障

    • 既然内容类似,为啥要创建多份配置⽂件?

      • redis-sentinel在运⾏中可能会对配置进⾏rewrite,修改⽂件内容
      • 假如⽤⼀份⽂件,就可能出现修改混乱的情况


  • 启动所有容器:docker-compose up -d
  • 查看运行日志:docker-compose logs

2.重新推举

1.redis-master宕机之后



  • 哨兵发现了主节点sdown,进⼀步的由于主节点宕机得票到达                                                       2                                     /                                     3                                              2/3                              2/3,到达法定得票,于是master被判定为odown

    • 主观下线(Subjectively Down,SDown):哨兵感知到主节点没⼼跳了,判定为主观下线
    • 客观下线(Objectively Down,ODown):多个哨兵告竣⼀致意⻅,才能以为master确实下线了


  • 接下来,哨兵们挑选出了⼀个新的master,上图中,是172.22.04:6379这个节点

  • 此时,对于Redis来说仍然是可以继续利用的

2.redis-master重启之后



  • 哨兵日志:刚才新启动的redis-master被当成了slave


3.总结



  • Redis主节点假如宕机,哨兵会把其中的⼀个从节点,提拔成主节点
  • 当之前的Redis主节点重启之后,这个主节点被加⼊到哨兵的监控中,但是只会被作为从节点使⽤

3.推举原理



  • 假定生产环境如下


  • 主观下线

    • 当redis-master宕机,此时redis-master和三个哨兵之间的⼼跳包就没有了
    • 此时,站在三个哨兵的⻆度来看,redis-master出现严峻故障,因此三个哨兵均会把redis-master判定为主观下线(SDown)

  • 客观下线

    • 此时,哨兵sentenal1, sentenal2, sentenal3均会对主节点故障这件事变进⾏投票
    • 当故障得票数 >= 配置的法定票数之后,意味着redid-master故障这个事变被坐实,此时触发客观下线(ODown)
      1. sentinel monitor redis-master 172.22.0.4 6379 2
      复制代码

  • 推举出哨兵的leader

    • 接下来需要哨兵把剩余的slave中挑选出⼀个新的master,这个⼯作不需要所有的哨兵都参与,只需要选出个代表(称为leader),由leader负责进⾏slave升级到master的提拔过程
    • 这个推举过程涉及到Raft算法,假定一共三个哨兵节点S1,S2,S3

      • 每个哨兵节点都给其他所有哨兵节点,发起⼀个"拉票请求"

        • S1 -> S2, S1 -> S3, S2 -> S1, S2 -> S3,S3 -> S1, S3 -> S2

      • 收到拉票请求的节点,会回复⼀个 “投票响应”,响应的效果有两种可能, 投or不投

        • 例如:S1给S2发了个投票请求,S2就会给S1返回投票相应
        • S2是否要投S1,取决于S2是否给别人投过票了(每个哨兵只有一票)
        • 假如没投过(S1是第一个向S2拉票的),S2就会投给S1,否则则不投

      • 一轮投票完成之后,发现得票超过半数的节点,主动成为leader

        • 假如出现平票,则重新再投一次即可
        • 这也是为啥发起哨兵节点设置成奇数个的原因,假如为偶数个,则增大了平票的概率,带来了不须要的开销

      • leader节点负责挑选⼀个slave成为新的master,当其他的sentenal发现新的master出现了,就分析推举结束了

    • 综上,Raft算法的核心就是”先下手为强”,谁率先发出了拉票请求,谁就有更大的概率成为leader

      • 决定因素:网络延时,其本身就带有一定的随机性

    • 具体选出的哪个节点是leader不重要,重要的是能选出一个节点

  • leader挑选出合适的slave成为新的master

    • 挑选规则

      • 比力优先级,优先级高(数值小的)的上位

        • 优先级是配置文件中的配置项slave-priority或者replica-priority

      • 比力replication offset,谁复制的数据多,高的上位
      • **比力run id**,谁的id`小,谁上位

        • :大小全凭缘分,选谁都可以,随便挑一个


    • 当某个slave节点被指定为master之后

      • leader指定该节点执行slave no one,成为master`
      • leader指定剩余的slave节点,都依附于这个新master



4.总结



  • 上述过程,都是"⽆⼈值守",Redis ⾃动完成的,这样做就解决了主节点宕机之后需要⼈⼯⼲预的问题,提⾼了体系的稳定性和可⽤性
  • 留意事项

    • 哨兵节点不能只有一个,否则哨兵节点挂了也会影响体系可用性

      • 分布式体系中,应该制止利用“单点”,应该有冗余

    • 哨兵节点最好是奇数个,方便推举leader,得票更轻易超过半数

      • 大部分情况下,3个就充足了

    • 哨兵节点不负责存储数据,仍然是Redis主从节点负责存储

      • 哨兵节点可以利用一些配置不高的机器来部署

    • 哨兵 + 主从复制解决的问题是”提高可用性”,不能解决”数据极端情况下写丢失”的问题
    • 哨兵 + 主从复制不能提高数据的存储容量,当需要存的数据靠近或者超过机器的物理内存,这样的结构就不能胜任了

      • 为了能存储更多的数据,就引入了集群



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表