kv存储主从复制的设计与实现 📅 2026/7/25 15:26:28 一、主从复制的作用kv存储是一款内存数据库一旦网络宕机数据直接中断存在数据丢失的风险。主从复制功能就是用于解决发生单机故障时数据易丢失的问题。配合Sentinel 或 Cluster使用时单机发生故障可以实现自动切换从节点可被自动提升为主节点继续提供服务。主从复制的优点如下1主节点Master数据实时复制到从节点Replica形成多副本避免单点故障导致数据丢失。2主节点处理写请求从节点分担读请求显著提升系统的读吞吐能力。3配合 Sentinel 或 Cluster当主节点故障时从节点可被提升为新的主节点继续提供服务。主从复制默认是异步的这意味着主节点在执行完写命令后立即返回客户端结果无需等待从节点确认这保证了主节点的高性能。虽然存在极短的主从数据不一致窗口但通过WAIT命令可以请求同步复制来降低数据丢失风险只是降低无法成为一个强一致性的系统。二、两种核心同步机制全量与增量当从节点与主节点建立连接或同步中断后重连时同步方式由复制偏移量Replication Offset和复制 IDReplication ID共同决定。1、全量同步触发条件从节点首次连接或请求的偏移量已不在主节点的复制积压缓冲区Replication Backlog内又或主从的复制 ID 不匹配。执行流程基于状态机设计生成 RDB 快照主节点 fork 子进程执行bgsave生成当前数据的 RDB 快照文件。期间所有新写命令被暂存到输出缓冲区。传输 RDB 文件RDB 生成后发送给从节点。主节点会复用同一次 RDB 生成来服务多个同时请求的从节点避免资源浪费。加载与对齐从节点清空旧数据加载 RDB。主节点持续缓存新写命令待从节点加载完成后通过REPLCONF ACK通知主节点主节点再发送缓存命令完成数据对齐。2. 增量同步触发条件从节点因网络抖动短暂断线重连且主节点仍保留其断线期间的命令复制偏移量和 复制 ID均在主节点中能对上。实现原理复制积压缓冲区主节点维护一个固定长度的环形缓冲区存储最近传播的写命令及其偏移量。断点续传从节点重连后发送PSYNC携带主节点运行IDRun ID和已处理的复制偏移量。主节点判断若 Run ID 匹配且偏移量仍在积压缓冲区内主节点返回CONTINUE从该偏移量起发送增量命令避免全量 RDB 传输。三、关键状态机复制与同步kv存储引擎通过状态机严格管理复制流程。从节点的核心状态变迁如下主节点192.168.137.13:9096 从节点192.168.137.14:9096 配置主从关系redis-cli -h 192.168.137.14 -p 9096 REPLICAOF 192.168.137.13 9096初始化从节点存储主节点地址状态REPL_STATE_NONE变为REPL_STATE_CONNECT。连接建立定时任务触发连接成功后状态变为REPL_STATE_CONNECTING。主从握手从节点发送PING、AUTH认证并告知自身端口及能力状态推进至REPL_STATE_SEND_HANDSHAKE等。同步请求发送PSYNC状态转为REPL_STATE_TRANSFER准备接收 RDB。在线同步RDB 加载完成状态进入REPL_STATE_CONNECTED转为长连接命令流同步。从节点状态状态常量含义所处阶段REDIS_REPL_NONE初始状态没有进行任何复制。初始化REDIS_REPL_CONNECT需要连接主节点。执行replicaof命令后进入此状态等待周期任务触发连接。初始化REDIS_REPL_CONNECTING正在与主节点建立TCP连接。建立连接REDIS_REPL_RECEIVE_PONG连接建立后等待主节点回复PONG这是握手的第一步。主从握手REDIS_REPL_TRANSFER正在接收主节点发来的RDB文件全量同步数据。复制类型判断与执行REDIS_REPL_CONNECTED同步完成已与主节点保持连接正在接收实时的增量命令。复制类型判断与执行主节点状态状态常量含义主节点动作REDIS_REPL_WAIT_BGSAVE_START准备为从节点生成RDB文件但正在等待后台保存任务开始。可能等待其他bgsave任务完成。REDIS_REPL_WAIT_BGSAVE_ENDRDB文件正在后台生成中。主节点执行bgsave在此期间继续累积写命令。REDIS_REPL_SEND_BULKRDB文件已生成正在通过网络发送给从节点。主节点发送RDB文件。REDIS_REPL_ONLINERDB文件传输完成进入命令传播阶段持续发送增量写命令。主节点持续将新写命令发送给从节点。四、主从命令传播全量同步完成后主从节点的数据库处于一致状态。然而主节点每时每刻都可能收到新的写命令这会让主从数据再次变得不一致。为了维持一致命令传播机制会像一个单向的管道将主节点上执行的、会改变数据的命令持续不断地发送给所有已连接的从节点。从节点接收到这些命令后只需照单全收并在本地重放执行就能让自身数据库状态再次跟上主节点的步伐。命令传播能高效运行主要依靠两个关键设计1、复制积压缓冲区Replication Backlog增量同步的基石为了应对从节点可能发生的短暂断线Redis 在命令传播的同时会将所有写命令也写入一个由主节点维护的 复制积压缓冲区Replication Backlog 中。工作原理这个缓冲区是一个固定长度的队列deque其大小可在配置文件中调整默认1MB。当从节点断线重连后它会向主节点报告自己已经执行的复制偏移量Offset。决策过程主节点会检查从节点报告的偏移量之后的数据是否仍然存在自己的积压缓冲区中。如果在主节点就会进行增量同步只发送断线期间缺失的那部分命令效率极高。如果不在则意味着断线时间过长增量同步已不可能只能退回全量同步。2、心跳检测与命令丢失发现保证主从连接的可靠性在长期运行的系统中网络抖动可能导致命令在传输途中丢失但连接并未断开。为此Redis 引入了心跳检测机制。在命令传播阶段从节点会以每秒一次的频率向主节点发送一个包含自身当前复制偏移量的REPLCONF ACK offset命令。这个心跳主要有两个作用检测连接状态主节点如果长时间收不到从节点的心跳就能感知到连接异常。发现命令丢失主节点收到心跳后会对比心跳中的偏移量和自己本地的偏移量。如果发现从节点的偏移量比自己的小就说明从节点丢失了一些已传播的命令。此时主节点会主动从积压缓冲区中找到这些缺失的命令并重新发送给从节点从而保证了数据的最终一致性。KV存储引擎主从复制是在内存容量、网络带宽与数据一致性之间做出的精妙权衡。它利用RDB 快照应对大规模全量同步又借助复制积压缓冲区化解偶发断线重连。复制 ID 与偏移量的组合精准定义了数据版本。主从同步是高可用设计的基本环节更能为构建稳定可靠的分布式系统提供宝贵的思路。推荐一个零声教育学习教程个人觉得老师讲得不错分享给大家[LinuxNginxZeroMQMySQLRedisfastdfsMongoDBZK流媒体CDNP2PK8SDockerTCP/IP协程DPDK等技术内容点击立即学习:链接