您的当前位置:首页正文

[Redis][哨兵][下]详细讲解

2024-10-28 来源:个人技术集锦


1.安装部署(基于Docker)

1.编排Redis主从节点

  • 编写docker-compose.yml
    • 创建/root/redis/docker-compose.yml,同时cdyml所在⽬录中
    • 说明:docker中可以通过容器名字作为ip地址,进⾏相互之间的访问
    version: '3.7'
    services:
    	master:
    		image: 'redis:5.0.9'
    		container_name: redis-master
    		restart: always
    		command: redis-server --appendonly yes
    		ports: 
    			- 6379:6379
    	slave1:
    		image: 'redis:5.0.9'
    		container_name: redis-slave1
    		restart: always
    		command: redis-server --appendonly yes --slaveof redis-master 6379
    		ports:
    			- 6380:6379
    	slave2:
    		image: 'redis:5.0.9'
    		container_name: redis-slave2
    		restart: always
    		command: redis-server --appendonly yes --slaveof redis-master 6379
    		ports:
    			- 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 ,同时cdyml所在⽬录中
    version: '3.7'
    services:
    	sentinel1:
    		image: 'redis:5.0.9'
    		container_name: redis-sentinel-1
    		restart: always
    		command: redis-sentinel /etc/redis/sentinel.conf
    		volumes:
    			- ./sentinel1.conf:/etc/redis/sentinel.conf
    		ports:
    			- 26379:26379
    	sentinel2:
    		image: 'redis:5.0.9'
    		container_name: redis-sentinel-2
    		restart: always
    		command: redis-sentinel /etc/redis/sentinel.conf
    		volumes:
    			- ./sentinel2.conf:/etc/redis/sentinel.conf
    		ports:
    			- 26380:26379
    	sentinel3:
    		image: 'redis:5.0.9'
    		container_name: redis-sentinel-3
    		restart: always
    		command: redis-sentinel /etc/redis/sentinel.conf
    		volumes:
    			- ./sentinel3.conf:/etc/redis/sentinel.conf
    		ports:
    			- 26381:26379
    networks:
    	default:
    	external:
    	name: redis-data_default
    
  • 创建配置文件:创建sentinel1.confsentinel2.confsentinel3.conf,三分文件的内容是完全相同的,都放在/root/redis-sentinel/⽬录中
    bind 0.0.0.0
    port 26379
    sentinel monitor redis-master redis-master 6379 2
    sentinel down-after-milliseconds redis-master 1000
    
    • 理解sentinel monitor
      • 主节点名:这个是哨兵内部⾃⼰起的名字
      • 主节点ip:部署redis-master的设备ip
        • 此处由于是使⽤docker,可以直接写docker的容器名,会被⾃动DNS成对应的容器ip
      • 法定票数:哨兵需要判定主节点是否挂了,但是有的时候可能因为特殊情况
        • ⽐如主节点仍然⼯作正常,但是哨兵节点⾃⼰⽹络出问题了,⽆法访问到主节点了
        • 此时就可能会使该哨兵节点认为主节点下线,出现误判
        • 使⽤投票的⽅式来确定主节点是否真的挂了是更稳妥的做法
        • 需要多个哨兵都认为主节点挂了,票数 >= 法定票数之后,才会真的认为主节点是挂了
      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.选举原理

  • 假定生产环境如下

4.总结

  • 上述过程,都是"⽆⼈值守",Redis ⾃动完成的,这样做就解决了主节点宕机之后需要⼈⼯⼲预的问题,提⾼了系统的稳定性和可⽤性
  • 注意事项
    • 哨兵节点不能只有一个,否则哨兵节点挂了也会影响系统可用性
      • 分布式系统中,应该避免使用“单点”,应该有冗余
    • 哨兵节点最好是奇数个,方便选举leader,得票更容易超过半数
      • 大部分情况下,3个就足够了
    • 哨兵节点不负责存储数据,仍然是Redis主从节点负责存储
      • 哨兵节点可以使用一些配置不高的机器来部署
    • 哨兵 + 主从复制解决的问题是”提高可用性”,不能解决”数据极端情况下写丢失”的问题
    • 哨兵 + 主从复制不能提高数据的存储容量,当需要存的数据接近或者超过机器的物理内存,这样的结构就不能胜任了
      • 为了能存储更多的数据,就引入了集群
显示全文