Redis Sentinel


:Mr.zhou  阅读: 1,682 次

  Redis 的哨兵模式(Sentinel)为 Redis 提供了高可用。可以不用人为干预,自动提升 Slave 为 Master,从而实现自动故障转移。Sentinel 也提供了对 Redis 实例的监控、告警、为 Clients 提供配置服务等。

  

  环境

  node-a : Redis 实例 和 Sentinel 实例 ;IP:172.16.1.10 ;redis listen:6379 ;Sentinel listen:26379

  node-b : Redis 实例 和 Sentinel 实例 ;IP:172.16.1.20 ;redis listen:6379 ;Sentinel listen:26379

  node-c : Sentinel 实例 ;IP:172.16.1.30 ;Sentinel listen:26379

  VIP 172.16.1.5 对外提供服务

  步骤

  1、安装 redis

[root@node-a ~]# yum -y install tcl
[root@node-a ~]# cd /usr/local/src/
[root@node-a src]# wget http://download.redis.io/releases/redis-3.2.1.tar.gz
[root@node-a src]# tar xf redis-3.2.1.tar.gz
[root@node-a src]# cd redis-3.2.1
[root@node-a redis-3.2.1]# make
[root@node-a redis-3.2.1]# make test
\o/ All tests passed without errors!
[root@node-a redis-3.2.1]# make PREFIX=/usr/local/redis-3.2.1 install
[root@node-a redis-3.2.1]# ln -s /usr/local/redis-3.2.1/ /usr/local/redis
[root@node-a redis-3.2.1]# mkdir /usr/local/redis/{conf,logs,data}
[root@node-a redis-3.2.1]# cp redis.conf sentinel.conf /usr/local/redis/conf/

  2、编辑 redis 和 sentinel 配置文件

[root@node-a conf]# cat 6379.conf
bind 0.0.0.0
protected-mode no
port 6379
tcp-backlog 10240
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "/usr/local/redis/logs/redis_6379.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename 6379_dump.rdb
dir /usr/local/redis/data/
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
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-size -2
list-compress-depth 0
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
[root@node-a conf]#
[root@node-a conf]# cat 6379_s.conf
bind 0.0.0.0
port 26379
daemonize yes
dir /tmp
logfile "/usr/local/redis/logs/sentinel_6379.log"
sentinel monitor r6379 172.16.1.10 6379 2
sentinel down-after-milliseconds r6379 30000
sentinel parallel-syncs r6379 1
sentinel failover-timeout r6379 180000
sentinel client-reconfig-script r6379 /usr/local/redis/data/reconfig.sh
[root@node-a conf]#

  3、编写 reconfig.sh 脚本

  Sentinel 在进行故障转移时会执行此脚本,并且向该脚本传递 7 个参数:master-name role state from-ip from-port to-ip to-port

[root@node-a data]# cat reconfig.sh
#!/bin/bash
# Change VIP when sentinel invoke this script

# Define Var
VIP=172.16.1.5
NETMASK=24
LocalInter=eth0
FromIP=$4
ToIP=$6
LocalIP=$(ifconfig ${LocalInter}|awk -F "[: ]+" '/inet addr:/{print $4}')

# Unset failed Master host 's VIP

if [ "$FromIP" == "$LocalIP" ];then
  /sbin/ip addr del ${VIP}/${NETMASK} dev ${LocalInter}
fi

# Set VIP to new Master host

if [ "$ToIP" == "$LocalIP" ];then
  /sbin/ip addr add ${VIP}/${NETMASK} dev ${LocalInter}
  /sbin/arping -q -c 3 -A ${VIP} -I ${LocalInter}
fi
[root@node-a data]#

[root@node-a data]# chmod +x reconfig.sh

  4、将已编译好的程序、配置文件和脚本分发至 node-b node-c

[root@node-a data]# rsync -avzP /usr/local/redis-3.2.1 node-b:/usr/local/
[root@node-a data]# rsync -avzP /usr/local/redis-3.2.1 node-c:/usr/local/

[root@node-a data]# ssh node-b 'ln -s /usr/local/redis-3.2.1/ /usr/local/redis'
[root@node-a data]# ssh node-c 'ln -s /usr/local/redis-3.2.1/ /usr/local/redis'

  5、修改 node-b 的 redis 配置文件,作为 node-a 的从库。在 node-b 的配置文件增加以下配置

slaveof 172.16.1.10 6379

  6、启动 node-a node-b 的 redis 服务,默认 node-a 的 redis 为 Master;配置 node-a 的 VIP ;启动 node-a node-b node-c 的 sentinel 服务。

  启动 redis 服务

[root@node-a ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/6379.conf
[root@node-b ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/6379.conf

  检查主从状态

[root@node-a ~]# /usr/local/redis/bin/redis-cli info Replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.20,port=6379,state=online,offset=113,lag=0
master_repl_offset:113
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:112
[root@node-a ~]#

  主从状态正常

  为 Master 服务器配置 VIP

[root@node-a ~]# ip addr add 172.16.1.5/24 dev eth0

[root@node-a ~]# ip addr
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 52:54:00:ff:32:45 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.10/24 brd 172.16.1.255 scope global eth0
    inet 172.16.1.5/24 scope global secondary eth0
    inet6 fe80::5054:ff:feff:3245/64 scope link
       valid_lft forever preferred_lft forever
[root@node-a ~]#

  在 node-c 使用 VIP 连接 redis 服务

[root@node-c ~]# /usr/local/redis/bin/redis-cli -h 172.16.1.5 info Replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.20,port=6379,state=online,offset=575,lag=1
master_repl_offset:575
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:574
[root@node-c ~]#

  使用VIP连接正常

  在 node-a node-b node-c 启动 sentinel 服务

[root@node-a ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/6379_s.conf --sentinel
[root@node-b ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/6379_s.conf --sentinel
[root@node-c ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/6379_s.conf --sentinel

  通过 sentinel 查看状态

[root@node-a ~]# /usr/local/redis/bin/redis-cli -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=r6379,status=ok,address=172.16.1.10:6379,slaves=1,sentinels=3
[root@node-a ~]#

  此时 master 为 1.10 ,有一个 slave.

  7、测试

  关闭 node-a 的 redis

[root@node-a ~]# /usr/local/redis/bin/redis-cli DEBUG sleep 300

  通过 sentinel 查看状态

[root@node-c]# /usr/local/redis/bin/redis-cli -p 26379 INFO Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=r6379,status=ok,address=172.16.1.20:6379,slaves=1,sentinels=3
[root@node-c]#

  此时 Master 为 1.20

  使用 VIP 连接 redis 服务

[root@node-c ~]# /usr/local/redis/bin/redis-cli -h 172.16.1.5 INFO Replication
# Replication
role:master
connected_slaves:0
master_repl_offset:24098
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
[root@node-c ~]#

  node-a redis sleep 300s 后,查看 Replication 状态

[root@node-c ~]# /usr/local/redis/bin/redis-cli -h 172.16.1.5 INFO Replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.10,port=6379,state=online,offset=47472,lag=1
master_repl_offset:47740
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:24100
repl_backlog_histlen:23641
[root@node-c ~]#

  使用 VIP 可以连接到 redis 服务。实现了 redis 的高可用。

  再次确认 VIP 在哪台服务器

[root@node-a ~]# ip addr
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 52:54:00:ff:32:45 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.10/24 brd 172.16.1.255 scope global eth0
    inet6 fe80::5054:ff:feff:3245/64 scope link
       valid_lft forever preferred_lft forever
[root@node-a ~]#

[root@node-b ~]# ip addr
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 52:54:00:d0:e2:65 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.20/24 brd 172.16.1.255 scope global eth0
    inet 172.16.1.5/24 scope global secondary eth0
    inet6 fe80::5054:ff:fed0:e265/64 scope link
       valid_lft forever preferred_lft forever
[root@node-b ~]#

  到此 Redis 的哨兵模式已配置完成,可根据业务需求更改仲裁时间 ,也可以在故障发生时,通过调用脚本实现告警通知。Redis 已提供集群服务,使用 Codis 的可以考虑测试下。具体使用哪个服务,要以业务需求为主。

  感谢 金山猎豹 海军的交流


转载请注明原文链接:http://www.z-dig.com/redis-sentinel.html



正文部分到此结束