Redis 的读写主从复制及哨兵(sentinel)配置

Redis主从复制可以一个reids服务宕机,导致应用宕机的情况。同时可以构建读写分离架构,满足业务量大并发高的使用场景。

Redis主从架构拓扑图结构

Redis主ä»æ¶æå¾ç¤º

主从架构的搭建

构建redis集群只需要启动多个实例即可,每个实例对应一个配置文件。这里我用到的端口分别是6379(master)、6380(slave)、6381(slave),直接把6379的配文件,复制为对应端口号命名的文件

[root@localhost etc]# cp 6379.conf 6380.conf
[root@localhost etc]# cp 6379.conf 6381.conf

修改6379的配置文件

requirepass 123456 //设置访问密码

分别修改6380、6381的配置文件

port 6380 //修改为对应的端口号

daemonize yes //允许守护进程启动

pidfile /var/run/redis_6380.pid //修改为对应的端口号

slaveof 127.0.0.1 6379 //复制功能,将作为6379的从服务器

masterauth 123456 //主服务器认证,填入主服务器的访问密码

requirepass 123456 //设置访问密码

启动redis实例

[root@localhost bin]# redis-server ../etc/6379.conf 
2253:C 30 Jul 17:28:52.270 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2253:C 30 Jul 17:28:52.271 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=2253, just started
2253:C 30 Jul 17:28:52.271 # Configuration loaded
[root@localhost bin]# redis-server ../etc/6380.conf 
2263:C 30 Jul 17:29:00.401 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2263:C 30 Jul 17:29:00.401 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=2263, just started
2263:C 30 Jul 17:29:00.401 # Configuration loaded
[root@localhost bin]# redis-server ../etc/6381.conf 
2269:C 30 Jul 17:29:04.394 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2269:C 30 Jul 17:29:04.395 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=2269, just started
2269:C 30 Jul 17:29:04.395 # Configuration loaded

来验证一下主从复制功能

[root@localhost ~]# redis-cli -p 6379
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=21363,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=21363,lag=0
master_replid:b8a5fb5265ed3757945eb741ebcec54c93978a70
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:21363
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:21363
127.0.0.1:6379> set test hello
OK
127.0.0.1:6379> exit
[root@localhost ~]# redis-cli -p 6380
127.0.0.1:6380> auth 123456
OK
127.0.0.1:6380> get test
"hello"
127.0.0.1:6380> exit
[root@localhost ~]# redis-cli -p 6381
127.0.0.1:6381> auth 123456
OK
127.0.0.1:6381> get test
"hello"

可以看到当主服务器写入命令,从服务器可以同步

当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库来升格为主数据库,以使得系统能够继续提供服务。然而整个过程相对麻烦且需要人工介入,难以实现自动化。 为此,Redis 2.4提供了哨兵工具来实现自动化的系统监控和故障恢复功能。
哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。

从redis源码包复制sentinel配置文件过去

[root@localhost redis-4.0.10]# cp sentinel.conf /usr/local/redis/etc/sentinel_6379.conf
[root@localhost redis-4.0.10]# cd /usr/local/redis/etc/
[root@localhost etc]# cp sentinel_6379.conf sentinel_6380.conf 
[root@localhost etc]# cp sentinel_6379.conf sentinel_6381.conf

分别编辑三个配置文件

//允许作为守护进程运行
daemonize yes
logfile="/usr/local/redis/logs/sentinel_6379.log"

// Sentinel节点的端口
port 26379

dir "/usr/local/redis/tmp"

// 当前Sentinel节点监控 127.0.0.1:6379 这个主节点
// 2代表判断主节点失败至少需要2个Sentinel节点节点同意
// mymaster是主节点的别名
sentinel monitor mymaster 127.0.0.1 6379 2

//设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同
sentinel auth-pass mymaster 123456

//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达
sentinel down-after-milliseconds mymaster 30000

//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1

//故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 180000

启动sentinel的方法:

  • redis-sentinel sentinel_6379.conf
  • redis-server sentinel_6379.conf --sentinel
[root@localhost bin]# redis-sentinel ../etc/sentinel_6379.conf --sentinel
[root@localhost bin]# redis-sentinel ../etc/sentinel_6380.conf --sentinel
[root@localhost bin]# redis-sentinel ../etc/sentinel_6381.conf --sentinel
[root@localhost bin]# ps -ef|grep redis
root      1040     1  0 17:03 ?        00:00:03 /usr/local/redis/bin/redis-server 127.0.0.1:6379
root      1052     1  0 17:03 ?        00:00:03 /usr/local/redis/bin/redis-server 127.0.0.1:6380
root      1063     1  0 17:03 ?        00:00:03 /usr/local/redis/bin/redis-server 127.0.0.1:6381
root      1372     1  0 17:35 ?        00:00:01 redis-sentinel *:26379 [sentinel]
root      1384     1  0 17:38 ?        00:00:00 redis-sentinel *:26380 [sentinel]
root      1393     1  0 17:40 ?        00:00:00 redis-sentinel *:26381 [sentinel]

部署好sentinel后,查看sentinel配置

# Generated by CONFIG REWRITE

// 发现了两个从节点
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380

// 发送了两个Sentinel节点
sentinel known-sentinel mymaster 127.0.0.1 26380 a3bbd7ef3cc298ab48d1d945fd2ca65cf34c7864
sentinel known-sentinel mymaster 127.0.0.1 26381 0cbcd8dd005d796c3010dad133ef1ceec41471b1
sentinel current-epoch 0

下面来试验一下

干掉6379端口

[root@localhost bin]# kill -9 1040
[root@localhost bin]# ps -aux | grep redis
root      1052  0.1  0.9 147356  9704 ?        Ssl  17:03   0:05 /usr/local/redis/bin/redis-server 127.0.0.1:6380
root      1063  0.1  0.9 147356  9700 ?        Ssl  17:03   0:04 /usr/local/redis/bin/redis-server 127.0.0.1:6381
root      1372  0.3  0.7 145304  7736 ?        Rsl  17:35   0:04 redis-sentinel *:26379 [sentinel]
root      1384  0.3  0.7 145304  7728 ?        Ssl  17:38   0:03 redis-sentinel *:26380 [sentinel]
root      1393  0.3  0.7 145304  7728 ?        Ssl  17:40   0:03 redis-sentinel *:26381 [sentinel]
root      1425  0.0  0.0 112704   972 pts/1    R+   17:57   0:00 grep --color=auto redis

查看sentinel日志,sentinel检测到了6379下线,将从节点6381切换为主节点

1495:X 31 Jul 21:14:17.186 # +sdown master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.238 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2
1495:X 31 Jul 21:14:17.238 # +new-epoch 1
1495:X 31 Jul 21:14:17.238 # +try-failover master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.242 # +vote-for-leader 5d098ba72d270b55cb39341afcdf2196383ebda4 1
1495:X 31 Jul 21:14:17.249 # 0cbcd8dd005d796c3010dad133ef1ceec41471b1 voted for 5d098ba72d270b55cb39341afcdf2196383ebda4 1
1495:X 31 Jul 21:14:17.250 # a3bbd7ef3cc298ab48d1d945fd2ca65cf34c7865 voted for 5d098ba72d270b55cb39341afcdf2196383ebda4 1
1495:X 31 Jul 21:14:17.326 # +elected-leader master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.326 # +failover-state-select-slave master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.427 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.427 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.479 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.830 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.830 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:17.879 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:18.357 # -odown master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:18.579 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:18.579 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:18.631 # +failover-end master mymaster 127.0.0.1 6379
1495:X 31 Jul 21:14:18.632 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381
1495:X 31 Jul 21:14:18.632 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
1495:X 31 Jul 21:14:18.632 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
1495:X 31 Jul 21:14:48.633 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381

可以看到主节点的端口号是6381了

 127.0.0.1:26379> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6381"
    7) "runid"
    8) "dd568a9d0599d1071360dc2b8e8ac1280886c80c"
    9) "flags"
   10) "master"

Sentinel节点监控的从节点信息

127.0.0.1:26379> sentinel slaves mymaster
1)  1) "name"
    2) "127.0.0.1:6380"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6380"
    7) "runid"
    8) "ebe180d1d6be990cc0b6f7bb7e9b8fa9ffce4342"
    9) "flags"
   10) "slave"
……
2)  1) "name"
    2) "127.0.0.1:6379"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6379"
    7) "runid"
    8) ""
    9) "flags"
   10) "s_down,slave,disconnected"
 

6380还是作为从节点,6379变成了从节点,已经下线 

由以上信息可得,端口为6380的Redis数据节点成为新的主节点,端口为6379的旧主节点断开连接。

试着重启端口6379的数据节点

[root@localhost ~]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/6379.conf 
1608:C 31 Jul 21:28:22.993 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1608:C 31 Jul 21:28:22.994 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=1608, just started
1608:C 31 Jul 21:28:22.994 # Configuration loaded
[root@localhost ~]# ps -ef|grep redis
root      1046     1  0 19:36 ?        00:00:09 /usr/local/redis/bin/redis-server 127.0.0.1:6380
root      1058     1  0 19:36 ?        00:00:09 /usr/local/redis/bin/redis-server 127.0.0.1:6381
root      1495     1  0 20:31 ?        00:00:10 /usr/local/redis/bin/redis-server *:26379 [sentinel]
root      1551     1  0 20:47 ?        00:00:07 /usr/local/redis/bin/redis-server *:26381 [sentinel]
root      1563     1  0 20:51 ?        00:00:06 /usr/local/redis/bin/redis-server *:26380 [sentinel]
root      1609     1  0 21:28 ?        00:00:00 /usr/local/redis/bin/redis-server 127.0.0.1:6379

 在查看一下sentinel主节点信息

127.0.0.1:26379> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6381"
    7) "runid"
    8) "dd568a9d0599d1071360dc2b8e8ac1280886c80c"
    9) "flags"
   10) "master"

可以看到尽管6379已经起来了,但是6381还是主节点

再看从节点信息

127.0.0.1:26379> sentinel slaves mymaster
1)  1) "name"
    2) "127.0.0.1:6380"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6380"
    7) "runid"
    8) "ebe180d1d6be990cc0b6f7bb7e9b8fa9ffce4342"
    9) "flags"
   10) "slave"
……
2)  1) "name"
    2) "127.0.0.1:6379"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6379"
    7) "runid"
    8) "d8ec483539434abe548a5567ed083f53d4755296"
    9) "flags"
   10) "slave" 

6379还是作为从节点

从上面的逻辑架构和故障转移试验中,可以看出Redis Sentinel的以下几个功能。

  • 监控:Sentinel节点会定期检测Redis数据节点和其余Sentinel节点是否可达。
  • 通知:Sentinel节点会将故障转移通知给应用方。
  • 主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系。
  • 配置提供者:在Redis Sentinel结构中,客户端在初始化的时候连接的是Sentinel节点集合,从中获取主节点信息。

猜你喜欢

转载自blog.csdn.net/Derek_Yam/article/details/81286637