我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis | 第11章 服务器的复制《Redis设计与实现》

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis | 第11章 服务器的复制《Redis设计与实现》

Redis | 第11章 服务器的复制《Redis设计与实现》

目录
  • 前言
  • 1. 旧版复制功能的实现
    • 1.1 同步与命令传播
    • 1.2 旧版复制功能的缺陷
  • 2. 新版复制功能的实现
    • 2.1 部分重同步的实现原理
  • 3. PSYNC 命令的实现
  • 4. 复制的详细步骤
    • 4.1 设置主服务器的地址和端口
    • 4.2 建立套接字连接
    • 4.3 发送 PING 命令
    • 4.4 身份验证
    • 4.5 发送端口信息
    • 4.6 同步
    • 4.7 命令传播
  • 5. 心跳检测
  • 最后

前言

参考资料:《Redis设计与实现 第二版》;

第四部分为多机数据库的实现,主要由以下模块组成:复制Sentinel集群

本篇将介绍 Redis 的复制功能。在 Redis 中,用户可以通过执行 SLAVEOF 命令或者设置 salveof 选项,让一个从服务器复制主服务器。

与本章相关的 Redis 命令总结在下篇文章,欢迎点击收藏,本篇将不再重复:

《Redis常用命令及示例总结(API)》:https://www.cnblogs.com/dlhjw/p/15639773.html


1. 旧版复制功能的实现

  • 旧版指 Redis 2.8 以前版本;
  • 旧版 Redis 的复制功能分为同步(sync)和命令传播(command propagate)两个操作:
    • 同步操作:将从服务器的数据库状态更新至主服务器当前所处的数据库状态;
    • 命令传播:用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器重新回到一致状态;

1.1 同步与命令传播

  • 同步:客户端向从服务器发送 SLAVEOF 命令,从服务器执行以下步骤:
    • 1)从服务器向主服务器发送 SYNC 命令;
    • 2)收到 SYNC 命令的主服务器执行 BGSAVE 命令,在后台生成 RDB 文件,并使用一个缓冲区记录此刻开始执行的所有写命令;
    • 3)当主服务器完成 BGSAVE 命令时,将 RDB 文件发给从服务器,从服务器接收并载入 RDB 文件,将数据库状态更新至主服务器执行 BGSAVE 命令时的数据库状态;
    • 4)主服务器将记录在缓冲区里的所有写命令发送给从服务器,从服务器执行写命令,将数据库状态更新至主服务器数据库当前的状态;

同步通信示例

  • 命令传播:同步操作完成后,主服务器会将自己执行的写命令,发送给从服务器。从服务器执行后,主从服务器数据库状态再次回到一致状态;

1.2 旧版复制功能的缺陷

  • 处于命令传播阶段的主从服务器因为网络问题中断了复制,重连后从服务器会向主服务器发送 SYNC 命令执行同步操作;

旧版复制功能的缺陷

  • SYNC 命令非常消耗资源:
    • 主服务器执行 BGSAVE 命令时:耗费主服务器大量 CPU、内存与磁盘 IO 资源;
    • 主服务器将 RDB 文件发给从服务器时:耗费主从服务器大量网络资源(流量和带宽),并对主服务器响应命令请求的时间产生影响;
    • 从服务器在载入 RDB 文件期间:从服务器阻塞无法处理命令请求;

2. 新版复制功能的实现

  • 新版指 Redis 2.8 以后版本;
  • 新版 Redis 的复制功能分为完全重同步(full resynchronization)和部分重同步(partial resynchronization)两个操作:
    • 完全重同步:与初次复制情况相同;
    • 部分重同步:主服务器仅将主从服务器在断线期间的写命令发给从服务器。使用 PSYNC 命令;

新版复制功能的实现

2.1 部分重同步的实现原理

  • 部分重同步依赖以下三个部分:
    • 主从服务器的复制偏移量(replication offset);
    • 主服务器的复制积压缓冲区(replication backlog);
    • 主服务器的运行 ID(run ID);
  • 复制偏移量
    • 执行复制的主从服务器双方会分别维护一个复制偏移量;
    • 主服务器每次向从服务器传播 N 个字节数据时,将自己的复制偏移量加 N;
    • 从服务器每次收到主服务器传播来的 N 字节数据时,将自己的复制偏移量加 N;
    • 通过对比主从服务器的复制偏移量可以判断其数据库状态是否一致;

复制偏移量示例

  • 复制积压缓冲区
    • 复制积压缓冲区由主服务器维护一个固定长度(fixed-size)先进先出(FIFO)队列,默认大小 1MB;
    • 当主服务器进行命令传播时,会将命令发给从服务器,同时将写命令入队到复制积压缓冲区;
    • 重连时,从服务器将自己的复制偏移量 offset 发给主服务器:
      • offset+1 的内容在复制积压缓冲区内,主服务器对从服务器执行部分同步操作;
      • 反之,执行完整重同步操作;
  • 复制积压缓冲区的大小可以根据公式估算:second * write_size_per_second
    • second 为从服务器断线后重连所需平均时间;
    • write_size_per_second 为主服务器平均每秒产生的写命令数据量;
    • 为安全起见,可将复制积压缓冲区大小设置为:上述公式乘 2;

复制积压缓冲区

  • 服务器运行 ID
    • 每个 Redis 都有自己的运行 ID;
    • 运行 ID 在服务器启动时自动生成,由 40 个随机的十六进制字符组成;
    • 从服务器对主服务器进行初次复制时,主服务器会将自己的运行 ID 传送给从服务器,从服务器将这个 ID 保存;
    • 重连时,从服务器向主服务器发送保存的运行 ID:
      • 若从服务器保存的 ID 为当前主服务器运行 ID,根据偏移量判断重同步方式;
      • 反之,执行完整重同步操作;

3. PSYNC 命令的实现

  • PSYNC 命令的调用方法有两种:
    • 从服务器没有复制过任何主服务器,或之前执行过 SLAVEOF NO ONE 命令,那么从服务器在开始复制时向主服务器发送 PSYNC ? -1 命令,主动请求主服务器进行完整重同步;
    • 反之,从服务器发送 PSYNC master_run_id offset 命令,master_run_id 为上一次复制时的主服务器的运行 ID,offset 为从服务器当前的复制偏移量;
  • 主服务器接受 PSYNC 命令后会产生三种回复:
    • 完整重同步:返回 +FULLRESYNC master_run_id offset,master_run_id 为当前主服务器的运行 ID,offset 为主服务器当前的复制偏移量;
    • 部分重同步:返回 +CONTINUE,从服务器只需要等待主服务器发送自己缺少的部分数据;
    • 错误:返回 -ERR,主服务器版本低于 Redis 2.8,从服务器发送 SYNC 命令,与主服务器执行完整同步操作;

PSYNC 命令的执行情况


4. 复制的详细步骤

  • 该步骤为 Redis 2.8 版本以上
  • 客户端向从服务器发送 SLAVEOF ip port 命令;

4.1 设置主服务器的地址和端口

  • 从服务器将 SLAVEOF ip port 命令的 ip 地址和 port 端口保存到服务器状态里:

    struct redisServer{
        //...
        //主服务器的地址
        char *masterhost;
        //主服务器的端口
        int masterport;
    };
    
  • 从服务器向客户端返回 OK,然后开始复制;

4.2 建立套接字连接

  • 从服务器根据 masterhostmasterport 创建连向主服务器的套接字连接;
  • 套接字连接(connect)成功后,从服务器为该套接字关联一个文件事务处理器,专门用来处理复制工作;
  • 主服务器接受(accept)从服务器的套接字连接后,为该套接字创建响应客户端状态,并将从服务器视作客户端(client);
  • 此时,从服务器具备服务器(server)和客户端(client)双重身份;

建立套接字连接

4.3 发送 PING 命令

  • 从服务器成为主服务器的客户端后,向主服务器发送 PING 命令;
  • PING 命令的作用:
    • 检查套接字的读写状态是否正常;
    • 检查主服务器能否正常处理命令请求;
  • 主服务器对 PING 命令的回复有 3 种情况:
    • 返回命令回复:但从服务器不能在有限时间内读取命令内容,表示主从服务器间网络连接状态不佳。此时从服务器会断开并重新创建连向主服务器的套接字;
    • 返回错误:表示主服务器暂时没法处理从服务器的命令请求。此时从服务器会断开并重新创建连向主服务器的套接字;
    • 返回 PONG:表示网络连接正常,从服务器可以继续执行复制工作;

发送 PING 命令的几种情况

4.4 身份验证

  • 从服务器收到 PONG 回复后,根据是否设置 masterauth 选项决定是否进行身份验证;

    • 从服务器没有设置 masterauth 选项,不进行身份验证;
    • 从服务器设置了 masterauth 选项,需要进行身份验证;
  • 在需要进行身份验证的情况下,从服务器给主服务器发送 AUTH password 命令,命令的参数 password 为从服务器 masterauth 选项的值;

  • 从服务器在进行身份验证时根据:主服务器的 requirepass 选项和从服务器的 masterauth 选项不同,可能遇到以下情况:

    主服务器的 requirepass 选项 从服务器的 masterauth 选项 情况
    设置 设置 相同则继续复制,不同则返回 invalid password 错误
    设置 没有设置 返回 NOAUTH 错误
    没有设置 设置 返回 no password is set 错误
    没有设置 没有设置 继续复制工作

身份验证的各种情况

4.5 发送端口信息

  • 身份验证完成后,从服务器执行 REPLCONF listening-port port-number 命令,向主服务器发送自己的监听端口号 port-number

  • 主服务器接受后,存储在从服务器的客户端状态 slave_listening_port 属性中:

    typedef struct redisClient{
        //...
        // 从服务器的监听端口号
        int slave_listening_port;
    } redisClient;
    

4.6 同步

  • 从服务器向主服务器发送 PSYNC 命令,执行同步操作,将自己的数据库更新至主服务器数据库当前所处的状态;
  • 在同步操作执行完后,主服务器会成为从服务器的客户端,理由如下:
    • 完整重同步情况:需要将缓冲区里的写命令发送给从服务器;
    • 部分重同步情况:需要将复制积压缓冲区里的写命令发送给从服务器;

同步操作下主从服务器互为对方的客户端

4.7 命令传播

  • 完成同步后,主服务器进入命令传播阶段,一直将写命令发给从服务器;

5. 心跳检测

  • 在命令传播阶段,从服务器默认每秒向主服务器发送命令 REPLCONF ACK replication_offsetreplication_offset 参数是从服务器当前的复制偏移量;
  • 心跳检测的三个作用:
    • 检测主从服务器的网络连接状态:使用 INFO replication 命令可以查看从服务器最后一次向主服务器发送 REPLCONF ACK 命令距离现在过了多久,一般在 0~1 秒为正常;
    • 辅助 min-slaves 配置选项:当从服务器数量 x 少于 min-slaves-to-write 属性值或 x 个服务器的延迟大于等于 min-slaves-max-lag 属性值时,主服务器拒绝写命令;
    • 检测命令丢失:当主服务器发现从服务器的 replication_offset 参数与自己的不一致时,补发写命令数据;
  • 补发命令数据与部分重同步的区别在于:前者没有断线,后再断线了;
  • Redis 2.8 版本以前没有补发命令数据功能;


最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis | 第11章 服务器的复制《Redis设计与实现》

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis | 第11章 服务器的复制《Redis设计与实现》

目录前言1. 旧版复制功能的实现1.1 同步与命令传播1.2 旧版复制功能的缺陷2. 新版复制功能的实现2.1 部分重同步的实现原理3. PSYNC 命令的实现4. 复制的详细步骤4.1 设置主服务器的地址和端口4.2 建立套接字连接4.3 发送 PING 命
Redis | 第11章 服务器的复制《Redis设计与实现》
2020-11-24

Redis | 第7章 Redis 服务器《Redis设计与实现》

目录前言1. 命令请求的执行过程1.1 发送命令请求1.2 读取命令请求1.3 命令执行器(1):查找命令实现1.4 命令执行器(2):执行预备操作1.5 命令执行器(3):调用命令的实现函数1.6 命令执行器(4):执行后续工作1.7 将命令回复发送给客户端
Redis | 第7章 Redis 服务器《Redis设计与实现》
2022-04-27

Redis | 第3章 对象《Redis设计与实现》

目录前言1. Redis对象概述1.1 对象的定义2. 字符串对象3. 列表对象3.1 quicklist 快速链表4. 哈希对象5. 集合对象6. 有序集合对象7. Redis对象的特点7.1 类型检查与命令多态7.2 内存回收7.3 对象共享7.4 对象的
Redis | 第3章 对象《Redis设计与实现》
2016-10-04

Redis | 第4章 Redis中的数据库《Redis设计与实现》

目录前言1. Redis中的数据库2. 数据库的键空间3. 键的生成时间与过期时间4. Redis中的过期键删除策略5. AOF、RDB和复制功能对过期键的处理5.1 生成 RDB 文件5.2 载入 RDB 文件5.3 AOF 文件写入5.4 AOF 重写5.
Redis | 第4章 Redis中的数据库《Redis设计与实现》
2020-04-14

Redis | 第8章 发布订阅与事务《Redis设计与实现》

目录前言《Redis常用命令及示例总结(API)》:https://www.cnblogs.com/dlhjw/p/15639773.html1. 发布订阅1.1 频道的订阅与退订1.2 模式的订阅与退订1.3 发送消息1.4 查看订阅消息2. 事务2.1 事
Redis | 第8章 发布订阅与事务《Redis设计与实现》
2016-06-20

Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》

目录前言1. RDB 持久化1.1 RDB 文件的创建与载入1.2 自动间隔性保存1.2.1 设置保存条件1.2.2 dirty 计数器和 lastsave 属性1.2.3 检查保存条件是否满足1.3 RDB 文件1.3.1 RDB 的文件结构1.3.2 da
Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》
2018-11-05

Redis | 第6章 事件与客户端《Redis设计与实现》

目录前言1. 事件1.1 文件事件1.1.1 I/O 多路复用程序的实现1.1.2 事件类型与 API1.1.3 文件事件的处理器1.2 时间事件1.2.1 API1.2.2 serverCron 函数1.3 事件的调度与执行2. 客户端2.1 客户端属性2.
Redis | 第6章 事件与客户端《Redis设计与实现》
2014-08-19

Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

目录前言1. Lua 脚本1.1 Redis 创建并修改 Lua 环境的步骤1.2 Lua 环境协作组件1.3 EVAL 命令的实现1.4 EVALSHA 命令的实现1.5 脚本管理命令的实现1.6 脚本复制1.6.1 EVAL、SCRIPT FLUSH、SC
Redis | 第9章 Lua 脚本与排序《Redis设计与实现》
2017-01-01

Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》

目录前言1. 启动并初始化 Sentinel2. Sentinel 与服务器间的默认通信2.1 获取主服务器信息2.2 获取从服务器信息2.3 向主服务器和从服务器发送信息3. 接受来自主服务器和从服务器的频道信息3.1 更新 Sentinel 字典3.2 创
Redis | 第12章 Sentinel 哨兵模式《Redis设计与实现》
2017-09-21

Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》

目录前言1. 二进制位数组1.1 位数组的表示1.2 GETBIT 命令的实现1.3 SETBIT 命令的实现1.4 BITECOUNT 命令的实现1.5 BITOP 命令的实现2. 慢查询日志2.1 慢查询记录的保存2.2 慢查询日志的阅览与删除2.3 添加
Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》
2019-06-28

Redis设计与实现2.1:主从复制

主从复制这是《Redis设计与实现》系列的文章,系列导航:Redis设计与实现笔记SLAVEOF新旧复制功能旧版复制功能旧版复制功能的实现为 同步 和 命令传播:当刚连上Master时,要做一次全同步:sequenceDiagramparticipant Sl
Redis设计与实现2.1:主从复制
2021-05-11

阿里云服务器复制实现高效的数据备份与恢复

随着云计算的快速发展,阿里云服务器复制已经成为了企业数据保护和容灾的重要手段。本文将详细介绍如何使用阿里云服务器复制实现高效的数据备份与恢复,以及如何选择最适合的复制策略。阿里云服务器复制是一种通过镜像技术,实现从一台服务器的系统文件、数据等全部复制到另一台服务器上的数据迁移方式。在实际操作中,通常通过阿里云的复
阿里云服务器复制实现高效的数据备份与恢复
2023-11-17

iOS远程控制阿里云ECS实现移动设备与服务器的深度集成

随着移动互联网的普及,越来越多的企业和个人开始使用阿里云ECS服务。然而,如何在移动端设备上实现对阿里云ECS服务器的远程控制,成为了许多用户关心的问题。本文将详细介绍如何使用iOS设备远程控制阿里云ECS服务器。正文:概述在iOS设备上实现对阿里云ECS服务器的远程控制,主要有两种方法:使用iOS原生应用进行远
iOS远程控制阿里云ECS实现移动设备与服务器的深度集成
2023-11-12

基于微信小程序的网上购物平台小程序的设计与实现 服务器端口php+mysql(附源码 调试 文档)

基于微信小程序的网上购物平台小程序 一、引言二、国内外研究现状三、系统需求分析四、系统设计五、系统实现六、系统测试与评估七、结论八、界面展示九、源码获取 摘要 本文介绍了一种基于微信小程序的网上购物平台小程序,该系统主要分为两
基于微信小程序的网上购物平台小程序的设计与实现 服务器端口php+mysql(附源码 调试 文档)
2023-12-22

编程热搜

目录