Redis包含三种集群策略:
主从复制 哨兵模式 redis cluster
主从复制
在主从复制中,数据分为两类:主数据库(master)和 从数据库(slave)。其中主从复制有如下特点:
主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库 从数据库一般都是只读的,并且结束主数据库同步过来的数据 一个master可以拥有多个slave,但是一个slave只能对应一个master
主从复制工作机制
1. 全量同步
初始化:
全量同步,redis全量复制一般发生在slave创建之处,这时slave需要将master上的所有数据都复制一份。具体步骤如下:
(1)从服务器连接主服务器,发送SYNC命令;
(2)主服务器收到SYNC命令后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
(3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
(4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
(5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
(6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令
(7)复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性

2. 增量同步
redis增量复制是指slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的命令。
3. redis主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,salve 在任何时候都可以发起全量同步。redis策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从节点进行全量同步。
4. 注意点
如果多个slave断线了,需要重启服务,因为只要slave重启,就会发送SYNC请求和master全量同步,当多个同时出现的时候,可能会导致Master IO剧增。
主从复制实例
版本信息

节点信息

redis基础安装上篇博客已经详细介绍:https://www.cnblogs.com/hukey/p/10053557.html 这里不在赘述
主要解析 redis 主从复制 参数和配置
在配置redis的时候要注意以下几点:
监听的地址一定要是两台服务器连通的地址,如监听 127.0.0.1 两端肯定是不会通的,通常可以直接修改为 bind 0.0.0.0; 从服务器启动了两个redis服务,请分别申明 dump.rdb文件名和log文件名
主redis启动服务:
[root@redis-master ~]# redis-server usr/local/redis/conf/6379.conf
[root@redis-master ~]# netstat -ntplu | egrep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 14485/redis-server
从redis启动服务:
注意:从 redis 一共是启动两个redis服务,端口为:6380、6381
[root@redis-slave-1 ~]# redis-server usr/local/redis/conf/6380.conf
[root@redis-slave-1 ~]# redis-server usr/local/redis/conf/6381.conf
[root@redis-slave-1 ~]# netstat -ntplu | egrep redis
tcp 0 0 0.0.0.0:6380 0.0.0.0:* LISTEN 14386/redis-server
tcp 0 0 0.0.0.0:6381 0.0.0.0:* LISTEN 14391/redis-server
复制
redis提供了主从同步功能。
通过slaveof配置项可以控制某一个redis作为另一个redis的从服务器,通过指定IP和端口来定位到主redis的位置。一般情况下,我们会建议用户为从redis设置一个不同频率的快照持久化的周期,或者为从redis配置一个不同的服务端口等等。
slaveof <masterip> <masterport>
如果主redis设置了验证密码的话(使用requirepass来设置),则在从redis的配置中要使用masterauth来设置校验密码,否则的话,主redis会拒绝从redis的访问请求。
masterauth <master-password>
当从redis失去了与主redis的连接,或者主从同步正在进行中时,redis该如何处理外部发来的访问请求呢?这里,从redis可以有两种选择:
第一种选择:如果slave-serve-stale-data设置为yes(默认),则从redis仍会继续响应客户端的读写请求。
第二种选择:如果slave-serve-stale-data设置为no,则从redis会对客户端的请求返回“SYNC with master in progress”,当然也有例外,当客户端发来INFO请求和SLAVEOF请求,从redis还是会进行处理。
你可以控制一个从redis是否可以接受写请求。将数据直接写入从redis,一般只适用于那些生命周期非常短的数据,因为在主从同步时,这些临时数据就会被清理掉。自从redis2.6版本之后,默认从redis为只读。
slave-read-only yes
只读的从redis并不适合直接暴露给不可信的客户端。为了尽量降低风险,可以使用rename-command指令来将一些可能有破坏力的命令重命名,避免外部直接调用。比如:
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
从redis会周期性的向主redis发出PING包。你可以通过repl_ping_slave_period指令来控制其周期。默认是10秒。
repl-ping-slave-period 10
在主从同步时,可能在这些情况下会有超时发生:
1.以从redis的角度来看,当有大规模IO传输时。
2.以从redis的角度来看,当数据传输或PING时,主redis超时
3.以主redis的角度来看,在回复从redis的PING时,从redis超时
用户可以设置上述超时的时限,不过要确保这个时限比repl-ping-slave-period的值要大,否则每次主redis都会认为从redis超时。
repl-timeout 60
我们还可以设置同步队列长度。队列长度(backlog)是主redis中的一个缓冲区,在与从redis断开连接期间,主redis会用这个缓冲区来缓存应该发给从redis的数据。这样的话,当从redis重新连接上之后,就不必重新全量同步数据,只需要同步这部分增量数据即可。
repl-backlog-size 1mb
如果主redis等了一段时间之后,还是无法连接到从redis,那么缓冲队列中的数据将被清理掉。我们可以设置主redis要等待的时间长度。如果设置为0,则表示永远不清理。默认是1个小时。
repl-backlog-ttl 3600
我们可以给众多的从redis设置优先级,在主redis持续工作不正常的情况,优先级高的从redis将会升级为主redis。而编号越小,优先级越高。比如一个主redis有三个从redis,优先级编号分别为10、100、25,那么编号为10的从redis将会被首先选中升级为主redis。当优先级被设置为0时,这个从redis将永远也不会被选中。默认的优先级为100。
slave-priority 100
假如主redis发现有超过M个从redis的连接延时大于N秒,那么主redis就停止接受外来的写请求。这是因为从redis一般会每秒钟都向主redis发出PING,而主redis会记录每一个从redis最近一次发来PING的时间点,所以主redis能够了解每一个从redis的运行情况。
min-slaves-to-write 3
min-slaves-max-lag 10
上面这个例子表示,假如有大于等于3个从redis的连接延迟大于10秒,那么主redis就不再接受外部的写请求。上述两个配置中有一个被置为0,则这个特性将被关闭。默认情况下min-slaves-to-write为0,而min-slaves-max-lag为10。
关于主从复制参数注解
复制
[root@redis-master ~]# redis-cli
127.0.0.1:6379> set p1 1
OK
127.0.0.1:6379> set p2 2
OK
127.0.0.1:6379> set p3 3
OK
127.0.0.1:6379> set p4 4
OK
127.0.0.1:6379> set p5 5
OK
复制
临时主从配置
从节点配置:
[root@redis-slave-1 conf]# redis-cli -h 192.168.118.16 -p 6380
192.168.118.16:6380> SLAVEOF 192.168.118.15 6379
OK
192.168.118.16:6380> INFO Replication
# Replication
role:slave
master_host:192.168.118.15 # master ip
master_port:6379 # master 端口
master_link_status:up # master 连接状态
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:364
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c9df23c58349d5f9abb83b1156df9e458766b784
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:364
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:364
192.168.118.16:6380> keys *
1) "p2"
2) "p1"
3) "p4"
4) "p5"
5) "p3"
复制
192.168.118.15:6379> INFO Replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.118.16,port=6380,state=online,offset=28,lag=1 # 标识出第一个slave节点的ip、port等状态
master_replid:c9df23c58349d5f9abb83b1156df9e458766b784
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
复制
如果要同步另一个从redis步骤相同,这里就不再演示。
尝试重启从redis查看主从配置是否依然生效:
从节点操作:
[root@redis-slave-1 ~]# redis-cli -h 192.168.118.16 -p 6380 shutdown # 关闭slave服务
[root@redis-slave-1 ~]# netstat -ntplu | egrep 6380
[root@redis-slave-1 ~]# redis-server usr/local/redis/conf/6380.conf # 开启slave服务
[root@redis-slave-1 ~]# netstat -ntplu | egrep 6380
[root@redis-slave-1 ~]# redis-cli -h 192.168.118.16 -p 6380
192.168.118.16:6380> INFO Replication # 通过查看,发现主从配置信息已经丢失。
# Replication
role:master
connected_slaves:0
master_replid:4e071c1597d046f07eaa2d83d8c22c8036c3fda5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.118.16:6380> keys * # 之前同步的数据依然存在。
1) "p4"
2) "p2"
3) "p5"
4) "p1"
5) "p3"
复制
所以,通过上面的测试得出:如果只是临时配置,重启服务则从节点配置的同步信息会丢失!
永久主从配置
想要主从配置重启生效,就需要在配置文件中申明:
从节点配置
[root@redis-slave-1 ~]# vim usr/local/redis/conf/6380.conf
281 # slaveof <masterip> <masterport>
282 slaveof 192.168.118.15 6379 # 申明 master_ip master_port
复制
保存退出
重启服务:
[root@redis-slave-1 ~]# redis-cli -h 192.168.118.16 -p 6380 shutdown; redis-server usr/local/redis/conf/6380.conf # 重启服务
[root@redis-slave-1 ~]# redis-cli -h 192.168.118.16 -p 6380
192.168.118.16:6380> INFO Replication # 查看复制状态,已经成功
# Replication
role:slave
master_host:192.168.118.15
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:882
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c9df23c58349d5f9abb83b1156df9e458766b784
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:882
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:869
repl_backlog_histlen:14
复制
永久的配置,即使重启了服务,配置也不会丢失,所以建议直接修改配置文件进行设置。
哨兵模式
在主从复制中,万一主库挂了,一样会带来很严重的后果,所有就有了哨兵(Sentinel)模式.
简介:
Redis Sentinel 是 Redis 官方提供的集群管理工具,可以部署在其他与redis集群可通讯的机器中监控redis集群。
功能特点:
监控redis是否按照预期良好运行; 如果发现某个redis节点运行出现状况,能够通知另一个进程; 自动故障迁移:当一个master不能正常工作,Sentinel会开始一次自动故障迁移操作,它会将失效的master的其中一个slave升级为新的Master,并让失效master的其他slave改为复制新的master,当客户端试图连接失效的master时,集群会向客户端返回新的master地址,使得集群可以使用现在的master替换失效的master和slave服务器切换后,master的redis.conf、slave的redis.conf和sentinel.conf配置文件的内容都会发生相应的改变,即:master主服务器的redis.conf 配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
Sentinel(哨兵)进程的工作方式:
1. 每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
2. 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)。
3. 如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。
4. 当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)。
5. 在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
6. 当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
7. 若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。
哨兵模式配置:
服务节点介绍:

首先,搭建 master 和 slave 主从配置:
192.168.118.16 节点:
[root@192.168.118.16 usr/local/src]#tar xf redis-4.0.10.tar.gz
[root@192.168.118.16 usr/local/src]#cd redis-4.0.10
[root@192.168.118.16 usr/local/src/redis-4.0.10]#mkdir -pv usr/local/redis/{db,log,conf}
mkdir: created directory ‘/usr/local/redis’
mkdir: created directory ‘/usr/local/redis/db’
mkdir: created directory ‘/usr/local/redis/log’
mkdir: created directory ‘/usr/local/redis/conf’
[root@192.168.118.16 usr/local/src/redis-4.0.10]#yum install gcc* -y
[root@192.168.118.16 usr/local/src/redis-4.0.10]#make PREFIX=/usr/local/redis/ install
......
Hint: It's a good idea to run 'make test' ;)
INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install
make[1]: Leaving directory `/usr/local/src/redis-4.0.10/src'
复制
[root@192.168.118.16 usr/local/src/redis-4.0.10]#for i in {79..82};do cp -a redis.conf usr/local/redis/conf/63$i.conf ; done
[root@192.168.118.16 usr/local/src/redis-4.0.10]#cd usr/local/redis/conf/
[root@192.168.118.16 usr/local/redis/conf]#ls
6379.conf 6380.conf 6381.conf 6382.conf
[root@192.168.118.16 usr/local/redis/conf]#vim modify_conf.sh
# 保存这个修改配置文件的脚本,直接执行
#!/bin/bash
sed -i "s/daemonize no/daemonize yes/g" 6379.conf
sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" 6379.conf
sed -i "s/port 6379/port 6379/g" 6379.conf
sed -i "s/dbfilename dump.rdb/dbfilename dump-6379.rdb/g" 6379.conf
sed -i "s/redis_6379.pid/redis_6379.pid/g" 6379.conf
sed -i "s/dir \.\//dir \/usr\/local\/redis\/db\//g" 6379.conf
sed -i "s/logfile \"\"/logfile \"\/usr\/local\/redis\/log\/redis-6379.log\"/g" 6379.conf
sed -i "s/daemonize no/daemonize yes/g" 6380.conf
sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" 6380.conf
sed -i "s/port 6379/port 6380/g" 6380.conf
sed -i "s/dbfilename dump.rdb/dbfilename dump-6380.rdb/g" 6380.conf
sed -i "s/redis_6379.pid/redis_6380.pid/g" 6380.conf
sed -i "s/dir \.\//dir \/usr\/local\/redis\/db\//g" 6380.conf
sed -i "s/logfile \"\"/logfile \"\/usr\/local\/redis\/log\/redis-6380.log\"/g" 6380.conf
sed -i "s/daemonize no/daemonize yes/g" 6381.conf
sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" 6381.conf
sed -i "s/port 6379/port 6381/g" 6381.conf
sed -i "s/dbfilename dump.rdb/dbfilename dump-6381.rdb/g" 6381.conf
sed -i "s/redis_6379.pid/redis_6381.pid/g" 6381.conf
sed -i "s/dir \.\//dir \/usr\/local\/redis\/db\//g" 6381.conf
sed -i "s/logfile \"\"/logfile \"\/usr\/local\/redis\/log\/redis-6381.log\"/g" 6381.conf
sed -i "s/daemonize no/daemonize yes/g" 6382.conf
sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" 6382.conf
sed -i "s/port 6379/port 6382/g" 6382.conf
sed -i "s/dbfilename dump.rdb/dbfilename dump-6382.rdb/g" 6382.conf
sed -i "s/redis_6379.pid/redis_6382.pid/g" 6382.conf
sed -i "s/dir \.\//dir \/usr\/local\/redis\/db\//g" 6382.conf
sed -i "s/logfile \"\"/logfile \"\/usr\/local\/redis\/log\/redis-6382.log\"/g" 6382.conf
[root@192.168.118.16 usr/local/redis/conf]#sh modify_conf.sh
启动服务
[root@192.168.118.16 /usr/local/redis/conf]#echo "export PATH=$PATH:/usr/local/redis/bin" > /etc/profile.d/redis.sh
[root@192.168.118.16 /usr/local/redis/conf]#. /etc/profile.d/redis.sh
[root@192.168.118.16 /usr/local/redis/conf]#for i in {79..82}; do redis-server 63$i.conf ; done
[root@192.168.118.16 /usr/local/redis/conf]#netstat -ntplu | egrep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 14329/redis-server
tcp 0 0 0.0.0.0:6380 0.0.0.0:* LISTEN 14331/redis-server
tcp 0 0 0.0.0.0:6381 0.0.0.0:* LISTEN 14336/redis-server
tcp 0 0 0.0.0.0:6382 0.0.0.0:* LISTEN 14347/redis-server
复制
# 通过在从服务上执行 slaveof ip port 就可以实现主从复制
[root@192.168.118.16 /usr/local/redis/conf]#for i in {80..82};do redis-cli -p 63$i slaveof 192.168.118.16 6379 ; done
OK
OK
OK
# 查看复制状态,up为正常,down则为配置失败
[root@192.168.118.16 /usr/local/redis/conf]#for i in {80..82};do redis-cli -p 63$i info replication | egrep master_link_status; done
master_link_status:up
master_link_status:up
master_link_status:up
# 查看主服务,确认有三个从节点
[root@192.168.118.16 /usr/local/redis/conf]#redis-cli -p 6379 info replication | egrep slave
connected_slaves:3
slave0:ip=192.168.118.16,port=6380,state=online,offset=154,lag=1
slave1:ip=192.168.118.16,port=6381,state=online,offset=154,lag=1
slave2:ip=192.168.118.16,port=6382,state=online,offset=154,lag=0
复制
到此,主从配置已经完成,接下来配置哨兵模式
【哨兵节点配置】
[root@192.168.118.15 /usr/local/src]#tar xf redis-4.0.10.tar.gz
[root@192.168.118.15 /usr/local/src]#cd redis-4.0.10
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#mkdir -pv /usr/local/redis/{db,log,conf}
mkdir: created directory ‘/usr/local/redis’
mkdir: created directory ‘/usr/local/redis/db’
mkdir: created directory ‘/usr/local/redis/log’
mkdir: created directory ‘/usr/local/redis/conf’
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#yum install gcc* -y
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#make PREFIX=/usr/local/redis/ install
......
Hint: It's a good idea to run 'make test' ;)
INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install
make[1]: Leaving directory `/usr/local/src/redis-4.0.10/src'
复制
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#for i in {79..81}; do cp -a sentinel.conf /usr/local/redis/conf/263$i.conf; done
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#cd /usr/local/redis/conf/
[root@192.168.118.15 /usr/local/redis/conf]#ls
26379.conf 26380.conf 26381.conf
[root@192.168.118.15 /usr/local/redis/conf]#vim modify_conf.sh
#!/bin/bash
sed -i "s/port 26379/port 26379/g" 26379.conf
sed -i "s/# protected-mode no/prote cted-mode no/g" 26379.conf
sed -i "s/sentinel monitor mymaster 127.0.0.1 6379 2/sentinel monitor mymaster 192.168.118.16 6379 2/g" 26379.conf
sed -i "s/sentinel down-after-milliseconds mymaster 30000/sentinel down-after-milliseconds mymaster 3000/g" 26379.conf
sed -i "s/sentinel failover-timeout mymaster 180000/sentinel failover-timeout mymaster 10000/g" 26379.conf
sed -i "s/port 26379/port 26380/g" 26380.conf
sed -i "s/# protected-mode no/protected-mode no/g" 26380.conf
sed -i "s/sentinel monitor mymaster 127.0.0.1 6379 2/sentinel monitor mymaster 192.168.118.16 6379 2/g" 26380.conf
sed -i "s/sentinel down-after-milliseconds mymaster 30000/sentinel down-after-milliseconds mymaster 3000/g" 26380.conf
sed -i "s/sentinel failover-timeout mymaster 180000/sentinel failover-timeout mymaster 10000/g" 26380.conf
sed -i "s/port 26379/port 26381/g" 26381.conf
sed -i "s/# protected-mode no/protected-mode no/g" 26381.conf
sed -i "s/sentinel monitor mymaster 127.0.0.1 6379 2/sentinel monitor mymaster 192.168.118.16 6379 2/g" 26381.conf
sed -i "s/sentinel down-after-milliseconds mymaster 30000/sentinel down-after-milliseconds mymaster 3000/g" 26381.conf
sed -i "s/sentinel failover-timeout mymaster 180000/sentinel failover-timeout mymaster 10000/g" 26381.conf
复制
修改端口
sed -i "s/port 26379/port 26379/g" 26379.conf
启动哨兵模式一定要关闭保护模式,否则哨兵模式无法正常工作,这点很重要!
sed -i "s/# protected-mode no/prote cted-mode no/g" 26379.conf
修改监控的主节点IP和port
最后的值 2 表示:将主redis判断为失效至少需要 2 个哨兵进程的同意,如果只开启一个哨兵进程,这里一定要修改为 1 否则无法正常切换
sed -i "s/sentinel monitor mymaster 127.0.0.1 6379 2/sentinel monitor mymaster 192.168.118.16 6379 2/g" 26379.conf
哨兵进程判断服务器已经掉线所需的毫秒数
默认30秒,这里为了测试修改为 3 秒
sed -i "s/sentinel down-after-milliseconds mymaster 30000/sentinel down-after-milliseconds mymaster 3000/g" 26381.conf
实现主从切换,完成故障转移的所需要的最大时间值。若哨兵进程在该配置值内未完成故障转移的操作,则认为本次故障转移操作失败
默认为 180秒,这里为了测试修改为10秒
sed -i "s/sentinel failover-timeout mymaster 180000/sentinel failover-timeout mymaster 10000/g" 26379.conf
sentinel.conf参数修改详解
复制
[root@192.168.118.15 /usr/local/redis/conf]#sh modify_conf.sh
[root@192.168.118.15 /usr/local/redis/conf]#echo "export PATH=$PATH:/usr/local/redis/bin" > /etc/profile.d/redis.sh
[root@192.168.118.15 /usr/local/redis/conf]#. /etc/profile.d/redis.sh
复制
为了试试检测服务是否正常,这里开启三个 192.168.118.15 分别开启 哨兵服务
如果启动出现以下信息:
5325:X 05 Dec 12:40:55.149 * +sentinel sentinel 5945f760d81b3b733b55f7c49a198acd4c55a92b 192.168.118.15 26380 @ mymaster 192.168.118.16 6379
5325:X 05 Dec 12:40:58.238 # +sdown sentinel 5945f760d81b3b733b55f7c49a198acd4c55a92b 192.168.118.15 26380 @ mymaster 192.168.118.16 6379
复制
注意:首次启动时, 出现 'sdown sentinel' 的报错,需要删除配置文件从新进行配置。
启动三个哨兵服务,如果正常情况如下:
5456:X 05 Dec 12:47:09.843 # Sentinel ID is 15a3dd5bdf9d051efdcce70e4317767327774182
5456:X 05 Dec 12:47:09.843 # +monitor master mymaster 192.168.118.16 6379 quorum 2
5456:X 05 Dec 12:47:09.844 * +slave slave 192.168.118.16:6380 192.168.118.16 6380 @ mymaster 192.168.118.16 6379
5456:X 05 Dec 12:47:09.858 * +slave slave 192.168.118.16:6381 192.168.118.16 6381 @ mymaster 192.168.118.16 6379
5456:X 05 Dec 12:47:09.867 * +slave slave 192.168.118.16:6382 192.168.118.16 6382 @ mymaster 192.168.118.16 6379
5456:X 05 Dec 12:47:10.242 * +sentinel sentinel 351a2d5c31ec30ebf13cf452752863a1117643ac 192.168.118.15 26379 @ mymaster 192.168.118.16 6379
5456:X 05 Dec 12:47:11.701 * +sentinel sentinel f08e767831b200e7c70a2a4c6315205c7fec5a6e 192.168.118.15 26380 @ mymaster 192.168.118.16 6379
复制
到此,哨兵模式已经构建完成。接下来测试下主从切换。
【哨兵集群的测试】
测试1: 【停止 redis 主节点】
停止 redis 主节点
[root@192.168.118.16 /usr/local/redis/conf]#redis-cli -h 192.168.118.16 -p 6379 info replication
# Replication
role:master
connected_slaves:3
slave0:ip=192.168.118.16,port=6380,state=online,offset=292373,lag=1
slave1:ip=192.168.118.16,port=6381,state=online,offset=292373,lag=1
slave2:ip=192.168.118.16,port=6382,state=online,offset=292373,lag=1
master_replid:5eb5fdbeadd1ef178a27a3d84849b7a3eefe5b1b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:292373
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:292373
[root@192.168.118.16 /usr/local/redis/conf]#redis-cli -h 192.168.118.16 -p 6379 shutdown
复制
5412:X 05 Dec 13:08:52.573 # +sdown master mymaster 192.168.118.16 6379
5412:X 05 Dec 13:08:52.693 # +new-epoch 1
5412:X 05 Dec 13:08:52.704 # +vote-for-leader f08e767831b200e7c70a2a4c6315205c7fec5a6e 1
5412:X 05 Dec 13:08:53.704 # +odown master mymaster 192.168.118.16 6379 #quorum 3/2
5412:X 05 Dec 13:08:53.704 # Next failover delay: I will not start a failover before Wed Dec 5 13:09:13 2018
5412:X 05 Dec 13:08:53.785 # +config-update-from sentinel f08e767831b200e7c70a2a4c6315205c7fec5a6e 192.168.118.15 26380 @ mymaster 192.168.118.16 6379
5412:X 05 Dec 13:08:53.785 # +switch-master mymaster 192.168.118.16 6379 192.168.118.16 6382
5412:X 05 Dec 13:08:53.785 * +slave slave 192.168.118.16:6381 192.168.118.16 6381 @ mymaster 192.168.118.16 6382
5412:X 05 Dec 13:08:53.785 * +slave slave 192.168.118.16:6380 192.168.118.16 6380 @ mymaster 192.168.118.16 6382
5412:X 05 Dec 13:08:53.785 * +slave slave 192.168.118.16:6379 192.168.118.16 6379 @ mymaster 192.168.118.16 6382
5412:X 05 Dec 13:08:56.802 # +sdown slave 192.168.118.16:6379 192.168.118.16 6379 @ mymaster 192.168.118.16 6382
复制
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#redis-cli -p 26379
127.0.0.1:26379> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "192.168.118.16"
5) "port"
6) "6382"
复制
主节点已经切换完成,之前是 6379 已经切换为 6382
在redis节点确认 6382 已经被自动配置为主节点,所有从节点同步都指向了 6382
[root@192.168.118.16 /usr/local/redis/conf]#redis-cli -h 192.168.118.16 -p 6382 info replication | egrep slave
connected_slaves:2
slave0:ip=192.168.118.16,port=6381,state=online,offset=330543,lag=0
slave1:ip=192.168.118.16,port=6380,state=online,offset=330543,lag=0
复制
测试2:【 恢复 redis 之前主节点】
启动之前down的服务
[root@192.168.118.16 /usr/local/redis/conf]#redis-server 6379.conf
复制
5412:X 05 Dec 13:13:49.290 # -sdown slave 192.168.118.16:6379 192.168.118.16 6379 @ mymaster 192.168.118.16 6382
5412:X 05 Dec 13:13:59.205 * +convert-to-slave slave 192.168.118.16:6379 192.168.118.16 6379 @ mymaster 192.168.118.16 6382
复制
[root@192.168.118.15 /usr/local/src/redis-4.0.10]#redis-cli -p 26379
127.0.0.1:26379> sentinel slaves mymaster # 可以查看 mymaster 集群里 salves 的信息,这里查看到一共3台
1) 1) "name"
2) "192.168.118.16:6379" # 之前的主节点通过关闭,再启动之后已经变成从节点。
3) "ip"
4) "192.168.118.16"
5) "port"
6) "6379"
复制
通过测试,哨兵进程完成了对故障节点的转移。
【python连接哨兵模式】
程序连接redis主从和哨兵模式是不同的,这里通过python来连接哨兵集群,代码如下:
from redis.sentinel import Sentinel
sentinel = Sentinel([('192.168.118.15', 26379),
('192.168.118.15', 26380),
('192.168.118.15', 26381)], socket_timeout = 0.5)
master = sentinel.discover_master('mymaster')
print('redis 主节点: ', master)
slaves = sentinel.discover_slaves('mymaster')
print('redis 从节点集群: ', slaves)
# 使用主节点进行写入操作
master = sentinel.master_for('mymaster', db=0)
w_ret = master.set('foo', 'bar')
# 使用从节点读取数据
slave = sentinel.slave_for('mymaster', db=0)
r_ret = slave.get('foo')
print(r_ret)
# 执行结果:
# redis 主节点: ('192.168.118.16', 6382)
# redis 从节点集群: [('192.168.118.16', 6379), ('192.168.118.16', 6380), ('192.168.118.16', 6381)]
# b'bar'
python连接redis-sentinel模式
复制

版权声明:本文内容来自CSDN:hukey,遵循CC 4.0 BY-SA版权协议上原文接及本声明。
本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行可。
原文链接:https://www.cnblogs.com/hukey/p/10071704.html
如有涉及到侵权,请联系,将立即予以删除处理。
在此特别鸣谢原作者的创作。
此篇文章的所有版权归原作者所有,与本公众号无关,商业转载建议请联系原作者,非商业转载请注明出处。
复制