数据库KV存储后端【免费下载链接】pikaPikiwidb is a Redis-Compatible database developed by Qihoos infrastructure team.项目地址https://gitcode.com/gh_mirrors/pi/pika点击查看免费下载PikiwidbPika通过 master/slave 主从复制实现数据的水平扩展与高可用其同步体系分为基于 rsync 的全量同步和基于 Binlog 的增量同步两条路径。本文以 docs/design/sync.md 为核心脉络结合 include/pika_rm.h、include/pika_define.h、include/pika_slave_node.h、src/pika_rsync_service.cc 等源码与 conf/pika.conf 配置项逐层拆解 Pika 从节点如何建立同步关系、主节点如何分发数据、增量同步如何通过滑动窗口限速帮助读者理解并调优主从复制全过程。一、同步体系总览全量同步与增量同步的分工Pika 的主从复制由从节点的slaveof命令触发配置文件中也可通过 slaveof 参数在启动时自动指定主节点。整体流程分为两个阶段全量同步DB Sync当从节点与主节点之间没有共同的历史同步点时主节点将整个 DB 文件 dump 后通过 rsync 传输给从节点从节点用收到的文件整体替换本地数据。增量同步Binlog Sync全量同步完成后主从双方基于 Binlog 偏移量BinlogOffset持续对齐主节点把新写入的命令实时推送给从节点。两种模式的触发条件与端口约定如下Pika 同步依赖 BinlogBinlog 文件会被自动或手动删除。当从节点请求的同步点对应的 Binlog 文件已不存在时无法增量续传必须退回全量同步。设计文档描述全量同步默认使用pika port 1000作为 rsync 传输端口增量同步默认使用pika port 2000端口。从源码常量可以印证端口设计include/pika_define.h 中定义了kPortShiftRSync 1000、kPortShiftReplServer 2000、kPortShiftRsync2 10001src/pika_server.cc 中分别以port kPortShiftRSync启动PikaRsyncService、以port kPortShiftRsync2启动rsync::RsyncServer从节点则以port kPortShiftReplServer连接主节点的增量复制服务。需要注意conf/pika.conf 中的端口注释port10001 用于 Rsync、port1000 用于增量复制与设计文档表述存在差异实际端口偏移以源码常量为准。二、全量同步基于 rsync 的 DB 文件传输1. 触发背景Pika Replicate 的基本流程Pika 的主从复制以PartitionDB为最小同步单位整个建立过程为从节点处理slaveof命令将自身状态切换为 slave并改变连接状态从节点向主节点发送MetaSync 请求在真正开始同步之前确保自身 DB 的拓扑结构与主节点一致从节点的每一个 Partition 单独向主节点对应的 Partition 发起trysync 请求逐个建立同步关系。从节点的复制状态在源码中对应ReplState枚举include/pika_define.h其状态机比设计文档列出的更细包括kNoConnect、kTryConnect、kTryDBSync、kWaitDBSync、kWaitReply、kConnected、kError、kDBNoConnect八个状态。2. 实现逻辑六步完成全量同步设计文档给出的全量同步实现流程如下Pika 实例启动的同时启动 Rsync 服务主节点发现某个 Partition 需要全量同步时先判断是否有可用的备份文件如果没有则先 dump 一份主节点通过 rsync 向从节点发送对应 Partition 的 dump 文件从节点的对应 Partition 用收到的文件替换自己的 DB从节点的对应 Partition 用最新的偏移量再次发起 trysync完成同步。rsync 的 daemon 模式由 PikaRsyncService 封装构造函数确定 rsync 工作目录db_sync_path下的子目录与 pid 文件路径StartRsync()调用pstd::StartRsync以0.0.0.0监听认证口令与masterauth保持一致未设置时使用默认值kDefaultRsyncAuth随后创建权限为 600 的rsync.secret密钥文件最后通过 pid 文件确认 rsync 进程已存活src/pika_rsync_service.cc。相关常量kDBSyncModule document、kDBSyncMaxGap 50定义在 include/pika_define.h。3. 从节点连接状态机设计文档用六个高层状态描述从节点与主节点建立同步的推进过程No Connect不尝试成为任何其他节点的 slaveShouldMetaSync向 master 请求 DB 的拓扑信息确保与自身一致TryConnect为每个 Partition 重置状态机使其处于准备同步的状态Connecting在所有 Partition 建立同步关系之前一直处于 connecting 状态EstablishSucces所有 Partition 建立同步关系成功Error出现异常。在源码层面SlaveNodeinclude/pika_slave_node.h维护SlaveStatekSlaveNotSync/kSlaveDbSync/kSlaveBinlogSync与BinlogSyncStatekNotSync/kReadFromCache/kReadFromFile分别刻画“DB 全量同步是否完成”与“Binlog 从缓存还是从文件读取”全量同步完成后即进入kSlaveBinlogSync的增量同步阶段。三、增量同步基于 Binlog 的持续对齐1. Binlog 的存储结构Pika 的主从同步完全依赖 Binlog一主多从结构中主节点给多个 slave 复用同一个 Binlog只是每个 slave 拥有各自的偏移量。主节点每执行完一条写命令就把命令追加到 Binlog同步模块读出 Binlog 发送给从节点从节点收到后执行并追加到自己的 Binlog。由于主从偏移量一致发生网络或节点故障需要重连时从节点只需将自己当前的 Binlog 偏移量发给主节点主节点从该偏移量起继续推送即可。如果简单地把命令一条条顺序追加容错性很差——文件里写错一个字节就可能导致整个文件不可用。因此 Pika 采用类似 LevelDB log 的分块记录格式存储 Binlog。相关常量见 include/pika_define.hRecordTypekFullType、kFirstType、kMiddleType、kLastType、kEof等记录类型用于将一条大记录跨块拆分kHeaderSize 1 3 4 8字节头部由 Type1 字节 length3 字节 time4 字节组成kBlockSize 64KB读写块的默认大小kBinlogPrefix write2fileBinlog 文件名前缀。具体实现位于 src/pika_binlog.cc 与 include/pika_binlog.hBinlog类内部持有Version维护pro_num_、pro_offset_、logic_id_、term_Put()负责写入EmitPhysicalRecord()负责按块切分记录。Binlog 文件默认大小由构造函数参数决定100MBinclude/pika_binlog.h与配置项 binlog-file-size 的默认值 100M 一致。偏移量本身由BinlogOffsetfilenumoffset物理偏移与LogicOffsettermindex逻辑偏移共同组成LogOffsetinclude/pika_define.h从节点上报、主节点下发的都是这种复合偏移。2. 增量同步的交互过程设计文档将增量同步的报文交互归纳为三步从库发送BinlogSyncRequest报文报文中说明自己已经收到的 BinlogOffset主库收到 BinlogSyncRequest 后从同步点开始发出一批BinlogSyncResponse从库收到 BinlogSyncResponse 后先写入本地 Binlog再继续执行步骤 1。该循环由主节点的“发送窗口 从节点 ACK”机制驱动从节点写入本地 Binlog 后回送 ack主节点根据 ack 推进发送位置从而形成流水线式的持续同步。四、同步模块ReplicaManagerRM的两层结构Pika 的同步由ReplicaManagerRM模块统一负责对应 include/pika_rm.h 中的PikaReplicaManager类。RM 内部是两层结构逻辑层负责同步逻辑如状态机推进、窗口维护、binlog 读取调度传输层负责连接管理、数据解析与传输。传输层又分为两个子模块ReplicationClientPikaReplClientinclude/pika_repl_client.h发起连接的建立从节点侧使用ReplicationServerPikaReplServerinclude/pika_repl_server.h响应报文主节点侧使用。每两个实例之间的所有 Partition 复用一条连接避免为每个 Partition 建立独立 TCP 连接带来的开销。数据同步的最小单位是 Partition。每个 Pika 实例会同时维护两类对象include/pika_rm.hMasterPartitionSyncMasterDB记录跟随自己的 slave 同步信息包括 slave 的同步状态与当前的sessionId通过SlaveNode的 session 机制防重连串扰逻辑层据此向各 slave 推送同步数据SlavePartitionSyncSlaveDB记录主节点的信息RmNode中的 ip、port、db_name、sessionId逻辑层按需向 master 发送同步请求。逻辑层维护两个核心数据结构MasterPartitions记录每个跟随自己的 SlaveNode 信息与SlavePartitions记录主节点信息分别以sync_master_dbs_与sync_slave_dbs_两个哈希表存储include/pika_rm.h。五、同步过程窗口机制与背压控制1. MasterPartition 同步事件主节点侧逻辑层处理 MasterPartition 的同步事件向对应的从节点同步数据过程为读取 MasterPartition 的 Binlog 信息后将BinlogOffsetInfo记录到对应 SlaveNode 自己的 window 中将 Binlog 暂存到临时的待发送队列辅助线程Auxiliary thread定时将临时待发送队列中的数据通过 RM 传输层发送给对应的 slave 节点收到 slave 的 BinlogSyncResponse即 ack后得知 slave 已收到的 BinlogOffset更新 SlaveNode 的 window然后重复步骤 1 继续同步。window滑动窗口的核心作用是控制每个 SlaveNode 的同步速度避免少数同步慢的从节点占用过多资源。其数据结构与逻辑在 include/pika_slave_node.h 的SyncWindow与 src/pika_slave_node.cc 中实现每个待确认的 Binlog 条目对应一个SyncWinItem记录offset_、binlog_size_、acked_SyncWindow内部用双端队列win_保存未确认条目Update()根据从节点回传的 start/end 偏移将区间内的条目标记为acked_并顺带推进acked_offset队列剩余容量 sync_window_size - win_.size()容量不足即暂停发送从而形成背压。举例说明沿用设计文档场景Pika 收到 BinlogOffset 为 100 到 200 的 ack response 后从 window 中移除 BinlogOffset 位于 100200 的元素继续发送 BinlogOffset 为 1100 和 1200 的 binlog同时把这两个新偏移加入 window。窗口内未确认的条目越多发送越保守从而自动适配慢从节点。窗口上限由配置项 sync-window-size 控制默认 9000表示窗口内最多容纳的待确认 Binlog 条目数在网络延迟高的场景下适当调大可提升同步吞吐。此外 include/pika_rm.h 定义了批量发送参数kBinlogSendPacketNum 40、kBinlogSendBatchNum 100以及发送/接收保活超时kSendKeepAliveTimeout2s与kRecvKeepAliveTimeout20s。2. SlavePartition 同步事件从节点侧逻辑层处理 SlavePartition 的同步事件收到 master 发送的同步数据后向 master 发送相应的 response过程为按照解析出的 Partition 信息将 binlog 写入任务分配到对应的线程处理对应配置 sync-binlog-thread-num默认 1建议与databases数量一致最终取值为Min(sync-binlog-thread-num, databases)保证每个 DB 有独立线程写 Binlog线程写入 Binlog 之后调用传输层发送 BinlogSyncResponseack根据 Binlog 中的 key 分配给对应的线程处理写入 DB 任务对应配置 sync-thread-num默认 6建议与主节点thread-pool-size接近。从源码看主从之间的这些报文交互分别由 src/pika_repl_client.ccSendTrySyncRequest、SendDBSyncRequest、SendMetaSyncRequest、SendBinlogSyncAckRequest等与 src/pika_repl_server.ccSendSlaveBinlogChipsRequest等完成任务调度则通过PikaReplicaManager的ProduceWriteQueue/ConsumeWriteQueue与ScheduleWriteBinlogTask/ScheduleWriteDBTask接口include/pika_rm.h落地。六、全量同步相关配置速查以下配置项与主从同步直接相关均可在 conf/pika.conf 中找到配置项默认值说明port9221监听端口端口偏移1000 / 2000 / 10001服务于不同同步通道slaveof空格式master-ip:master-port启动后自动对主节点执行 SLAVEOFmasterauth空主节点认证口令必须与主节点requirepass一致同时作为 rsync 认证口令db-sync-path./dbsync/全量同步时 rsync 的工作目录db-sync-speed-1全量同步最大传输速度默认 -1约 1024MB/sthrottle-bytes-per-second200MB/s由从节点控制的全量复制 rsync 限速可config set动态调整rsync-timeout-ms1000全量同步阶段 rsync 超时过小会引起不必要重试max-rsync-parallel-num4rsync 并行通道数合法范围 [1, 4]非法值自动重置为 4sync-window-size9000增量同步窗口大小未确认条目上限高延迟场景调大可提效sync-thread-num6从节点写 DB 的线程数sync-binlog-thread-num1从节点写 Binlog 的线程数建议等于databasesbinlog-file-size100MBinlog 文件滚动大小七、总结与延伸阅读Pika 的同步设计可以概括为一句话以 Partition 为最小同步单位、以 Binlog 偏移为对齐基准、以 rsync 兜底全量、以滑动窗口限速增量。主节点侧通过SyncMasterDBSlaveNodeSyncWindow实现可控的多从推送从节点侧通过SyncSlaveDB 多线程写 Binlog/写 DB 实现并行落地而PikaReplicaManager把逻辑层与传输层ReplicationClient / ReplicationServer统一调度起来。想深入验证文中的机制可以继续阅读同步模块核心include/pika_rm.h、src/pika_rm.cc窗口与从节点状态include/pika_slave_node.h、src/pika_slave_node.ccBinlog 存储格式include/pika_binlog.h、src/pika_binlog.ccrsync 服务封装include/pika_rsync_service.h、src/pika_rsync_service.cc复制状态机与端口常量include/pika_define.h主从复制完整配置conf/pika.conf双主复制模式docs/ops/dualMaster.md、docs/ops/dualMaster_en.md同步设计英文版docs/design/sync_en.md赞分享数据库KV存储后端【免费下载链接】pikaPikiwidb is a Redis-Compatible database developed by Qihoos infrastructure team.项目地址https://gitcode.com/gh_mirrors/pi/pika点击查看免费下载相关推荐Apache Kvrocks 复制机制深度解析从全量同步到增量同步Apache Kvrocks 复制机制深度解析从全量同步到增量同步 概述 Apache Kvrocks 是一个基于 RocksDB 的高性能键值存储系统其复Airbyte Fauna Source 连接器深度解析全量同步、增量同步与删除事件的 FQL 实现原理Airbyte Fauna Source 连接器深度解析全量同步、增量同步与删除事件的 FQL 实现原理 本指南以 airbyte integrations/数据工程数据集成ETL后端大数据ARIS skills-codex-claude-review 覆盖层实战用 Codex 执行、Claude Code 审稿的跨模型研究评审管线ARIS skills codex claude review 覆盖层实战用 Codex 执行、Claude Code 审稿的跨模型研究评审管线 导读 本篇文AI 技能/插件AI 评测科研人工智能MCP 服务dsh-plugin上一篇VoyagerXSS防护措施防止跨站脚本攻击的方法下一篇purejs-onepage-scroll与移动端触摸滑动实现原理详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考