redis集群—主从同步(复制)

栏目: 数据库 · 发布时间: 6年前

内容简介:在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave),如图所示。假设现在有两个Redis服务器,地址分别为127.0.0.1:6379和127.0.0.1:12345,如果我们向服务器127.0.0.1:12345发送以下命令:

Redis 中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave),如图所示。

redis集群—主从同步(复制)

假设现在有两个Redis服务器,地址分别为127.0.0.1:6379和127.0.0.1:12345,如果我们向服务器127.0.0.1:12345发送以下命令:

127.0.0.1:12345> SLAVEOF 127.0.0.1 6379

OK

(注:SLAVEOF,说明后面的地址是主服务器)

那么服务器127.0.0.1:12345将成为127.0.0.1:6379的从服务器,而服务器127.0.0.1:6379则会成为127.0.0.1:12345的主服务器。

(记得去http://redisdoc.com/topic/replication.html上将一些操作进行补充)

本文是按照《Redis设计与实现》一书所整理的,感觉原书讲的非常棒,所以下面的这部分的知识将按照原书的逻辑进行介绍:

先介绍旧版复制功能在处理断线后重新连接的从服务器时,会遇上怎样的低效情况。新版复制功能是如何通过部分重同步来解决旧版复制功能的低效问题的,并说明部分重同步的实现原理。

旧版复制功能的实现

Redis的复制功能分为 同步(sync)命令传播(command propagate) 两个操作 :

1、同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态;

2、命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。

同步

当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作 ,也即是,将从服务器的数据库状态更新至主服务器当前所处的数据库状态。

从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是 SYNC命令的执行步骤

1、 从服务器向主服务器发送SYNC 命令;

2、 收到SYNC命令的主服务器执行BGSAVE命令 ,在 后台生成一个RDB文件并使用一个缓冲区记录从现在开始执行的所有写命令;

3、当 主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件 ,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。

4、 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令 ,将自己的数据库状态更新至主服务器数据库当前所处的状态。

命令传播

在执行完同步操作之后,主从服务器之间数据库状态已经相同了 。但这个状态并非一成不变, 如果主服务器执行了写操作,那么主服务器的数据库状态就会修改 ,并导致主从服务器状态不再一致。

所以为了让主从服务器再次回到一致状态,主服务器需要对从服务器执行命令传播操作 :主服务器会将自己执行的写命令,也即是造成主从服务器不一致的那条写命令,发送给从服务器执行,当从服务器执行了相同的写命令之后,主从服务器将再次回到一致状态。

旧版复制功能的缺陷

在Redis中, 从服务器对主服务器的复制可以分为以下两种情况:

1、初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同;

2、断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连接重新连上了主服务器,并继续复制主服务器。

对于初次复制来说,旧版复制功能能够很好地完成任务,但对于 断线后重复制来说,旧版复制功能虽然也能让主从服务器重新回到一致状态,但效率却非常低。

我们给出一个例子进行说明:

从服务器终于重新连接上主服务器,因为这时主从服务器的状态已经不再一致,所以从服务器将向主服务器发送SYNC命令,而主服务器会将包含键k1至键k10089的RDB文件发送给从服务器,从服务器通过接收和载入这个RDB文件来将自己的数据库更新至主服务器数据库当前所处的状态。

上面给出的例子可能有一点理想化,因为在主从服务器断线期间,主服务器执行的写命令可能会有成百上千个之多,而不仅仅是两三个写命令。但 总的来说,主从服务器断开的时间越短,主服务器在断线期间执行的写命令就越少,而执行少量写命令所产生的数据量通常比整个数据库的数据量要少得多, 在这种情况下,为了让从服务器补足一小部分缺失的数据,却要让主从服务器重新执行一次SYNC命令 ,这种做法无疑是非常低效的。

SYNC命令是一个 非常耗费资源 的操作

SYNC命令是非常消耗资源的,因为每次执行SYNC命令,主从服务器需要执行一下操作:

1、 主服务器需要执行BGSAVE命令来生成RDB文件 ,这个生成操作会 耗费主服务器大量的CPU、内存和磁盘I/O资源;

2、 主服务器需要将自己生成的RDB文件发送给从服务器 ,这个发送操作会 耗费主从服务器大量的网络资源 (带宽和流量),并对主服务器响应命令请求的时间产生影响;

3、 接收到RDB文件的从服务器需要载入主服务器发来的RDB文件 ,并且在 载入期间,从服务器会因为阻塞而没办法处理命令请求

SYNC是一个如此消耗资源的命令,所以Redis最好在真需要的时候才需要执行SYNC命令。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

A Philosophy of Software Design

A Philosophy of Software Design

John Ousterhout / Yaknyam Press / 2018-4-6 / GBP 14.21

This book addresses the topic of software design: how to decompose complex software systems into modules (such as classes and methods) that can be implemented relatively independently. The book first ......一起来看看 《A Philosophy of Software Design》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具