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 架构
Sentinel 故障转移
哨兵的工作机制
-
心跳机制:
- 哨兵节点通过定期向Redis节点发送PING命令来检测节点的健康状态。
- Redis节点在收到PING命令后会回复PONG响应,表示节点正常运行。
- 如果哨兵节点在一定时间内(默认30秒)没有收到PONG响应,就会将该节点标记为不可用,并触发相应的故障转移操作。
-
主观下线和客观下线:
- 当哨兵节点将某个Redis节点标记为不可用时,这被称为“主观下线”。
- 哨兵节点之间会进行通信,询问其他哨兵节点是否也认为该节点已下线。
- 如果足够数量的哨兵节点(通常是大于哨兵总数的半数)都认为该节点已下线,则该节点被标记为“客观下线”,即确认该节点确实已不可用。
-
基于Raft算法的选举:
- 在Redis哨兵中,使用Raft算法(或其他类似的共识算法)来选举一个哨兵节点作为领袖节点(Leader)。
- 领袖节点负责协调和执行故障转移操作。
- 选举过程包括哨兵节点之间的投票和通信,以达成多数认同的共识。
-
故障转移操作:
- 领袖哨兵节点会选择一个从节点作为新的主节点。
- 领袖哨兵节点会向其他哨兵节点和从节点发送命令,让它们更新配置,将新的节点设置为主节点。
- 领袖哨兵节点还会通知客户端更新连接信息,以便它们连接到新的主节点。
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