程序猿
微录

Redis 主从集群与哨兵机制

程序猿微录 发布于: 2020-08-04 04:12 129 0 0 0
首页
文章
专栏
问答
寄语
公告
  • 前往登录

Redis 主从集群与哨兵机制

程序猿微录 发布于 2020-08-04 04:12 129 0 0 0
所属文册: Redis 文章标签: Redis 、主从 、哨兵

Redis 主从集群与哨兵机制

Redis的QPS可以达到10W/s,基本情况下单机已经可以满足了。当对性能要求更高时,一般都会采用集群方案来解决。

集群方案可以避免

  • 当数据量过大时性能瓶颈是硬件资源,而直接扩展硬件则利用率太低了;
  • 当Redis服务宕机时,对服务访问会产生严重影响;
  • 当Redis服务硬件损坏时,会造成不可恢复的灾难影响。

集群方案有很多,最简单的就是主从模式+哨兵模式。

一主二从示例

配置文件

master:使用默认的配置文件
port 6379

slave:使用默认的配置文件,修改端口配置,新增主从节点配置

  • 端口号
port 6380
  • 主节点配置: 注意这是v6.0.6。由于master-salve关键字被投票变更了,原来的slave改为replica
# replicaof <masterip> <masterport>
replicaof 127.0.0.1 6379
  • 如果master节点有密码,则需要配置密码
# masterauth <master-password>
# masterauth 123456

启动命令

master

 redis-server.exe

slave1

 redis-server.exe ../redis-6380.conf

salve2

 redis-server.exe ../redis-6381.conf

节点查询

127.0.0.1:0>info  Replication
"# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=2114,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=2114,lag=0
master_replid:229fe4bb558e5d5d60888cd22b8c4899595c9215
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2114
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2114
"

在主从集群中,主节点是读、写操作,从节点是只读操作。该属性可在配置文件中配置

127.0.0.1:0>get msg
"hello word"
127.0.0.1:0>set str  str
"OK"

localhost-slave-6380:0>get  msg
"hello word"
localhost-slave-6380:0>set msg  a
"READONLY You can't write against a read only replica.  "

主要参数

repl_timeout: 主从超时时间:默认60(s)


在RedisServer启动时,根据配置的config_hz启动定时任务serverCron。在这个任务中存在

run_with_period(1000) replicationCron();

在这个每秒执行主从复制的定时任务中,存在server.repl_timeout超时取消。

  • 主从连接超时
  • 主从数据传输超时
  • 主从无数据传输超时

repl-disable-tcp-nodelay: 主从复制数据传输时TCP是否禁用TCP_NODELAY。默认no


 if (server.repl_disable_tcp_nodelay)
        connDisableTcpNoDelay(c->conn); 

主从复制流程

  1. 服务启动从replicaof获取master节点地址
  2. 建立master节点通信
  3. master节点生成RDB文件,传输给salve节点,完成初次的全量复制
    1. 在master生成RDB期间,新接收的命令会缓存起来,在传输时一起传输到salve
  4. salve对接收到的RDB文件进行恢复,完成复制
  5. 后续节点通过命令传播机制,主节点执行的命令会传播到从节点再次执行

sentinel(哨兵)

sentinel(哨兵):用来监控、管理Redis集群。主要解决的是主从复制集群方案中出现节点宕机后主从问题。

多个sentinel不仅监控集群中的每一个Server节点,还监控其他的sentinel节点。

主要功能

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
  • 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

sentinel监控图示

Image [32].png

配置文件

哨兵1(sentinel.conf)

port 26379			

dir "../../logs"					

sentinel monitor mymaster 127.0.0.1 6379 2		

sentinel down-after-milliseconds mymaster 30000

sentinel parallel-syncs mymaster 1

sentinel failover-timeout mymaster 180000

哨兵2(sentinel-26380.conf)

port 26380			

dir "../../logs"			

sentinel monitor mymaster 127.0.0.1 6379 2		

sentinel down-after-milliseconds mymaster 30000

sentinel parallel-syncs mymaster 1

sentinel failover-timeout mymaster 180000

哨兵3(sentinel-26381.conf)

port 26381			

dir "../../logs"				

sentinel monitor mymaster 127.0.0.1 6379 2		

sentinel down-after-milliseconds mymaster 30000

sentinel parallel-syncs mymaster 1

sentinel failover-timeout mymaster 180000

启动

可以用redis-sentinel命令启动,也可以用

redis-server --sentinel命令启动

哨兵1:只监控到了主从

redis-sentinel.exe ../sentinel.conf
1075:X 04 Aug 2020 14:25:46.742 # Sentinel ID is cc5d8ced88de425bb2d2fa6a267e3ad86923b12e
1075:X 04 Aug 2020 14:25:46.742 # +monitor master mymaster 127.0.0.1 6379 quorum 2
1075:X 04 Aug 2020 14:25:46.746 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1075:X 04 Aug 2020 14:25:46.749 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

哨兵2:监控到了主从和已经启动的哨兵1

redis-sentinel.exe  ../sentinel-26380.conf
1076:X 04 Aug 2020 14:26:53.428 # Sentinel ID is 73f58d1263bb36298e11399fc6c63f98fdc6f64a
1076:X 04 Aug 2020 14:26:53.428 # +monitor master mymaster 127.0.0.1 6379 quorum 2
1076:X 04 Aug 2020 14:26:53.433 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1076:X 04 Aug 2020 14:26:53.436 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1076:X 04 Aug 2020 14:26:54.222 * +sentinel sentinel cc5d8ced88de425bb2d2fa6a267e3ad86923b12e 127.0.0.1 26379 @ mymaster 127.0.0.1 6379

哨兵3:监控到了主从和已启动的哨兵1和哨兵2

 redis-server.exe ../sentinel-26381.conf --sentinel
1077:X 04 Aug 2020 14:28:46.733 # Sentinel ID is c6a316bc1e0e18ad086c0a32de506f26abfbc393
1077:X 04 Aug 2020 14:28:46.733 # +monitor master mymaster 127.0.0.1 6379 quorum 2
1077:X 04 Aug 2020 14:28:46.740 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:28:46.743 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:28:47.960 * +sentinel sentinel 73f58d1263bb36298e11399fc6c63f98fdc6f64a 127.0.0.1 26380 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:28:48.644 * +sentinel sentinel cc5d8ced88de425bb2d2fa6a267e3ad86923b12e 127.0.0.1 26379 @ mymaster 127.0.0.1 6379

从启动日志也可以看出来,哨兵不仅监控Redis主从,还监控其他哨兵。哨兵1和哨兵2最后也会监控哨兵3

启动验证

sentinel:0>info replication
"# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=66246,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=66246,lag=0
master_replid:229fe4bb558e5d5d60888cd22b8c4899595c9215
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:66246
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:66246
"
sentinel:0>

故障迁移

关闭master节点验证,等待30秒

哨兵1:

1075:X 04 Aug 2020 14:46:03.706 # +sdown master mymaster 127.0.0.1 6379
1075:X 04 Aug 2020 14:46:03.717 # +new-epoch 1
1075:X 04 Aug 2020 14:46:03.722 # +vote-for-leader c6a316bc1e0e18ad086c0a32de506f26abfbc393 1
1075:X 04 Aug 2020 14:46:03.786 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2
1075:X 04 Aug 2020 14:46:03.787 # Next failover delay: I will not start a failover before Tue Aug  4 14:52:04 2020
1075:X 04 Aug 2020 14:46:04.956 # +config-update-from sentinel c6a316bc1e0e18ad086c0a32de506f26abfbc393 127.0.0.1 26381 @ mymaster 127.0.0.1 6379
1075:X 04 Aug 2020 14:46:04.957 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
1075:X 04 Aug 2020 14:46:04.959 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
1075:X 04 Aug 2020 14:46:04.959 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
1075:X 04 Aug 2020 14:46:34.962 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

哨兵2:

1076:X 04 Aug 2020 14:46:03.393 # +sdown master mymaster 127.0.0.1 6379
1076:X 04 Aug 2020 14:46:03.719 # +new-epoch 1
1076:X 04 Aug 2020 14:46:03.722 # +vote-for-leader c6a316bc1e0e18ad086c0a32de506f26abfbc393 1
1076:X 04 Aug 2020 14:46:04.526 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2
1076:X 04 Aug 2020 14:46:04.530 # Next failover delay: I will not start a failover before Tue Aug  4 14:52:03 2020
1076:X 04 Aug 2020 14:46:04.955 # +config-update-from sentinel c6a316bc1e0e18ad086c0a32de506f26abfbc393 127.0.0.1 26381 @ mymaster 127.0.0.1 6379
1076:X 04 Aug 2020 14:46:04.956 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
1076:X 04 Aug 2020 14:46:04.957 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
1076:X 04 Aug 2020 14:46:04.957 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
1076:X 04 Aug 2020 14:46:34.987 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

哨兵3:

1077:X 04 Aug 2020 14:46:03.611 # +sdown master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:03.703 # +odown master mymaster 127.0.0.1 6379 #quorum 2/2
1077:X 04 Aug 2020 14:46:03.703 # +new-epoch 1
1077:X 04 Aug 2020 14:46:03.703 # +try-failover master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:03.708 # +vote-for-leader c6a316bc1e0e18ad086c0a32de506f26abfbc393 1
1077:X 04 Aug 2020 14:46:03.724 # cc5d8ced88de425bb2d2fa6a267e3ad86923b12e voted for c6a316bc1e0e18ad086c0a32de506f26abfbc393 1
1077:X 04 Aug 2020 14:46:03.726 # 73f58d1263bb36298e11399fc6c63f98fdc6f64a voted for c6a316bc1e0e18ad086c0a32de506f26abfbc393 1
1077:X 04 Aug 2020 14:46:03.811 # +elected-leader master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:03.812 # +failover-state-select-slave master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:03.909 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:03.910 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:03.980 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:04.870 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:04.871 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:04.950 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:05.865 # -odown master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:05.975 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:05.975 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:06.051 # +failover-end master mymaster 127.0.0.1 6379
1077:X 04 Aug 2020 14:46:06.053 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
1077:X 04 Aug 2020 14:46:06.056 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
1077:X 04 Aug 2020 14:46:06.058 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
1077:X 04 Aug 2020 14:46:36.101 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

日志说明

为了能看懂以上启动日志,展示部分的日志说明

+reset-master <instance details> :主服务器已被重置。

+slave <instance details> :一个新的从服务器已经被 Sentinel 识别并关联。

+failover-state-reconf-slaves <instance details> :故障转移状态切换到了 reconf-slaves 状态。

+failover-detected <instance details> :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成了主服务器。

+slave-reconf-sent <instance details> :领头(leader)的 Sentinel 向实例发送了 SLAVEOF host port 命令,为实例设置新的主服务器。

+slave-reconf-inprog <instance details> :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。

+slave-reconf-done <instance details> :从服务器已经成功完成对新主服务器的同步。

-dup-sentinel <instance details> :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除 —— 当 Sentinel 实例重启的时候,就会出现这种情况。

+sentinel <instance details> :一个监视给定主服务器的新 Sentinel 已经被识别并添加。

+sdown <instance details> :给定的实例现在处于主观下线状态。

-sdown <instance details> :给定的实例已经不再处于主观下线状态。

+odown <instance details> :给定的实例现在处于客观下线状态。

-odown <instance details> :给定的实例已经不再处于客观下线状态。

+new-epoch <instance details> :当前的纪元(epoch)已经被更新。

+try-failover <instance details> :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中(waiting to be elected by the majority)。

+elected-leader <instance details> :赢得指定纪元的选举,可以进行故障迁移操作了。

+failover-state-select-slave <instance details> :故障转移操作现在处于 select-slave 状态 —— Sentinel 正在寻找可以升级为主服务器的从服务器。

no-good-slave <instance details> :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。

selected-slave <instance details> :Sentinel 顺利找到适合进行升级的从服务器。

failover-state-send-slaveof-noone <instance details> :Sentinel 正在将指定的从服务器升级为主服务器,等待升级功能完成。

failover-end-for-timeout <instance details> :故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaves will eventually be configured to replicate with the new master anyway)。

failover-end <instance details> :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。

+switch-master <master name> <oldip> <oldport> <newip> <newport> :配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。




在哨兵3中存在主从切换的信息

+switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380

结合日志说明,主服务器从6379切换到了6380。查看新的主服务器信息如下

localhost-slave-6380:0>info replication
"# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=504998,lag=1
master_replid:3a299441d6f9bb65ad21c7dc0dfc569004202b5a
master_replid2:4cc7a8b732eadcf56dafb1bd0506a85fc6cccf78
master_repl_offset:505264
second_repl_offset:448871
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:505264
"

此时再启动6379服务器

哨兵1:

1075:X 04 Aug 2020 15:01:44.393 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
1075:X 04 Aug 2020 15:01:54.400 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

哨兵2:

1076:X 04 Aug 2020 15:01:44.493 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

哨兵3:

1077:X 04 Aug 2020 15:01:44.719 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

可以看出来重新启动后,原来的主服务器变成了从服务器,而且所有哨兵都监控到了,并标记为非主观下线状态。