跳转至

54. redis主从复制原理及实现

1. 原理图

img_4.png

2. 原理文字说明

1.从服务器开启主从功能时,向主服务器发送sync命令(#1.第一次启动主从时 2.重新建立连接时)
2.接到sync命令的主服务器会调用bgsave命令,创建一个rdb文件,发送给从库
主服务器会将缓冲区记录记录接下来执行的所有写命令,再次传送给从库
3.当主服务器执行完bgsave命令时,它会向从服务器发送rdb文件,而从服务器则会接收并载入这个文件。
#至此,主从服务已经构建好了
4.主服务器将缓冲区储存的所有写命令以广播形式发送给从服务器执行

3. 可能出现的问题

主从复制不一致
复制有延时

4. 保证主从数据一致性的参数

min-slaves-to-write 1    #指定执行写操作所需的最少从服务器数量
min-slave-max-lag       #指定网络延迟的最大值

redis主从复制实现

1. 创建3个实例的目录

mkdir /data/638{0..2}

2. 编写配置文件

vim /data/6380/redis.conf

port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice
logfile "/data/6380/redis.log"
dbfilename dump.rdb
dir /data/6380
requirepass 123
masterauth 123
vim /data/6381/redis.conf

port 6381
daemonize yes
pidfile /data/6381/redis.pid
loglevel notice
logfile "/data/6381/redis.log"
dbfilename dump.rdb
dir /data/6381
requirepass 123
masterauth 123
vim /data/6382/redis.conf

port 6382
daemonize yes
pidfile /data/6382/redis.pid
loglevel notice
logfile "/data/6382/redis.log"
dbfilename dump.rdb
dir /data/6382
requirepass 123
masterauth 123

3. 启动3个实例

redis-server /data/6380/redis.conf

redis-server /data/6381/redis.conf

redis-server /data/6382/redis.conf

4. 查看示例运行情况

netstat -tunlp |grep 638
[root@152 6379]# redis-server /data/6380/redis.conf
[root@152 6379]# redis-server /data/6381/redis.conf
[root@152 6379]# redis-server /data/6382/redis.conf
[root@152 6379]# netstat -tunlp |grep 638
tcp        0      0 0.0.0.0:6380            0.0.0.0:*               LISTEN      104126/redis-server
tcp        0      0 0.0.0.0:6381            0.0.0.0:*               LISTEN      104128/redis-server
tcp        0      0 0.0.0.0:6382            0.0.0.0:*               LISTEN      104140/redis-server
tcp6       0      0 :::6380                 :::*                    LISTEN      104126/redis-server
tcp6       0      0 :::6381                 :::*                    LISTEN      104128/redis-server
tcp6       0      0 :::6382                 :::*                    LISTEN      104140/redis-server

5. 开启redis主从复制

#主库:6380    从库:6381、6382

#只需要在所有从库中执行命令即可
redis-cli -p 6381 -a 123
slaveof 127.0.0.1 6380

redis-cli -p 6382 -a 123
slaveof 127.0.0.1 6380
[root@152 6379]# redis-cli -p 6381 -a 123
127.0.0.1:6381> slaveof 127.0.0.1 6380
OK
127.0.0.1:6381> quit
[root@152 6379]# redis-cli -p 6382 -a 123
127.0.0.1:6382> slaveof 127.0.0.1 6380
OK
127.0.0.1:6382> quit

6. 查看主从复制状态

#主库可以监控从库的状态
redis-cli -p 6380 -a 123 info replication

redis-cli -p 6381 -a 123 info replication

redis-cli -p 6382 -a 123 info replication
#1.主库
[root@152 6379]# redis-cli -p 6380 -a 123 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=85,lag=1
slave1:ip=127.0.0.1,port=6382,state=online,offset=71,lag=1
master_repl_offset:85
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:84


#2.从库1
[root@152 6379]# redis-cli -p 6381 -a 123 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:85
slave_priority:100
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.从库2
[root@152 6379]# redis-cli -p 6382 -a 123 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:85
slave_priority:100
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

redis主从复制故障模拟

1. 关闭主库

redis-cli -p 6380 -a 123 shutdown

2. 从库查看主从状态

redis-cli -p 6381 -a 123 info replication
#可以根据此条 master_link_status:down ,看出主库是宕机状态
[root@152 6379]# redis-cli -p 6380 -a 123 shutdown

#1.
[root@152 6379]# redis-cli -p 6380 -a 123 info replication
Could not connect to Redis at 127.0.0.1:6380: Connection refused

#2.
[root@152 6379]# redis-cli -p 6381 -a 123 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:239
master_link_down_since_seconds:18
slave_priority:100
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.
[root@152 6379]# redis-cli -p 6382 -a 123 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:239
master_link_down_since_seconds:25
slave_priority:100
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. 所有从库取消主从

#6381
redis-cli -p 6381 -a 123
slaveof no noe

#6382
redis-cli -p 6382 -a 123
slaveof no noe
#1.原从库取消主从复制
[root@152 6379]# redis-cli -p 6381 -a 123
127.0.0.1:6381> slaveof no one
OK
127.0.0.1:6381> quit
[root@152 6379]# redis-cli -p 6382 -a 123
127.0.0.1:6382> slaveof no one
OK
127.0.0.1:6382> quit

#2.查看状态
[root@152 6379]# redis-cli -p 6381 -a 123 info replication
# Replication
role:master
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
[root@152 6379]# redis-cli -p 6382 -a 123 info replication
# Replication
role:master
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

4. 选择6381作为新主库,6382重新构建主从

#6382
redis-cli -p 6382 -a 123
slaveof 127.0.0.1 6381
[root@152 6379]# redis-cli -p 6382 -a 123
127.0.0.1:6382> slaveof 127.0.0.1 6381
OK
127.0.0.1:6382> quit

5. 查看主从状态

redis-cli -p 6381 -a 123 info replication

redis-cli -p 6382 -a 123 info replication
#1.6381:可以看出,有一个从库6382
[root@152 6379]# redis-cli -p 6381 -a 123 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6382,state=online,offset=1,lag=1
master_repl_offset:1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:0

#2.6382:可以看出,主库为6381
[root@152 6379]# redis-cli -p 6382 -a 123 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:1
slave_priority:100
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

6. 启动原主库6380并加入主从

redis-server /data/6380/redis.conf

#6380
redis-cli -p 6380 -a 123
slaveof 127.0.0.1 6381
[root@152 6379]# redis-server /data/6380/redis.conf
[root@152 6379]# redis-cli -p 6380 -a 123
127.0.0.1:6380> slaveof 127.0.0.1 6381
OK
127.0.0.1:6380> quit

7. 重新查看主从状态

redis-cli -p 6381 -a 123 info replication

redis-cli -p 6382 -a 123 info replication

redis-cli -p 6380 -a 123 info replication
#1.6381:主库
[root@152 6379]# redis-cli -p 6381 -a 123 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6382,state=online,offset=211,lag=0
slave1:ip=127.0.0.1,port=6380,state=online,offset=211,lag=1
master_repl_offset:211
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:210


#2.6382:从库1
[root@152 6379]# redis-cli -p 6382 -a 123 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:211
slave_priority:100
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.6380:从库2
[root@152 6379]# redis-cli -p 6380 -a 123 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:211
slave_priority:100
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
[root@152 6379]#

最后更新: 2022-02-20 08:44:07