redis主从复制

主从复制原理

主实例,自己有一个复制id,并且记录一份offset偏移量
在这里插入图片描述

副本实例连接主实例的时候,来对比它的旧的master的复制id( old master replication ID),和他的复制偏移量 (相当于报告一下进度条)

  1. 如果主实例中,根据他的id和offset,能分辨出来你之前的进度,那么去看偏移量

能分辨出来有两种情况

  • 副本实例的old master replication ID等于主实例的replication ID

  • 主实例是原来由salve升级上来的主实例,记录了自己的replication ID和自己的的old master replication ID如果你的副本实例,记录的old master replication ID和主实例的old master replication ID一样也是可以分辨出来你的进度,这时候也去看偏移量offset

  1. 比较偏移量offset之后,认为你的偏移量差距不大,差的这些增量指令都在主实例的buffer缓冲区中,就可以进行增量复制

例如:

  • 你的offset落后太多了.比如你的offset 到50,主实例的offset到100,但是主实例的缓冲区,只有30,
  • 意思就是如果你的offset到70,我还能给你搞一下增量复制,但是你落后太多了,差的那些增量指令,我也没有都保存住,那么你就去走全量复制吧(就像下图 slave1只能全量复制,slave2可以走增量复制)
    在这里插入图片描述
    在这里插入图片描述

增量复制

增量复制很好理解,就直接把缓冲区中的aof指令,从副本的offset开始后面那些,全都同步给副本实例,副本实例拿着一致性,就跟上进度了,就跟主实例保持一致了

全量复制

全量复制就是从主实例上创建一个新的rdb快照,同时这个时候新的请求都写在缓冲区,rdb创建好之后,将rdb发给副本实例,副本实例加载完rdb快照以后,主实例再把缓冲区中数据都传给副本实例,全部完成之后,副本实例就完成了和主实例的同步

官方文档翻译

在Redis复制的基础上(不包括Redis Cluster或Redis Sentinel作为附加层提供的高可用性功能),使用和配置leader follower (master-slave)复制非常简单:它允许replica(副本) Redis instances成为master instances的完全复制体。每次连接断开时,replica instances将自动重新连接到master instances,并且无论master instances发生什么情况,replica都会试图成为master的一个的完全复制体。

  1. 当主实例和副本实例连接良好时,主服务器通过向副本发送命令流来保持副本的更新,以便复制由于以下原因而对主数据集产生的影响:客户端写入、密钥过期或收回、更改主数据集的任何其他操作。

  2. 当主服务器和副本之间的链接断开时,由于网络问题或由于在主服务器或副本中检测到超时,副本将重新连接并尝试继续进行部分重新同步:这意味着它将尝试只获取断开连接时丢失的部分命令流。

  3. 当无法进行部分重新同步时,复制副本将要求进行完全重新同步。这将涉及一个更复杂的过程,在这个过程中,主机需要创建其所有数据的快照,将其发送到副本,然后在数据集更改时继续发送命令流。

Redis默认采用异步复制,低延迟,高性能,是绝大多数Redis用例的自然复制模式。但是,Redis副本异步地确认它们与主服务器定期接收的数据量。因此主机不会每次都等待副本处理命令,但是如果需要,它知道哪个副本已经处理了哪个命令。这允许有可选的同步复制。

客户端可以使用WAIT命令请求某些数据的同步复制。但是WAIT只能保证其他Redis实例中有指定数量的确认副本,它并不能将一组Redis实例变成一个一致性强的CP系统:在故障转移过程中,根据Redis持久性的具体配置,确认的写操作仍然会丢失。但是,使用WAIT,在发生故障事件后丢失写操作的概率大大降低到某些难以触发的故障模式。

您可以查看Sentinel或Redis集群文档,了解有关高可用性和故障转移的更多信息。本文其余部分主要介绍Redis基本复制的基本特性。

以下是关于Redis复制的一些非常重要的事实:

  1. Redis采用异步复制,用异步复制来主控对处理的数据量的确认。
  2. 一个主服务器可以有多个副本。
  3. 副本能够接受来自其他副本的连接。除了将多个副本连接到同一个主副本之外,副本还可以以类似级联的结构连接到其他副本。从Redis 4.0开始,所有的子副本将从主服务器接收完全相同的复制流。
  4. Redis复制在主机端是非阻塞的。这意味着当一个或多个副本执行初始同步或部分重新同步时,主服务器将继续处理查询。
  5. 复制在副本方面也基本上是无阻塞的。当复制副本执行初始同步时,它可以使用旧版本的数据集处理查询,假设您在中配置了Redisredis.conf版。否则,您可以配置Redis副本,以便在复制流关闭时向客户端返回错误。但是,在初始同步之后,必须删除旧数据集并加载新数据集。复制副本将在这个短暂的窗口期间阻止传入的连接(对于非常大的数据集,这可能长达数秒)。Redis 4.0以后,可以配置Redis,以便在不同的线程中删除旧的数据集,但是加载新的初始数据集仍然会在主线程中发生并阻塞副本。
  6. 复制既可以用于可扩展性,也可以用于只读查询的多个副本(例如,可以将缓慢的O(N)操作卸载到副本中),也可以简单地用于提高数据安全性和高可用性。
  7. 可以使用复制来避免主机将完整数据集写入磁盘的成本:典型的技术是配置主机redis.conf版为了完全避免持久化到磁盘,请连接一个配置为不时保存或启用AOF的复制副本。但是,必须小心处理此设置,因为重新启动的主机将以空数据集开始:如果副本尝试与其同步,则副本也将被清空。

主机关闭持久性时的复制安全性

在使用Redis复制的设置中,强烈建议在主副本和副本中打开持久性。当实际情况不允许(例如由于磁盘非常慢导致的延迟问题)的时候,应配置为服务器重启后redis实例并不自动重启。

为了更好地理解为什么一个redis实例,不进行任何持久化操作,但是却会在服务器重启之后自动重启是非常危险的,看以下示例,即从主机及其所有副本中擦除数据:

我们有一个设置,节点a作为主节点,关闭持久化,节点B和C从节点a复制。

此时节点A崩溃,但是它有一些自动重启系统,可以重新启动进程。但是,由于关闭了持久化,重启后节点a数据全部清空

节点B和C将从节点A复制,节点A是空的,于是节点B和C为了跟A同步,也把自个清空了

当Redis Sentinel(哨兵)用于高可用性时,关闭主机上的持久性以及进程的自动重启是危险的。例如,主机可以足够快地重新启动,使Sentinel无法检测到故障,从而发生上述故障模式。

每当你的1. 数据安全很重要,2. 并且在没有持久化的情况下配置了主从复制的时候,就应该禁用实例的自动重新启动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值