述
上文中,介绍了两种redis的持久化方式,分别是RDB和AOF的方式,下面再来看看redis中的主从复制.
主从配置也是一种数据备份的方案,而且可以在一定程度上提升redis性能,redis的主从复制和关系型数据库中的主从复制类似, 从机可以精确的复制主机上的数据, 配置好主从之后,一方面能够实现读写分离,降低master的压力,另一方面也可以用来数据备份
环境准备
我们就在一台服务器上,运行3个redis的实例, 首先,需要找到redis的目录,然后找到配置文件redis.conf
,复制三份出来,名称分别是redis-6379.conf
,redis-6380.conf
,redis-6381.conf
, 然后分别打开这三个配置文件,找到一些需要修改的配置改掉,具体有以下几个:1
2
3
4
5port 6379
pidfile /var/run/redis_6379.pid
logfile "6379.log"
dbfilename dump6379.rdb
appendfilename "appendonly6379.aof"
找到这几个配置,各自改成各自的配置,就ok了.
然后可以分去指定配置文件去启动,如下命令:1
2
3redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf
这时候就启动了三个reids了,然后如果需要通过redis-cli连接的话,只需要通过-p指定端口号就ok了
也可以通过用docker的方式再启动两个redis,具体方法请前往docker的分类下查看
这里我已经启动了三个redis实例了,然后通过redis-cli连接一下试试, 如下:
我这里的三个实例的地址分别是:1
2
3172.16.12.3:6379
172.16.12.3:6380
172.16.12.3:6381
主从配置
假设这三个实例中,6379是主机,也就是master,剩下的6380和6381是从机即slave,那么需要在从机上执行以下命令:1
2172.16.12.3:6380> slaveof 172.16.12.3 6379
OK
1 | 172.16.12.3:6381> slaveof 172.16.12.3 6379 |
也可以在两个从机的redis.conf中加入以下配置构建主从:1
slaveof 172.16.12.3 6379
这里有一个需要注意的地方,如果我们的主机设置了密码了, 那么需要在从机的配置中加入以下配置:1
masterauth 123456
123456是我主机的密码,不设置的话可能会导致从机连接不到主机
ok,主从搭建好之后,就可以通过命令查看每个实例的状态,如下:1
2
3
4
5
6
7
8
9
10
11172.16.12.3:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.1,port=6380,state=online,offset=57,lag=1
slave1:ip=172.17.0.1,port=6381,state=online,offset=57,lag=1
master_repl_offset:57
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:56
在6379上面执行INFO replication
,可以看到他的角色是master,然后下面有两个连接到的从机slave0和slave1,他们的ip端口这里都有
然后在从机上执行这个命令,返回如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17172.16.12.3:6381> INFO replication
# Replication
role:slave
master_host:172.16.12.3
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:407
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
这里就可以看到6381的角色是从机,而且还显示了他的主机的端口和ip地址
测试
配置完成之后,在主机上新添加一条数据:1
2172.16.12.3:6379> set k1 testv1
OK
然后再从机上去get,如下:1
2172.16.12.3:6380> get k1
"testv1"
好了,主机上的数据从机也可以获取的到了
另一种主从结构
上面,我们搭建的主从结构是这样的
其实还有一种方式,可以搭建成下面这个样子的:
上图中这种主从搭建方式,只需要在上文环境的基础上,修改6381的master即可,让6381去复制6380的数据,命令如下:1
2172.16.12.3:6381> slaveof 172.16.12.3 6380
OK
执行完毕后,看一下6379的信息:1
2
3
4
5
6
7
8
9
10172.16.12.3:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.17.0.1,port=6380,state=online,offset=4033,lag=0
master_repl_offset:4033
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:4032
可以看到,他的角色依然是master,然后从机只有一个6380了
那再来看一下6380的信息,如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18172.16.12.3:6380> info replication
# Replication
role:slave
master_host:172.16.12.3
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:4131
slave_priority:100
slave_read_only:1
connected_slaves:1
slave0:ip=172.17.0.1,port=6381,state=online,offset=155,lag=1
master_repl_offset:155
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:154
此时,6380的角色是一个从机,但是他自己还有一个从机,就是6381.
至此,上面这种方式的主从就搭建成功了
注意点
- 当主机运行了一段时间并且已经存储了数据,这是从机连接上来的话,从机是会复制主机上面的所有数据,而不是从连接的那个时间点开始复制
- 配置了主从之后,默认情况下,主机可读可写,从机只读不可写,也可以通过修改redis.conf中
slave-read-only
的值让从机也可以执行写操作 - 在整个主从结构运行过程中,如果主机不幸挂掉,重启之后,他依然是主机,主从复制操作也能够继续进行
主从原理
每一个 Redis master 都有一个 replication ID :这是一个较大的伪随机字符串,标记了一个给定的数据集。每个 master 也持有一个偏移量,master 将自己产生的复制流发送给 slave 时,发送多少个字节的数据,自身的偏移量就会增加多少,目的是当有新的操作修改自己的数据集时,它可以以此更新 slave 的状态。复制偏移量即使在没有一个 slave 连接到 master 时,也会自增,所以基本上每一对给定的Replication ID, offset都会标识一个 master 数据集的确切版本。
当 slave 连接到 master 时,它们使用 PSYNC 命令来发送它们记录的旧的 master replication ID 和它们至今为止处理的偏移量。通过这种方式, master 能够仅发送 slave 所需的增量部分。但是如果 master 的缓冲区中没有足够的命令积压缓冲记录,或者如果 slave 引用了不再知道的历史记录(replication ID),则会转而进行一个全量重同步:在这种情况下, slave 会得到一个完整的数据集副本,从头开始
简单来说,就是:
- slave启动成功连接到master后发送一个sync命令
- Master接到命令后启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令
- 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
- 全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中
- 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
- 只要是重新连接master,一次完全同步(全量复制)将被自动执行