redis 哨兵及实现(小节5)
redis 集群
上一个步骤的主从架构无法实现master 和 slave 角色的自动切换,即当 master 出现 redis 服务异常、主机断电、磁盘损坏等问题导致 master 无法使用,而 redis 高可用无法实现故障转移(将slave 提升为 master),需要手动改环境配置才能切换到 slave redis 服务器,另外也无法横向扩展 Redis 服务的并行写入性能,当单台 Redis 服务器性能无法满足业务写入需求的时候就必须需要一种方式解决以上的两个核心问题,即:1.master 和 slave 角色的无缝切换,让业务无感知从而不影响业务使用。 2.可以横向动态扩展 Redis 服务器,从而实现多态服务器并行写入以实现更高并发的目的。
Redis 集群实现方式:客户端分片 代理分片 Redis Cluster
Sentinel(哨兵)
Sentinel 进程是用于监控 redis 集群中 Master 主服务器工作的状态,在Master 主服务器方式故障的时候,可以实现 Master 和Slave 服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中, Redis 的哨兵模式到了 2.8 版本之后就稳定了下来。一般在生产环境也建议使用redis的2.8版本的以后版本。哨兵 (Sentinel)是一个分布式系统,可以在一个架构中运行多个哨兵(sentinel)进程,这些进程使用流言协议(gossip protocols)来接收关于 Master 主服务器是否下线的消息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave 作为新的Master。每个哨兵(sentinel)进程会向其他哨兵(sentinel)、Master、Slave 定时发送消息,已确认对方是否"活"着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的"主观认为宕机",主观是每个成员都具有的独自的而且可能相同也可能不同的意识
,英文名称:Subjective Down,简称 SDOWN,有主观宕机,肯定就有客观宕机,当"哨兵群"中的多数Sentinel 进程在对 Master主服务器做出 SDOWN的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的 Master Server下线判断,这种方式就是"客观宕机",客观是不依赖于某种意识而已经实际存在的一切事物
,英文名称是:Objectively Down,简称 ODOWN,通过一定的vote 算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)。
Sentinel 机制可以解决 master 和 slave 角色的切换问题。
实现环境(需要手动先配置出来)
主机 | IP地址 |
---|---|
master | 1.101 |
slave1 | 1.102 |
slave2 | 1.103 |
直接redis编译安装脚本安装
参考redis安装(小节1)脚本安装即可
master
修改以下信息
~]# vim /apps/redis/etc/redis.conf
bind 0.0.0.0
requirepass 123
#重启服务
~]# systemctl restart redis
slave1和slave2
修改以下信息
~]# vim /apps/redis/etc/redis.conf
bind 0.0.0.0 <--监听端口
slaveof 192.168.1.101 6379 <--
masterauth 123 <--认证密码
requirepass 123 <--
#重启服务
~]# systemctl restart redis
master
~]# vim /apps/redis/etc/sentinel.conf
bind 0.0.0.0 <--
logfile "sentinel_26379.log" <--
pidfile "redis-sentinel.pid" <--
daemonize yes <--
dir /apps/redis/data/ <--数据存放位置
sentinel monitor mymaster 192.168.1.101 6379 2 <--名称可随便设置但是要和下行的一致(如"mymaster")
sentinel auth-pass mymaster 123 <--名称要一致
#过滤一下、查看文件内容
~]# grep "^[a-Z]" /apps/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
logfile "sentinel_26379.log"
pidfile "redis-sentinel.pid"
daemonize yes
dir /apps/redis/data/
sentinel monitor mymaster 192.168.1.101 6379 2
sentinel auth-pass mymaster 123
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
#传文件
~]# scp /apps/redis/etc/sentinel.conf 192.168.1.102:/apps/redis/etc/
~]# scp /apps/redis/etc/sentinel.conf 192.168.1.103:/apps/redis/etc/
#启动哨兵进程
~]# redis-sentinel /apps/redis/etc/sentinel.conf
#端口号
~]# ss -ntlp |grep 26379
LISTEN 0 511 *:26379 *:* users:(("redis-sentinel",pid=20578,fd=6))
#如果报错可以sentinel监控日志
~]# tail -f /apps/redis/data/sentinel_26379.log
slave1和slave2
#启动哨兵进程
server1 ~]# redis-sentinel /apps/redis/etc/sentinel.conf
server1 ~]# /apps/redis/bin/redis-cli -h 192.168.1.101 -p 26379
192.168.1.101:26379> INFO
...
# Sentinel <--哨兵当前工作状态
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
#master:名称,状态,地址,slave,哨兵
master0:name=mymaster,status=ok,address=192.168.1.101:6379,slaves=2,sentinels=3
master
kill 掉 redis 的7671进程
~]# ps -ef |grep redis
redis 7671 1 0 01:40 ? 00:00:02 /apps/redis/bin/redis-server 0.0.0.0:6379
root 20503 1 0 02:00 ? 00:00:00 redis-sentinel 0.0.0.0:26379 [sentinel]
root 20529 4011 0 02:02 pts/0 00:00:00 grep --color=auto redis
#kill掉7671 resid进程
~]# kill -9 7671
~]# ps -ef |grep redis
root 20503 1 0 02:00 ? 00:00:00 redis-sentinel 0.0.0.0:26379 [sentinel]
root 20533 4011 0 02:02 pts/0 00:00:00 grep --color=auto redis
slave2
server2 ~]# /apps/redis/bin/redis-cli -h 192.168.1.102
192.168.1.102:6379> AUTH 123
OK
192.168.1.102:6379> INFO
...
# Replication
role:master <--102成了master
connected_slaves:1
slave0:ip=192.168.1.103,port=6379,state=online,offset=287122,lag=1 <--slave:103,端口6379,状态,
master_replid:f35950770f4eb7e276b8b7acc01994a242bba6da
master_replid2:3a53aa9fa35d2d9517eae0505cb8d3dbf2870437
master_repl_offset:287263
second_repl_offset:267798
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:287263
...
注意:此时文件信息自动发生变化、slave1(102)成为了master
server2 ~]# vim /apps/redis/etc/redis.conf
slaveof 192.168.1.102 6379 <--
master
如果想把之前的master(101),再次启动需要手动更改配置文件,因为(102)已经成为了新的master。
#把101加到102中
redis ~]# vim /apps/redis/etc/redis.conf
...
slaveof 192.168.1.102 6379
masterauth 123
#启动
redis ~]# systemctl start redis
#查看端口是否启动
redis ~]# ss -ntlp|grep 6379
LISTEN 0 511 *:6379 *:* users:(("redis-server",pid=4283,fd=6))
LISTEN 0 511 *:26379 *:* users:(("redis-sentinel",pid=4161,fd=6))
~]# redis-cli -h 192.168.1.102 -p 6379
192.168.1.102:6379> AUTH 123
OK
192.168.1.102:6379> INFO
...
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.1.103,port=6379,state=online,offset=253255,lag=1 <--
slave1:ip=192.168.1.101,port=6379,state=online,offset=253255,lag=0 <--
master_replid:26656b9ec6791428afdd8665d161dc76ad8dd5a7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:253396
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:253396
#写入一个数据
192.168.1.102:6379> SET abc redis
OK
server2
查看数据是否同步
server2 ~]# redis-cli
127.0.0.1:6379> AUTH 123
OK
127.0.0.1:6379> GET abc
"redis" <--可以看到数据说明已经同步