博客参考:散尽浮华的Redis主从复制下的工做原理梳理html
此做者写的很是好,此处只作挪用,方便本身查看。redis
Redis主从复制的配置十分简单,它可使从服务器是主服务器的彻底拷贝。须要清除Redis主从复制的几点重要内容:数据库
1
2
3
4
5
6
7
8
9
10
11
|
1)Redis使用异步复制。但从Redis 2.8开始,从服务器会周期性的应答从复制流中处理的数据量。
2)一个主服务器能够有多个从服务器。
3)从服务器也能够接受其余从服务器的链接。除了多个从服务器链接到一个主服务器以外,多个从服务器也能够链接到一个从服务器上,造成一个
图状结构。
4)Redis主从复制不阻塞主服务器端。也就是说当若干个从服务器在进行初始同步时,主服务器仍然能够处理请求。
5)主从复制也不阻塞从服务器端。当从服务器进行初始同步时,它使用旧版本的数据来应对查询请求,假设你在redis.conf配置文件是这么配置的。
不然的话,你能够配置当复制流关闭时让从服务器给客户端返回一个错误。可是,当初始同步完成后,须要删除旧的数据集和加载新的数据集,在
这个短暂的时间内,从服务器会阻塞链接进来的请求。
6)主从复制能够用来加强扩展性,使用多个从服务器来处理只读的请求(好比,繁重的排序操做能够放到从服务器去作),也能够简单的用来作数据冗余。
7)使用主从复制能够为主服务器免除把数据写入磁盘的消耗:在主服务器的redis.conf文件中配置“避免保存”(注释掉全部“保存“命令),而后链接一个配
置为“进行保存”的从服务器便可。可是这个配置要确保主服务器不会自动重启(要得到更多信息请阅读下一段)
|
当主服务器不进行持久化时复制的安全性
1
2
3
4
5
6
7
8
9
10
11
12
|
在进行主从复制设置时,强烈建议在主服务器上开启持久化,当不能这么作时,好比考虑到延迟的问题,应该将实例配置为避免自动重启。
为何不持久化的主服务器自动重启很是危险呢?
为了更好的理解这个问题,看下面这个失败的例子,其中主服务器和从服务器中数据库都被删除了。
设置节点A为主服务器,关闭持久化,节点B和C从节点A复制数据。
这时出现了一个崩溃,但Redis具备自动重启系统,重启了进程,由于关闭了持久化,节点重启后只有一个空的数据集。
节点B和C从节点A进行复制,如今节点A是空的,因此节点B和C上的复制数据也会被删除。
当在高可用系统中使用Redis Sentinel,关闭了主服务器的持久化,而且容许自动重启,这种状况是很危险的。
好比主服务器可能在很短的时间就完成了重启,以致于Sentinel都没法检测到此次失败,那么上面说的这种失败的状况就发生了。
若是数据比较重要,而且在使用主从复制时关闭了主服务器持久化功能的场景中,都应该禁止实例自动重启。
|
Redis主从复制是如何工做的
1
2
3
4
5
6
7
8
9
10
11
12
|
若是设置了一个从服务器,在链接时它发送了一个SYNC命令,无论它是第一次链接仍是再次链接都没有关系。
而后主服务器开始后台存储,而且开始缓存新链接进来的修改数据的命令。当后台存储完成后,主服务器把数据文件发送到从服务器,
从服务器将其保存在磁盘上,而后加载到内存中。而后主服务器把刚才缓存的命令发送到从服务器。这是做为命令流来完成的,而且
和Redis协议自己格式相同。
你能够经过telnet本身尝试一下。在Redis服务器工做时链接到Redis端口,发送SYNC命令,会看到一个批量的传输,而且主服务器接收
的每个命令都会经过telnet会话从新发送一遍。
当主从服务器之间的链接因为某些缘由断开时,从服务器能够自动进行重链接。当有多个从服务器同时请求同步时,主服务器只进行一个后台存储。
当链接断开又从新连上以后,通常都会进行一个完整的从新同步,可是从Redis2.8开始,只从新同步一部分也能够。
|
部分从新同步
1
2
3
4
5
6
7
8
9
10
|
从Redis 2.8开始,若是遭遇链接断开,从新链接以后能够从中断处继续进行复制,而没必要从新同步。
它的工做原理是这样:
主服务器端为复制流维护一个内存缓冲区(
in
-memory backlog)。主从服务器都维护一个复制偏移量(replication offset)和master run
id
,
当链接断开时,从服务器会从新链接上主服务器,而后请求继续复制,假如主从服务器的两个master run
id
相同,而且指定的偏移量在内存缓冲
区中还有效,复制就会从上次中断的点开始继续。若是其中一个条件不知足,就会进行彻底从新同步(在2.8版本以前就是直接进行彻底从新同步)。
由于主运行
id
不保存在磁盘中,若是从服务器重启了的话就只能进行彻底同步了。
部分从新同步这个新特性内部使用PSYNC命令,旧的实现中使用SYNC命令。Redis2.8版本能够检测出它所链接的服务器是否支持PSYNC命令,不支持的
话使用SYNC命令。
|
无磁盘复制
1
2
3
4
|
一般来说,一个彻底从新同步须要在磁盘上建立一个RDB文件,而后加载这个文件以便为从服务器发送数据。
若是使用比较低速的磁盘,这种操做会给主服务器带来较大的压力。Redis从2.8.18版本开始尝试支持无磁盘的复制。
使用这种设置时,子进程直接将RDB经过网络发送给从服务器,不使用磁盘做为中间存储。
|
配置
1
2
3
4
5
6
7
8
9
10
|
主从复制的配置十分简单:把下面这行加入到从服务器的配置文件中便可。
slaveof 192.168.1.1 6379
固然你须要把其中的192.168.1.1 6379替换为你本身的主服务器IP(或者主机名
hostname
)和端口。另外你能够调用SLAVEOF命令,
主服务器就会开始与从服务器同步。
关于部分从新同步,还有一些针对复制内存缓冲区的优化参数。查看Redis介质中的Redis.conf示例得到更多信息。
使用repl-diskless-
sync
配置参数来启动无磁盘复制。使用repl-diskless-
sync
-delay 参数来配置传输开始的延迟时间,以便等待
更多的从服务器链接上来。查看Redis介质中的Redis.conf示例得到更多信息。
|
只读从服务器
1
2
3
4
5
6
7
8
|
从Redis 2.6开始,从服务器支持只读模式,而且是默认模式。这个行为是由Redis.conf文件中的slave-
read
-only 参数控制的,
能够在运行中经过CONFIG SET来启用或者禁用。
只读的从服务器会拒绝全部写命令,因此对从服务器不会有误写操做。但这不表示能够把从服务器实例暴露在危险的网络环境下,
由于像DEBUG或者CONFIG这样的管理命令仍是能够运行的。不过你能够经过使用rename-
command
命令来为这些命令更名来增长安全性。
你可能想知道为何只读限制还能够被还原,使得从服务器还能够进行写操做。虽然当主从服务器进行从新同步或者从服务器重启后,
这些写操做都会失效,仍是有一些使用场景会想从服务器中写入临时数据的,但未来这个特性可能会被去掉。
|
限制有N个以上从服务器才容许写入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
从Redis 2.8版本开始,能够配置主服务器链接N个以上从服务器才容许对主服务器进行写操做。可是,由于Redis使用的是异步主从复制,
没办法确保从服务器确实收到了要写入的数据,因此仍是有必定的数据丢失的可能性。
这一特性的工做原理以下:
1)从服务器每秒钟
ping
一次主服务器,确认处理的复制流数量。
2)主服务器记住每一个从服务器最近一次
ping
的时间。
3)用户能够配置最少要有N个服务器有小于M秒的确认延迟。
4)若是有N个以上从服务器,而且确认延迟小于M秒,主服务器接受写操做。
还能够把这看作是CAP原则(一致性,可用性,分区容错性)不严格的一致性实现,虽然不能百分百确保一致性,但至少保证了丢失的数据不会超过M秒内的数据量。
若是条件不知足,主服务器会拒绝写操做并返回一个错误。
1)min-slaves-to-write(最小从服务器数)
2)min-slaves-max-lag(从服务器最大确认延迟)
|