Redis主从复制机制详解

原创做者,公众号【程序员读书】,欢迎关注公众号,转载文章请注明出处哦。程序员

在上一篇文章中,咱们了解了Redis两种不一样的持久化方式,Redis服务器经过持久化,把Redis内存中持久化到硬盘当中,当Redis宕机时,咱们重启Redis服务器时,能够由RDB文件或AOF文件恢复内存中的数据。redis

不过持久化后的数据仍然只在一台机器上,所以当硬件发生故障时,好比主板或CPU坏了,这时候没法重启服务器,有什么办法能够保证服务器发生故障时数据的安全性?或者能够快速恢复数据呢?想作到这一点,咱们须要再了解Redis另一种机制:主从复制安全

什么是主从复制

Redis的主从复制机制是指可让从服务器(slave)能精确复制主服务器(master)的数据,以下图所示:bash

上面的图表示的是一台master服务器与slave服务器的状况,其实一台master服务器也能够对应多台slave服务器,以下图所示:服务器

另外,slave服务器也能够有本身的slave服务器,这样的服务器称为sub-slave,而这些sub-slave经过主从复制最终数据也能与master保持一致,以下图所示:异步

主从复制的方式和工做原理

Redis的主从复制是异步复制,异步分为两个方面,一个是master服务器在将数据同步到slave时是异步的,所以master服务器在这里仍然能够接收其余请求,一个是slave在接收同步数据也是异步的。ui

复制方式

Redis主从复制分为如下三种方式:spa

1、当master服务器与slave服务器正常链接时,master服务器会发送数据命令流给slave服务器,将自身数据的改变复制到slave服务器。3d

2、当由于各类缘由master服务器与slave服务器断开后,slave服务器在从新连上master服务器时会尝试从新获取断开后未同步的数据即部分同步,或者称为部分复制。code

3、若是没法部分同步(好比初次同步),则会请求进行全量同步,这时master服务器会将本身的rdb文件发送给slave服务器进行数据同步,并记录同步期间的其余写入,再发送给slave服务器,以达到彻底同步的目的,这种方式称为全量复制。

工做原理

master服务器会记录一个replicationId的伪随机字符串,用于标识当前的数据集版本,还会记录一个当数据集的偏移量offset,无论master是否有配置slave服务器,replication Id和offset会一直记录并成对存在,咱们能够经过如下命令查看replication Id和offset:

> info repliaction
复制代码

经过redis-cli在master或slave服务器执行该命令会打印相似如下信息(不一样服务器数据不一样,打印信息不一样):

connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=9472,lag=1
master_replid:2cbd65f847c0acd608c69f93010dcaa6dd551cee
master_repl_offset:9472
复制代码

当master与slave正常链接时,slave使用PSYNC命令向master发送本身记录的旧master的replication id和offset,而master会计算与slave之间的数据偏移量,并将缓冲区中的偏移数量同步到slave,此时master和slave的数据一致。

而若是slave引用的replication太旧了,master与slave之间的数据差别太大,则master与slave之间会使用全量复制的进行数据同步。

配置主从复制

Redis的主从配置很是简单,咱们可使用两种方式来配置主从服务器,在这时咱们先假设Redismaster服务器地址为192.168.0.101

客户端发送同步命令

# 向客户端
saveof 192.168.1.101 6379
复制代码

slave服务器配置主服务器

在这里slave服务器的redis.conf经过saveof选项,能够指定master服务器,以下:

slaveof 192.168.1.101 6379
复制代码

经过上面两种方式的配置,master服务器与slave服务器便已经能够开始进行数据同步了。

master要求验证

上面配置的是master服务器没有设置密码的状况,若是master设置了密码,则能够在链接到slave服务器redis-cli执行下面的命令:

# <password>指代实际的密码
config set masterauth <password>
复制代码

或者在slave服务器的redis.conf中配置下面的选项:

# <password>指代实际的密码
masterauth <password>
复制代码

避免slave被清空

slave会被清空?slave不用同步了master的数据吗?备份的数据怎么会清空了呢?

当master服务器关闭了持久化时,若是发生故障后自动重启时,由本地没有保存持久化的数据,重启的Redis内存数据为空,而slave会自动同步master的数据,这时候,slave服务器的数据也会被清空。

如何避免slave被清空呢?

若是条件容许(通常均可以的),master服务器仍是要开启持久化,这样master故障重启时,能够快速恢复数据,而同步这台master的slave数据也不会被清空。

若是master不能开启持久化,则不该该设置让master发生故障后重启(有些机器会配置自动重启),而是将某个slave服务器升级为master服务器,对外继续提供服务。

slave默认为只读的

Redis2.6之后,slave只读模式是默认开启的,咱们能够经过配置文件中的slave-read-only选项配置是否开启只读模式:

# 默认是yes
slave-read-only yes/no 
复制代码

或者在客户端中经过config set命令设置是否开启只读模式:

config set slave-read-only no
复制代码

上面将slave服务器设置为能够写入,可是要注意,若是slave也配置了本身的从服务器(sub-slave),那么sub-slave只会同步从master服务器同步到slave的数据,而并会同步咱们直接写入slave服务器的数据。

主从复制中的key过时问题

咱们都知道Redis能够经过设置key的过时时间来限制key的生存时间,Redis处理key过时有惰性删除和按期删除两种机制,而在配置主从复制后,slave服务器就没有权限处理过时的key,这样的话,对于在master上过时的key,在slave服务器就可能被读取,因此master会累积过时的key,积累必定的量以后,发送del命令到slave,删除slave上的key。

若是slave服务器升级为master服务器 ,则它将开始独立地计算key过时时间,而不须要经过master服务器的帮助。

主从复制的做用

保存Redis数据副本

当咱们只是经过RDBAOFRedis的内存数据持久化毕竟只是在本地,并不能保证绝对的安全,而经过将数据同步slave服务器上,能够保留多一个数据备份,更好地保证数据的安全。

读写分离

在配置了主从复制以后,若是master服务器的读写压力太大,能够进行读写分离,客户端向master服务器写入数据,在读数据时,则访问slave服务器,从而减轻master服务器的访问压力。

高可用性与故障转移

服务器的高可用性是指服务器能提供7*24小时不间断的服务,Redis能够经过Sentinel系统管理多个Redis服务器,当master服务器发生故障时,Sentineal系统会根据必定的规则将某台slave服务器升级为master服务器,继续提供服务,实现故障转移,保证Redis服务不间断。

小结

Redis的主从复制可让咱们把Redis中的数据同步到其余服务器上,为数据安全提供更加安全的保障,也可让咱们的服务器在发生故障时而没法重启时,能够更加快速地切换服务器,继续对外提供服务。


你的关注,是我写做路上最大的鼓励!

相关文章
相关标签/搜索