Skip to content

Redis主从复制

1.是什么

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

2.能干嘛

1.读写分离,性能扩展

2.容灾快速恢复

image-20220822104619830

3.怎么玩:主从复制

​ 这里只是在一台服务器模拟主从复制,如果需要在不同的服务器,则需要在每台服务器上都安装redis,并修改相关配置

1.拷贝一份redis.conf文件

image-20220822121100143

2.新建redis6379.conf

​ 这里我已经安装好了redis,只需要修改拷贝多个redis.conf配置文件,根据配置文件来进行启动即可。

​ redis中的include有点类似于jsp中的include,这里我们用include来引入之前的配置,在redis6379.conf指定需要修改的配置。

shell
#进入到myredis目录
[root@bogon myredis]# cd /usr/local/src/myredis/
#查看redis6379.conf,如果文件不存在则执行wq保存创建
[root@bogon myredis]# vi redis6379.conf 

#进入到redis6379.conf文件
#引入我们前拷贝的redis.conf配置,使用绝对路径
include /usr/local/src/myredis/redis.conf
#设置pid文件名
pidfile /var/run/redis_6379.pid
#设置端口号
port 6379
#设置rdb文件名
dbfilename dump6379.rdb

3.新建redis6380.conf,填写以下内容

1.直接拷贝redis6379.conf到redis.6380.conf

image-20220822122638795

2.修改redis.6380.conf配置文件

shell
include /usr/local/src/myredis/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb

4.新建redis6381.conf,填写以下内容

操作同上

shell
include /usr/local/src/myredis/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb

5.启动三台redis服务

shell
[root@bogon src]# redis-server myredis/redis6379.conf 
[root@bogon src]# redis-server myredis/redis6380.conf 
[root@bogon src]# redis-server myredis/redis6381.conf

6.查看系统进程,三个redis服务是否启动成功

shell
[root@bogon src]# ps -ef|grep redis
root     43544     1  0 12:36 ?        00:00:00 redis-server *:6379
root     43616     1  0 12:38 ?        00:00:00 redis-server *:6380
root     43622     1  3 12:38 ?        00:00:00 redis-server *:6381
root     43628 42446  0 12:38 pts/2    00:00:00 grep --color=auto redis

7.查看三台主机运行情况

shell
#打印主从复制的相关信息
info replication

6379

shell
[root@bogon src]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
#master主机,salve从机
role:master
#从机连接数
connected_slaves:0
master_failover_state:no-failover
master_replid:27adfc249e25e91ae6f7c858a73dccbd0cc9b53a
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:6379>

6380

shell
[root@bogon ~]# redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:12395b0df61b3d553f3c24346e20a4778122a66a
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>

6381

shell
[root@bogon ~]# redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:4a7382d9a851b02a069b99f089d93a3c11f6e6c9
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>

7.配置从库

这里以6379作为主库,6380、6381作为从库。

shell
#成为某个实例的从服务器
#将当前服务设置为从库,从属于ip port的主机,如果是其他服务器则指定该服务器的ip、端口
slaveof  <ip><port>

1、在6380和6381上执行: slaveof 127.0.0.1 6379

6380

shell
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:168
slave_priority:100
slave_read_only:1
connected_slaves:0
master_failover_state:no-failover
master_replid:46453fed0a522865720b02b94b4e32c7c3ef8ada
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:168

6381

shell
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:252
slave_priority:100
slave_read_only:1
connected_slaves:0
master_failover_state:no-failover
master_replid:46453fed0a522865720b02b94b4e32c7c3ef8ada
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:252
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:99
repl_backlog_histlen:154

6379

shell
127.0.0.1:6379> info replication
# Replication
role:master
#可以看到有两台从机
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=308,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=308,lag=1
master_failover_state:no-failover
master_replid:46453fed0a522865720b02b94b4e32c7c3ef8ada
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:308
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:308
127.0.0.1:6379>

2、在主机上可读可写,在从机上只能读取数据,写数据会报错

(1)主机可读可写,从机可读

image-20220822125749389

image-20220822125832121

image-20220822125844249

(2)从机只能读,不能写

image-20220822125930500

3、主机挂掉,重启就行,一切如初

当主机挂掉,重启只会从机还是认主机的,身份不会发生改变

image-20220822130140061

image-20220822130201249

4、从机重启需重设:slaveof 127.0.0.1 6379,也可以将配置增加到文件中。永久生效。

image-20220822131001380

从机重启,会重新拉取主机的数据进行同步

4.薪火相传

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。

shell
#在从机C中指定另一台从机B的ip和端口,
#这样B对于C来说就是主机,B可以进行写操作
slaveof  <ip><port>

image-20220822131940285

1.中途变更转向:会清除之前的数据,重新建立拷贝最新的

2.风险是一旦某个slave宕机,后面的slave都没法备份

3.主机挂了,从机还是从机,无法写数据了

5.反客为主

当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。用 slaveof no one 将从机变为主机。

shell
#将从机变成主机
slaveof  no one

关闭主机

image-20220822132435038

将从机从主机变为主机

image-20220822132522853

6.复制原理

1.Slave启动成功连接到master后会发送一个sync命令

2.Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步

3.全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

4.增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

5.但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

image-20220822132635130