(九)、Redis主从复制

概念

主从复制,主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

主从复制环境搭建

复制三个Redis配置文件,分别更改里面的日志文件名称、不同的端口号、RDB文件的名称、快照开启

daemonize yes
logfile "6379.log"
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump79.rdb
daemonize yes
logfile "6380.log"
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump80.rdb
daemonize yes
logfile "6381.log"
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump81.rdb

Redis端口准备完毕

[root@VM-4-15-centos myredis]# ps -ef|grep redis
root      1589     1  0 21:37 ?        00:00:17 redis-server 127.0.0.1:6380
root      1661     1  0 21:37 ?        00:00:14 redis-server 127.0.0.1:6381
root     25093 30799  0 23:23 pts/0    00:00:00 redis-cli -p 6379
root     25162  1192  0 23:23 pts/1    00:00:00 redis-cli -p 6380
root     25305  1289  0 23:24 pts/2    00:00:00 redis-cli -p 6381

查看具体信息,三个机器

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:792005b03b49fde4d36a9fc24c2c64add164eeeb
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
127.0.0.1:6380>  info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:760bbf4ee817db6ad5a2fb5a41d799ba23854d56
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
127.0.0.1:6381>  info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:5cb1b5303d59b9c7a1624096eedbd821cbc098c7
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

在主机6379中添加三个数据

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK

从机6380备份

127.0.0.1:6380> keys *
(empty array)
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> keys *
1) "k1"
2) "k2"
3) "k3"

从机6381备份

127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
127.0.0.1:6381> keys *
1) "k2"
2) "k3"
3) "k1"

一主两从模式

一个Master两个Slave

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=266,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=252,lag=1
master_failover_state:no-failover
master_replid:45e9cc2c8fbcaf4447dd2399e2a42a13dccf0707
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:266
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:266

主从备份切入点

从机在备份时候,会从主机从头到尾开始复制过来,无论从机什么时候连接上主机的

从机是否能写入数据

6381从机中写入数据失败

127.0.0.1:6381> set k5 v5
(error) READONLY You can't write against a read only replica.

从机不能写入数据,只读

主机关机之后,从机状态

主机6379关机

127.0.0.1:6379> shutdown
not connected> exit

从机63806381还是原地待命

127.0.0.1:6380>  info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1298
master_link_down_since_seconds:105
slave_priority:100
slave_read_only:1
connected_slaves:0
master_failover_state:no-failover
master_replid:45e9cc2c8fbcaf4447dd2399e2a42a13dccf0707
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1298
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1298
127.0.0.1:6381>  info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1298
master_link_down_since_seconds:97
slave_priority:100
slave_read_only:1
connected_slaves:0
master_failover_state:no-failover
master_replid:45e9cc2c8fbcaf4447dd2399e2a42a13dccf0707
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1298
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:127
repl_backlog_histlen:1172

主机恢复之后,从机数据能否保持一致

主机6379重新连接,并新增一条数据

[root@VM-4-15-centos myredis]# redis-server /root/myredis/redis79.conf
[root@VM-4-15-centos myredis]# redis-cli -p 6379
127.0.0.1:6379> keys *
1) "k4"
2) "k3"
3) "k1"
4) "k2"
127.0.0.1:6379> set k5 v5
OK

63816380从机会继续备份

127.0.0.1:6381> keys *
1) "k4"
2) "k5"
3) "k2"
4) "k3"
5) "k1"

从机断开一段时间之后,数据能否一致

6380从机关机

127.0.0.1:6380> shutdown
not connected> exit

在主机6379中新增数据

127.0.0.1:6379> keys *
1) "k5"
2) "k2"
3) "k1"
4) "k3"
5) "k4"
127.0.0.1:6379> set k6 v6
OK

在另一个6381从机中查询

127.0.0.1:6381> get k6
"v6"

这时候从机6380恢复

[root@VM-4-15-centos ~]# redis-server /root/myredis/redis80.conf
[root@VM-4-15-centos ~]# redis-cli -p 6380

查看信息已经和主机断连,不再是从机状态

127.0.0.1:6380>  info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:caece3e0a3cb3c2eb950267241ce5ab304efd8bd
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

这时候主机6379新增一条数据

127.0.0.1:6379> set k9 v9
OK

从机6380查询不到

127.0.0.1:6380> get k9
(nil)

每次从机和master主机断开之后需要重新连接,除非写进配置文件自动重连,具体位置redis.conf搜寻#### REPLICATION ####

从机上位模式

使当前数据库停止与其他数据库的同步,转成主数据库

SLAVEOF no one

薪火相传模式

  • 上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力(奴隶的奴隶还是奴隶)
  • 中途变更转向:会清除之前的数据,重新建立拷贝最新的
  • slaveof 新主库IP 新主库端口

复制原理

slave启动成功连接到master后会发送一个sync命令
master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

哨兵模式

能够自动监控主机,如果主机挂了,在剩余的从机里面用投票的方式决定新的主机

哨兵模式配置

6379为主机,6380、6381为从机

创建一个文件,配置哨兵

[root@VM-4-15-centos myredis]# touch sentinel.conf
[root@VM-4-15-centos myredis]# vim sintinel.conf
sentinel monitor host6379 127.0.0.1 6379 1

最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机

启动哨兵

在redis安装目录下启动,哨兵开始巡逻

[root@VM-4-15-centos redis-6.2.1]# redis-sentinel  /root/myredis/sentinel.conf
30353:X 16 Aug 2021 22:46:55.419 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
30353:X 16 Aug 2021 22:46:55.419 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=30353, just started
30353:X 16 Aug 2021 22:46:55.419 # Configuration loaded
30353:X 16 Aug 2021 22:46:55.419 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.2.1 (00000000/0) 64 bit
  .-`` .-```.  ```/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 30353
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

30353:X 16 Aug 2021 22:46:55.420 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
30353:X 16 Aug 2021 22:46:55.420 # Sentinel ID is 8206264712b3f0688eb364d8e1353eec683fb659
30353:X 16 Aug 2021 22:46:55.420 # +monitor master host6379 127.0.0.1 6379 quorum 1
30353:X 16 Aug 2021 22:46:55.422 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:46:55.434 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379

关闭主机6379

127.0.0.1:6379> shutdown
not connected> exit

等待哨兵巡逻投票新的主机

0353:X 16 Aug 2021 22:49:33.543 # +new-epoch 1
30353:X 16 Aug 2021 22:49:33.543 # +try-failover master host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.549 # +vote-for-leader 8206264712b3f0688eb364d8e1353eec683fb659 1
30353:X 16 Aug 2021 22:49:33.549 # +elected-leader master host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.549 # +failover-state-select-slave master host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.632 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.632 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.732 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.973 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:33.973 # +failover-state-reconf-slaves master host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:34.022 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:35.015 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:35.015 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:35.086 # +failover-end master host6379 127.0.0.1 6379
30353:X 16 Aug 2021 22:49:35.086 # +switch-master host6379 127.0.0.1 6379 127.0.0.1 6380
30353:X 16 Aug 2021 22:49:35.086 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ host6379 127.0.0.1 6380
30353:X 16 Aug 2021 22:49:35.086 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380
30353:X 16 Aug 2021 22:50:05.090 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ host6379 127.0.0.1 6380

最后主机为6380

127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=20619,lag=1
master_failover_state:no-failover
master_replid:9decacfce1e69d40a1cd37600881919ab4ef464d
master_replid2:eec2ebe84740b484344d0e4ffba5cdc29e0d5c54
master_repl_offset:20619
second_repl_offset:10146
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:20619

当之前挂掉的主机6379重新连接上,这时候还是单独的主机

[root@VM-4-15-centos ~]# redis-server /root/myredis/redis79.conf
[root@VM-4-15-centos ~]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:a911210268512fd5125a73fe0db7a5175126d161
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

过一会被哨兵监控到,挂了的master重启回来,会变成slave

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:32598
slave_priority:100
slave_read_only:1
connected_slaves:0
master_failover_state:no-failover
master_replid:9decacfce1e69d40a1cd37600881919ab4ef464d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:32598
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:28369
repl_backlog_histlen:4230

复制延时

由于所有的写操作都是先在Master上操作,然后同步更新到slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

原文地址:https://www.cnblogs.com/cg-ww/p/15176264.html