第九章:Redis replication 主从复制-阿里云开发者社区

开发者社区> 数据库> 正文

第九章:Redis replication 主从复制

简介: 什么是主从复制 一个master可以有多个slave 一个slave只能有一个master 数据流是单向的,master到slave 全量复制和部分复制 run id 查看复制偏移量(用来比对两边数据同步问题,相差不能太大) 插一个命令redis-cli -p 6379 info server | grep run查看redis运行id image.png 查看复制偏移量 image.png 全量复制 在Redis复制的基础上,使用和配置主从复制非常简单,它允许从属Redis服务器成为主服务器的精确副本。

什么是主从复制

  1. 一个master可以有多个slave
  2. 一个slave只能有一个master
  3. 数据流是单向的,master到slave

全量复制和部分复制

run id 查看复制偏移量(用来比对两边数据同步问题,相差不能太大)
  1. 插一个命令redis-cli -p 6379 info server | grep run查看redis运行id
    img_6fa55ec3cf9b38745c6a6a0003092fef.png
    image.png
  2. 查看复制偏移量


    img_d05762efe594b1fdac52c785c50465d3.png
    image.png
全量复制

在Redis复制的基础上,使用和配置主从复制非常简单,它允许从属Redis服务器成为主服务器的精确副本。每次链路断开时,从设备将自动重新连接到主设备,无论主设备发生什么情况,都将试图成为主设备的精确副本。

这个系统使用三个主要机制:

  1. 当主和从实例连接良好时,主设备通过发送命令流来保持从设备更新,以便复制对主数据集中发生的数据集的影响:客户机写入,密钥过期或被驱逐等等。
  2. 当主站和从站之间的链路断开时,对于网络问题或者由于在主站或从站中感测到超时,从站重新连接并尝试进行部分重新同步:这意味着它将尝试只获取部分在断开连接时错过的命令流。
  3. 当部分重新同步不可能时,从机将要求完全重新同步。这将涉及一个更复杂的过程,在这个过程中,主机需要创建所有数据的快照,将数据发送给从机,然后在数据集更改时继续发送命令流。

Redis默认使用异步复制,这是高延迟和高性能,是绝大多数Redis用例的自然复制模式。 但是,Redis从站会异步确认主站定期收到的数据量。

某些数据的同步复制可以由客户端使用WAIT命令来请求。 但WAIT只能确保在其他Redis实例中具有指定数量的已确认副本:在故障转移期间出于不同原因的故障转移期间,确认写入仍可能丢失,或取决于Redis持久性的确切配置。 您可以检查Sentinel或Redis群集文档以获取有关高可用性和故障转移的更多信息。 本文的其余部分主要描述了Redis基本复制的基本特征。

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

  • Redis使用异步复制,异步从到主机确认处理的数据量。

  • 主人可以有多个奴隶。

  • 从站能够接受来自其他从站的连接。除了将多个从站连接到同一个主站之外,从站也可以以层叠状结构连接到其他从站。自从Redis 4.0以来,所有的子从服务器都会收到与主服务器完全相同的复制流。

  • Redis复制在主端是非阻塞的。这意味着当一个或多个从机执行初始同步或部分重新同步时,主机将继续处理查询。

  • 复制在很大程度上也是非阻塞的。从服务器执行初始同步时,它可以使用旧版本的数据集处理查询,假定您在redis.conf中配置了Redis。否则,如果复制流已关闭,则可以将Redis从属程序配置为向客户端返回错误。但是,在初始同步之后,必须删除旧数据集,并且必须加载新数据集。从站将在这个简短的窗口中阻塞传入的连接(对于非常大的数据集可能只有很多秒)。自Redis 4.0以来,可以配置Redis,以便旧数据集的删除发生在不同的线程中,但是加载新的初始数据集仍然会在主线程中发生并阻止从属。

  • 复制既可用于可伸缩性,也可用于只读查询的多个从站(例如,可将低速O(N)操作卸载到从站),或者仅用于数据安全。

  • 可以使用复制来避免让主服务器将完整数据集写入磁盘的成本:一种典型的技术包括配置主服务器redis.conf以避免永久保存到磁盘,然后连接配置为不时保存的从服务器或启用AOF。然而,这个设置必须小心处理,因为重新启动的主设备将从一个空数据集开始:如果从设备尝试与其同步,则从设备也将被清空。

当master宕机的复制安全

在使用Redis复制的设置中,强烈建议在主服务器和从服务器中启用持久性。如果这种情况不可行,例如由于磁盘速度非常慢导致的延迟问题,则应配置实例以避免重新启动后自动重新启动。

为了更好地理解关闭配置为自动重启的主设备是否危险的原因,请检查以下故障模式,其中数据从主设备及其所有从设备擦除:

  1. 我们有一个设置,节点A作为主节点,持久性关闭,节点B和C从节点A复制。
  2. 节点A崩溃,但它有一些自动重新启动系统,重新启动过程。但是由于持久性被关闭,节点将重新启动一个空的数据集。
  3. 节点B和C将从节点A复制,节点A是空的,所以它们将有效地销毁它们的数据副本。
    当Redis Sentinel用于高可用性时,关闭主服务器上的持久性以及进程的自动重启也是危险的。例如,主机可以很快重启,Sentinel不会检测到故障,以便发生上述故障模式。

每次数据安全很重要,复制与配置为无持久性的主站一起使用时,应禁用实例的自动重启。

当Redis Sentinel用于高可用性时,关闭主服务器上的持久性以及进程的自动重启也是危险的。 例如,主机可以很快重启,Sentinel不会检测到故障,以便发生上述故障模式。

每次数据安全很重要,复制与配置为无持久性的主站一起使用时,应禁用实例的自动重启。

Redis复制如何工作

每个Redis master都有一个复制ID:它是一个大的伪随机字符串,标记数据集的给定故事。 每个主设备也会获得一个偏移量,该设置为生成的每个复制流字节增加以发送到从设备,以便使用修改数据集的新更改更新从设备的状态。 即使没有从机连接,复制偏移量也会增加,所以基本上每一对给定的:
识别主数据集的确切版本。

当从站连接到主站时,它们使用PSYNC命令来发送它们的旧主站复制ID以及到目前为止处理的偏移量。这样主人可以发送所需的增量部分。但是,如果主缓冲区中没有足够的积压,或者从服务器引用了不再知道的历史记录(复制标识),则会发生完全重新同步:在这种情况下,从服务器将获得数据集的完整副本, 从头开始​​。

这是完全同步如何更详细地工作:

  • 主人开始一个后台保存过程,以生成一个RDB文件。同时开始缓冲从客户端收到的所有新的写入命令。当后台保存完成后,主服务器将数据库文件传输给从服务器,将其保存到磁盘上,然后将其加载到内存中。主机会将所有缓冲的命令发送给从机。这是作为命令流完成的,并且与Redis协议本身的格式相同。

  • 你可以通过telnet自己尝试一下。在服务器正在做一些工作的同时连接到Redis端口并发出SYNC命令。您将看到一个批量传输,然后主机接收到的每个命令都将在远程登录会话中重新发出。实际上,SYNC是一个旧的协议,不再由较新的Redis实例使用,但仍然存在向后兼容性:它不允许部分重新同步,所以现在使用PSYNC。

  • 如前所述,当主从链路出于某种原因关闭时,从站能够自动重新连接。如果主站收到多个并发的从站同步请求,它将执行一次后台保存,以便为它们提供全部服务。

无盘复制

通常情况下,完全重新同步需要在磁盘上创建一个RDB文件,然后从磁盘重新加载相同的RDB,以便向从属设备提供数据。

对于较慢的磁盘,对于主设备来说这可能是一个非常紧张的操作。 Redis 2.8.18版是第一个支持无盘复制的版本。 在此设置中,子进程直接通过线将RDB发送到从服务器,而不使用磁盘作为中间存储。

全量复制开销

  • bgsave时间
  • RDB文件网络传输时间
  • 从节点清空数据时间
  • 从节点加载RDB时间
  • 可能的AOF重写时间

部分复制

连接断开时,master会写一个复制缓冲区的命令,slave再连接master时候会把自己的偏量值offset和runid告诉master,如果丢失数据在buffer缓存的一个范围内,则master把缓冲区队列的数据给slave。然后再把部分数据同步给slave

复制的配置

slaveof命令
  1. 复制命令
slaveof 127.0.0.1 6380

丢弃旧数据集,转而开始对新主服务器进行同步。

  1. 取消复制
slaveof no one

将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。

配置

主要修改4个参数:

  1. port;
  2. logfile;
  3. slaveof;
  4. pidfile;
  5. daemonize(是否在后台执行)
然后再添加配置
slaveof ip port
slave-read-only yes #设置只读
两种方式比较
方式 命令 配置
优点 无需重启 统一配置
缺点 不便于管理 需要重启
实战
  1. 我配置了一个端口为6379,和端口为6380的服务,并在后台启动
#6379配置
port 6379
pidfile /var/run/redis_6379.pid
# slaveof <masterip> <masterport>
logfile "6379.log"
daemonize yes


#6380配置
port 6380
pidfile /var/run/redis_6380.pid
slaveof 127.0.0.1 6379
masterauth xxxxx    #如果master有密码,则需要设置
logfile "6380.log"
daemonize yes
  1. img_26f889830aad31ef9b1b0ff00ba51cb3.png
    对6379执行命令 info replication

    img_767081550aef7d1f54b655cc108b82b3.png
    对6380执行命令 info replication
  2. 然后我在主机上set一个东西,在slave上获取


    img_7f05ab29cf4314266c33ade8428ea443.png
    image.png
  3. 同步数据

在master的cli中执行slaveof 127.0.0.1 6380

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章