redis 哨兵

71 阅读6分钟

redis集群介绍

主从架构无法实现master和slave角色的自动切换,即当master出现redis服务异常、主机断电、磁盘损坏等问题导致master无法使用,而redis主从复制无法实现自动的故障转移(将slave 自动提升为新master),需要手动修改环境配置,才能切换到slave redis服务器,另外当单台Redis服务器性能无法满足业务写入需求的时候,也无法横向扩展Redis服务的并行写入性能

需要解决以上的两个核心问题:

  • master和slave角色的无缝切换,让业务无感知从而不影响业务使用
  • 可横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的。

Redis 集群实现方式:

  • 客户端分片: 由应用决定将不同的KEY发送到不同的Redis服务器
  • 代理分片: 由代理决定将不同的KEY发送到不同的Redis服务器,代理程序如:codis,twemproxy等
  • Redis Cluster

哨兵 (Sentinel)工作原理

sentinel架构和故障转移

Sentinel 架构

image.png

Sentinel 故障转移

image.png

哨兵的工作机制

  1. 心跳机制

    • 哨兵节点通过定期向Redis节点发送PING命令来检测节点的健康状态。
    • Redis节点在收到PING命令后会回复PONG响应,表示节点正常运行。
    • 如果哨兵节点在一定时间内(默认30秒)没有收到PONG响应,就会将该节点标记为不可用,并触发相应的故障转移操作。
  2. 主观下线和客观下线

    • 当哨兵节点将某个Redis节点标记为不可用时,这被称为“主观下线”。
    • 哨兵节点之间会进行通信,询问其他哨兵节点是否也认为该节点已下线。
    • 如果足够数量的哨兵节点(通常是大于哨兵总数的半数)都认为该节点已下线,则该节点被标记为“客观下线”,即确认该节点确实已不可用。
  3. 基于Raft算法的选举

    • 在Redis哨兵中,使用Raft算法(或其他类似的共识算法)来选举一个哨兵节点作为领袖节点(Leader)。
    • 领袖节点负责协调和执行故障转移操作。
    • 选举过程包括哨兵节点之间的投票和通信,以达成多数认同的共识。
  4. 故障转移操作

    • 领袖哨兵节点会选择一个从节点作为新的主节点。
    • 领袖哨兵节点会向其他哨兵节点和从节点发送命令,让它们更新配置,将新的节点设置为主节点。
    • 领袖哨兵节点还会通知客户端更新连接信息,以便它们连接到新的主节点。

sentinel中的三个定时任务

  • 每10秒每个sentinel对master和slave执行info

发现slave节点

确认主从关系

  • 每2秒每个sentinel通过master节点的channel交换信息(pub/sub)

通过sentinel__:hello频道交互

交互对节点的“看法”和自身信息

  • 每1秒每个sentinel对其他sentinel和redis执行ping

实现哨兵

哨兵的准备实现主从复制架构

哨兵的前提是已经实现了一个redis的主从复制的运行环境,从而实现一个一主两从基于哨兵的高可用

redis架构

  • 主 192.168.10.1
  • 从1 192.168.10.10
  • 从2 192.168.10.20

所有主从节点的redis.conf中关健配置

范例: 准备主从环境配置

安装redis略

先实现主从复制

​
​
#在所有主从节点执行
[root@centos7  ~]#vim apps/redis/etc/redis.conf
bind 0.0.0.0#或者非交互执行
[root@centos8 ~]#sed -i 's/bind 127.0.0.1/bind 0.0.0.0/' 
​
​
#在所有从节点执行
[root@centos8 ~]#echo "replicaof 192.168.10.1 6379" >> /etc/redis.conf
#在所有主从节点执行
[root@centos8 ~]#systemctl enable --now redis
​
​
​

编辑哨兵的配置文件

sentinel配置

Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持.默认监听在26379/tcp端口.

哨兵可以不和Redis服务器部署在一起,但一般部署在一起以节约成本

所有redis节点使用相同的以下示例的配置文件

#如果是编译安装,在源码目录有sentinel.conf,复制到安装目录即可,:/apps/redis/etc/sentinel.conf
​
​
[root@centos7 ~]#vim /etc/redis-sentinel.conf 
bind 0.0.0.0   #修改监听端口 
port 26379     #不用修改默认
daemonize yes  # 不用修改如果是systemd 启动模式, 修改后启动不了
pidfile "/apps/resdis/run/redis-sentinel.pid"  #指定pid文件
logfile "/apps/redis/log/sentinel_26379.log"  # 指定日志文件
dir "/tmp"  #工作目录不用修改
​
​
​
sentinel monitor mymaster 192.168.10.1 6379 2
#mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口
#2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移,一般此值是所有sentinel节点(一般总数是>=3的 奇数,如:3,5,7等)的一半以上的整数值,比如,总数是3,即3/2=1.5,取整为2,是master的ODOWN客观下线的依据
​
​
sentinel auth-pass mymaster 123456
#mymaster集群中master的密码,注意此行要在上面行的下面
​
sentinel down-after-milliseconds mymaster 30000
#(SDOWN)判断mymaster集群中所有节点的主观下线的时间,    单位:毫秒,建议3000(3秒) 否则等待时间过长
​
sentinel parallel-syncs mymaster 1
#发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力
​
sentinel failover-timeout mymaster 180000
#所有slaves指向新的master所需的超时时间,单位:毫秒
​
sentinel deny-scripts-reconfig yes #禁止修改脚本
​
​
​

修改文件内容

[root@localhost etc]#grep -vE "^#|^$"  sentinel.conf 
bind 0.0.0.0
port 26379
daemonize  yes
pidfile /apps/redis/run/redis-sentinel.pid
logfile "/apps/redis/log/sentinel.log"
dir /tmp
sentinel monitor mymaster 192.168.10.1 6379 2
sentinel auth-pass  mymaster  123456
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

准备service 文件 注意先开 主再开从 全部节点都需要

[root@localhost etc]#cat  >> /lib/systemd/system/redis-sentinel.service  <<eof
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
eof
​
​
[root@localhost etc]# systemctl daemon-reload 
[root@localhost etc]# systemctl start redis-sentinel.service

关掉 主服务器验证

在主上观察日志

主再恢复后会变成从

[root@localhost etc]#systemctl start redis
[root@localhost etc]#redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.10.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:134979
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:473c28e4bd1fcf189af91222aaed0d2c235f32aa
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:134979
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:133670
repl_backlog_histlen:1310