实现目标:
一主两从,集群起始VIP在master上边,如果当前master挂了,sentinel自动选出一个slave当选master,并把VIP漂移到这台机器,然后把另一台slave指向的master改为此机器,并同步此机器的数据,实现高可用
实操
环境说明
IP | redis角色 | 安装的软件 |
172.16.1.216 | master | redis,redis-sentinel |
172.16.1.223 | slave | redis.redis-sentinel |
172.16.1.215 | slave | redis,redis-sentinel |
VIP:172.16.1.227
安装Redis
三台机器安装redis
[root@redis-1 ~]# wget -c http://download.redis.io/releases/redis-3.0.7.tar.gz
[root@redis-1 ~]# tar zxf redis-3.0.7.tar.gz
[root@redis-1 ~]# cd redis-3.0.7
[root@redis-1 ~]# make
[root@redis-1 ~]# cp redis-3.0.7/src/redis-benchmark /usr/local/sbin/
[root@redis-1 ~]# cp redis-3.0.7/src/redis-check-aof /usr/local/sbin/
[root@redis-1 ~]# cp redis-3.0.7/src/redis-check-dump /usr/local/sbin/
[root@redis-1 ~]# cp redis-3.0.7/src/redis-cli /usr/local/sbin/
[root@redis-1 ~]# cp redis-3.0.7/src/redis-sentinel /usr/local/sbin/
[root@redis-1 ~]# cp redis-3.0.7/src/redis-server /usr/local/sbin/
[root@redis-1 ~]# mkdir /etc/redis
[root@redis-1 ~]# mkdir -p /data/redis/
172.16.1.216 master配置文件
[root@redis-1 ~]# grep -v "^#" /etc/redis/redis.conf | grep -v "^$"
daemonize yes
pidfile "/var/run/redis.pid"
port 3717
tcp-backlog 511
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/data/redis/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/data/redis"
masterauth "123456"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass "123456"
maxmemory 256mb
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
172.16.1.223 slave1 配置文件
daemonize yes
pidfile /var/run/redis.pid
port 3717
tcp-backlog 511
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/data/redis/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis
slaveof 172.16.1.216 3717 #slave就是比主 多了这一个选项,slave需要指定master的IP的端口
masterauth 123456
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass 123456
maxmemory 256mb
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
172.16.1.215 slave2的配置文件
daemonize yes
pidfile /var/run/redis.pid
port 3717
tcp-backlog 511
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/data/redis/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis
slaveof 172.16.1.216 3717 #slave就是比主 多了这一个选项,slave需要指定master的IP的端口
masterauth 123456
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass 123456
maxmemory 256mb
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
三台sentinel配置文件相同
port 23717 dir /tmp #监视一个名为mymaster的master,master为172.16.1.216,端口号为3717,而将这个master判断为失效,至少需要2个sentinel同意(只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)不过要注意, 无论你设置要多少个 Sentinel 同意才能判断一个服务器失效, 一个 Sentinel 都需要获得系统中多数(majority) Sentinel 的支持, 才能发起一次自动故障迁移 sentinel monitor mymaster 172.16.1.216 3717 2 #指定了 Sentinel 认为服务器已经断线所需的毫秒数 sentinel down-after-milliseconds mymaster 30000 #指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 #故障转移的超时时间 sentinel client-reconfig-script piaoyi_vip.sh /etc/redis/script/piaoyi_vip.sh #这个参数配置执行脚本,sentinel在做failover的时候会执行这个脚本,并且传递6个参数<master-name>、 <role>、 <state>、 <from-ip>、 <from-port>、 <to-ip> 、<to-port>,其中<to-ip>是新主redis的IP地址,可以在这个脚本里做VIP漂移操作
piaoyi_vip.sh脚本内容
#!/bin/bash
MASTER_IP=$6 #第六个参数是新主redis的ip地址
LOCAL_IP='172.16.1.216' #其他两个服务器上为172.16.1.223,172.16.1.215
VIP='172.16.1.217'
NETMASK='16'
INTERFACE='eth0'
if [ ${MASTER_IP} = ${LOCAL_IP} ];then #如果master的IP是自己机器的IP,那么就将VIP绑定到本机
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP绑定到该服务器上
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP从该服务器上删除
exit 0
fi
exit 1 #如果返回1,sentinel会一直执行这个脚本
启动服务
三台机器启动redis
redis-server /etc/redis/redis.conf
三台机器启动sentinel
redis-sentinel /etc/redis/redis-sentinel
master上先绑定VIP
/sbin/ip addr add 172.16.1.217/16 dev eth0
/sbin/arping -q -c 3 -A 172.16.1.217 -I eth0
连接任意sentinel服务可以获知当前主redis服务信息
[root@redis-1 ~]# redis-cli -p 23717 -a 123456 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=172.16.1.216:3717,slaves=2,sentinels=3
测试:
把master停掉,登录到另外一台机器,查看sentinel状态,并查看VIP是否漂移新的master机器上
[root@redis-1 ~]# killall redis-server #停master
[root@redis-3 ~]# redis-cli -p 23717 -a 123456 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=172.16.1.215:3717,slaves=2,sentinels=3 #172.16.1.215已经提升为新的master
查看VIP已经漂移到172.16.1.215上
[root@redis-2 ~]# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:48:ae:43:e6:00 brd ff:ff:ff:ff:ff:ff inet 172.16.1.215/22 brd 172.16.3.255 scope global eth0 inet 172.16.1.217/16 scope global secondary eth0 inet6 fe80::f848:aeff:fe43:e600/64 scope link valid_lft forever preferred_lft forever
登录到172.16.1.223查看 redis状态,已经指向新的master
[root@redis-2 redis]# redis-cli -p 3717 -a 123456 info replication
# Replication
role:slave
master_host:172.16.1.215 #已经指向新的master
master_port:3717
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:1185986
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
Sentinel介绍
作用
- Master状态检测
- 如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave
- Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换
工作方式
- 每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他Sentinel 实例发送一个 PING 命令
- 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
- 如果一个Master被标记为主观下线,则正在监视这个Master的所有Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
- 当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
- 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
- 当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
- 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对
某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在
对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-downby-
addr 命令互相交流之后,得出的Master Server下线判断,然后开启
failover.
通俗来讲就是:
redis的sentinel系统用来管理多个redis服务器,可以实现一个功能上实现HA的
集群。该系统主要执行三个任务:
①监控( Monitoring ): Redis Sentinel实时监控主服务器和从服务器运行状
态。
②提醒(notification): 当被监控的某个 Redis 服务器出现问题时, Redis
Sentinel 可以向系统管理员发送通知