redis高可用的三种常见的集群方式:redis sentinel 、redis cluster(多主机+分布式)、redis sharding。本文主机介绍redis sentinel的部署过程。
centos7部署redis的主机ip地址:
master:10.11.11.109
slave:10.11.11.110,10.11.11.111
3.1、Redis3.x Sentinel集群配置
Redis服务启动和配置文件端口的查询
# ansible redmon -i /root/ans/ansible_inventory.txt -m systemd -a "name=redis enabled=yes state=started"
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "rpm -ql redis"
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "ps -ef | grep redis"
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "ss -tunlp | grep redis"
3.1.1、准备Redis配置文件:
# ansible redmon -i /root/ans/ansible_inventory.txt -m fetch -a "src=/etc/redis.conf dest=/root/ans/conf.d flat=yes" --limit=10.11.11.109
# ansible redmon -i /root/ans/ansible_inventory.txt -m fetch -a "src=/etc/redis-sentinel.conf dest=/root/ans/conf.d flat=yes" --limit=10.11.11.109
3.1.2、三台机器主从节点的准备:
1)、master节点:10.11.11.109
修改后,包含默认的情况如下:
# sed -e "s/#.*//g" redis.conf | awk '{if (length !=0) print $0}'
bind 10.11.11.109
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /var/log/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 /var/lib/redis
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 yes
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
下面是可以或需要修改的选项:
仅仅修改这四项,为的是方便管理,也可以保持默认配置
daemonize yes 使Redis以守护进程模式运行
pidfile /var/run/redis_端口号.pid 设置Redis的PID文件位置
port 端口号6379 设置Redis监听的端口号
dir 自己定义目录 设置持久文件存放位置
logfile /var/log/redis/redis.log
dir /var/lib/redis
详细情况:
bind 10.11.11.109
protected-mode no
默认情况下,Redis node和sentinel的protected-mode都是yes,在搭建集群时,若想从远程连接redis集群,需要将redis.conf和sentinel.conf的protected-mode修改为no,若只修改redis node,从远程连接sentinel后,依然是无法正常使用的,且sentinel的配置文件中没有protected-mode配置项,需要手工添加。
protected-mode在默认开启的情况下要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问
##启用增量(Master禁用)
appendonly yes
appendfsync everysec
2)、slave节点:10.11.11.110-111
修改后,包含默认的情况如下:
# sed -e "s/#.*//g" redis.conf.201-202 | awk '{if (length !=0) print $0}'
bind 10.11.11.110-111
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /var/log/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 /var/lib/redis
slaveof 10.11.7.205 6379
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 yes
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
详细说明:
下面是可以或需要修改的选项:
仅仅修改这四项,为的是方便管理,也可以保持默认配置
daemonize yes 使Redis以守护进程模式运行
pidfile /var/run/redis_端口号.pid 设置Redis的PID文件位置
port 端口号6379 设置Redis监听的端口号
dir 自己定义目录 设置持久文件存放位置
protected-mode no
默认情况下,Redis node和sentinel的protected-mode都是yes,在搭建集群时,若想从远程连接redis集群,需要将redis.conf和sentinel.conf的protected-mode修改为no,若只修改redis node,从远程连接sentinel后,依然是无法正常使用的,且sentinel的配置文件中没有protected-mode配置项,需要手工添加。
protected-mode在默认开启的情况下要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问
logfile "/var/log/redis/redis.log"
bind 10.11.11.110-111
##启用增量(Master禁用)
appendonly yes
appendfsync everysec
slave-priority 80 ---->110
slave-priority 50 --->111
添加为从节点:
# slaveof
slaveof 192.168.0.247 6379
copy到指定的主从节点:
# ls
redis.conf redis.conf.201 redis.conf.202 redis-sentinel.conf
# ansible redmon -i /root/ans/ansible_inventory.txt -m copy -a "src=/root/ans/conf.d/redis.conf dest=/etc/redis.conf backup=yes" --limit=10.11.11.109
# ansible redmon -i /root/ans/ansible_inventory.txt -m copy -a "src=/root/ans/conf.d/redis.conf.201 dest=/etc/redis.conf backup=yes" --limit=10.11.11.110
# ansible redmon -i /root/ans/ansible_inventory.txt -m copy -a "src=/root/ans/conf.d/redis.conf.202 dest=/etc/redis.conf backup=yes" --limit=10.11.11.111
3)、启动Redis主从集群
先启动主节点(master):
# ansible redmon -i /root/ans/ansible_inventory.txt -m systemd -a "name=redis enabled=yes state=restarted" --limit=10.11.11.109
再启动从节点:
# ansible redmon -i /root/ans/ansible_inventory.txt -m systemd -a "name=redis enabled=yes state=restarted" --limit=10.11.11.110,10.11.11.111
4)、防火墙放行
# ansible redmon -i /root/ans/ansible_inventory.txt -m firewalld -a "zone=public state=enabled permanent=yes port=6379/tcp"
# ansible redmon -i /root/ans/ansible_inventory.txt -m firewalld -a "zone=public state=enabled permanent=true port=6379/udp"
注意使其生效喔
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "firewall-cmd --reload"
5)、查看redis主从状态
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "redis-cli -h 10.11.11.109 info Replication" --limit=10.11.11.109
10.11.11.109 | SUCCESS | rc=0 >>
# Replication
role:master
connected_slaves:2
slave0:ip=10.11.11.111,port=6379,state=online,offset=57,lag=1
slave1:ip=10.11.11.110,port=6379,state=online,offset=57,lag=1
master_repl_offset:57
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:56
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "redis-cli -h 10.11.11.111 info Replication" --limit=10.11.11.111
10.11.11.111 | SUCCESS | rc=0 >>
# Replication
role:slave
master_host:10.11.11.109
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:85
slave_priority:50
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
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "redis-cli -h 10.11.11.110 info Replication" --limit=10.11.11.110
10.11.11.110 | SUCCESS | rc=0 >>
# Replication
role:slave
master_host:10.11.11.109
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:99
slave_priority:80
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
3.1.3、配置sentinel集群
1)、主备主机的sentinel.conf配置如下:
master节点:
# sed -e "s/#.*//g" redis-sentinel.conf | awk '{if (length !=0) print $0}'
port 26379
dir /data/var/tmp
sentinel monitor mymaster 10.11.11.109 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
logfile /data/var/log/redis/sentinel.log
bind 10.11.11.109
protected-mode no
slave节点:
# sed -e "s/#.*//g" redis-sentinel.conf.110 | awk '{if (length !=0) print $0}'
port 26379
dir /data/var/tmp
sentinel monitor mymaster 10.11.11.109 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
logfile /data/var/log/redis/sentinel.log
bind 10.11.11.110
protected-mode no
# sed -e "s/#.*//g" redis-sentinel.conf.backup111 | awk '{if (length !=0) print $0}'
port 26379
dir /data/var/tmp
sentinel monitor mymaster 10.11.11.109 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
logfile /data/var/log/redis/sentinel.log
bind 10.11.11.111
protected-mode no
copy到指定的主从节点:
# ls
redis-sentinel.conf.110 redis-sentinel.conf.backup111 redis-sentinel.conf.master
# ansible redmon -i /root/ans/ansible_inventory.txt -m copy -a "src=/root/ans/conf.d/redis-sentinel.conf.master dest=/etc/redis-sentinel.conf backup=yes" --limit=10.11.11.109
# ansible redmon -i /root/ans/ansible_inventory.txt -m copy -a "src=/root/ans/conf.d/redis-sentinel.conf.110 dest=/etc/redis-sentinel.conf backup=yes" --limit=10.11.11.110
# ansible redmon -i /root/ans/ansible_inventory.txt -m copy -a "src=/root/ans/conf.d/redis-sentinel.conf.backup111 dest=/etc/redis-sentinel.conf backup=yes" --limit=10.11.11.111
2)、防火墙配置
# ansible redmon -i /root/ans/ansible_inventory.txt -m firewalld -a "zone=public state=enabled permanent=yes port=26379/tcp"
# ansible redmon -i /root/ans/ansible_inventory.txt -m firewalld -a "zone=public state=enabled permanent=yes port=26379/udp"
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "firewall-cmd --reload"
3)、启动sentinel集群
注意点:
1):首次启动时,必须先启动Master
2):Sentinel 只在 server 端做主从切换,app端要自己开发(例如Jedis库的SentinelJedis,能够监控Sentinel的状态)
3):若Master已经被判定为下线,Sentinel已经选择了新的Master,也已经将old Master改成Slave,但是还没有将其改成new Master。若此时重启old Master,则Redis集群将处于无Master状态,此时只能手动修改配置文件,然后重新启动集群
# ansible redmon -i /root/ans/ansible_inventory.txt -m systemd -a "name=redis-sentinel state=started enabled=yes" --limit=10.11.11.109
# ansible redmon -i /root/ans/ansible_inventory.txt -m systemd -a "name=redis-sentinel state=started enabled=yes" --limit=10.11.11.110
# ansible redmon -i /root/ans/ansible_inventory.txt -m systemd -a "name=redis-sentinel state=started enabled=yes" --limit=10.11.11.111
查询状态:
主从节点查看的结果是一样的:
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "redis-cli -h 10.11.11.109 -p 26379 info Sentinel"
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "redis-cli -h 10.11.11.110 -p 26379 info Sentinel"
# ansible redmon -i /root/ans/ansible_inventory.txt -m shell -a "redis-cli -h 10.11.11.110 -p 26379 info Sentinel"
10.11.11.111 | SUCCESS | rc=0 >>
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.11.11.109:6379,slaves=2,sentinels=3
10.11.11.109 | SUCCESS | rc=0 >>
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.11.11.109:6379,slaves=2,sentinels=3
10.11.11.110 | SUCCESS | rc=0 >>
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.11.11.109:6379,slaves=2,sentinels=3
4)、宕机演示
添加测试数据:
[root@redis247 ~]# redis-cli -h 192.168.0.8 -p 6379
192.168.0.9:6379> set lll 245
OK
192.168.0.8:6379> save
OK
[root@redis247 ~]# redis-cli -h 192.168.0.247 -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=redismaster,status=ok,address=192.168.0.247:6379,slaves=2,sentinels=3
关掉redis-server服务:
[root@redis247 ~]# redis-cli -h 192.168.0.247 -p 6379 shutdown
[root@redis247 ~]# ss -tunlp | grep redis
tcp LISTEN 0 128 192.168.0.247:26379 *:* users:(("redis-sentinel",1241,4))
状态切换的结果:
[root@redis247 ~]# redis-cli -h 192.168.0.247 -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=redismaster,status=ok,address=192.168.0.9:6379,slaves=2,sentinels=3
[root@redis247 ~]# redis-cli -h 192.168.0.9 -p 26381 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=redismaster,status=ok,address=192.168.0.9:6379,slaves=2,sentinels=3
再关闭sentinel:(相当于主机宕机)
[root@redis247 ~]# ss -tunlp | grep redis
tcp LISTEN 0 128 192.168.0.247:26379 *:* users:(("redis-sentinel",1241,4))
[root@redis247 ~]# ps -aux | grep redis
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 1241 0.5 0.4 133532 2412 ? Ssl 14:26 0:07 redis-sentinel 192.168.0.247:26379 [sentinel]
root 1272 0.0 0.1 103252 840 pts/0 S+ 14:49 0:00 grep redis
[root@redis247 ~]# kill -9 1241
[root@redis247 ~]# ps -aux | grep redis
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 1274 0.0 0.1 103252 840 pts/0 S+ 14:49 0:00 grep redis
[root@redis247 ~]# ss -tunlp | grep redis
状态同上
重新启动:
[root@redis247 ~]# /etc/init.d/redis restart
[root@redis247 ~]# redis-sentinel /usr/local/redis/sentinel.conf
[root@redis247 ~]# redis-cli -h 192.168.0.8 -p 26380 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=redismaster,status=ok,address=192.168.0.9:6379,slaves=2,sentinels=3
#注意:原来的主宕机重新启动后,充当从的角色
# 如果不是主宕机,而是从宕机,那么不会发生切换行为,只会把宕机的那台从集群中剔除。
# 已宕机的机器,如果再次加入集群,只要它成为了当前主的从机,则Sentinel会自动发现,并将其加入集群成员。
再次查看测试数据:
[root@redis247 ~]# redis-cli -h 192.168.0.9 -p 6379
192.168.0.9:6379> get lll
"245"