DDIA第五章:复制
1. 章节介绍
本章围绕分布式数据系统中的复制展开,探讨了在多台机器上保留相同数据副本的相关技术与挑战。复制旨在提升系统可用性、降低延迟、扩展读取吞吐量,但核心难题在于处理复制数据的变更。文中介绍了单领导者、多领导者和无领导者三种主流变更复制算法,以及同步与异步复制、故障处理等关键问题,为分布式数据库设计与运维提供重要参考。
核心知识点 | 面试频率 |
---|---|
单领导者复制 | 高 |
多领导者复制 | 中 |
无领导者复制 | 中 |
同步与异步复制 | 高 |
复制延迟问题 | 高 |
冲突解决 | 中 |
故障切换 | 中 |
2. 知识点详解
2.1 领导者与追随者(单领导者复制)
- 角色划分:副本分为领导者(主库)和追随者(从库),客户端写入请求必须发送给领导者,领导者将数据变更通过复制日志同步给追随者。
- 读写规则:客户端读取可向领导者或追随者查询,但只有领导者接受写操作。
- 同步与异步复制:
- 同步复制:领导者等待追随者确认后再向客户端返回成功,保证数据一致性,但可能因追随者故障阻塞写入。
- 异步复制:领导者无需等待追随者响应,写入性能好,但可能因领导者故障丢失未同步数据。
- 故障处理:
- 从库失效:通过复制日志追赶恢复,从断开处继续获取数据变更。
- 主库失效:需进行故障切换,包括确认主库失效、选举新主库、重新配置系统,可能面临数据丢失、脑裂等问题。
2.2 复制日志的实现
- 基于语句的复制:记录执行的SQL语句并发送给从库,存在非确定性函数、自增列等问题。
- 传输预写式日志(WAL):复制底层磁盘块变更日志,与存储引擎耦合,版本兼容性差。
- 逻辑日志复制(基于行):记录行级别的插入、删除、更新信息,与存储引擎解耦,便于解析和版本兼容。
- 基于触发器的复制:通过触发器记录数据变更,灵活性高但开销大、易出错。
2.3 复制延迟问题
- 最终一致性:异步复制下,从库可能落后主库,导致暂时的数据不一致,最终会趋于一致。
- 相关一致性保证:
- 读己之写一致性:用户能看到自己提交的更新,可通过从主库读取、跟踪更新时间戳等实现。
- 单调读:用户多次读取不会看到数据回退,可固定从同一副本读取。
- 一致前缀读:保证读取到的写入顺序符合因果关系,避免因果颠倒。
2.4 多领导者复制
- 应用场景:多数据中心运维(提升性能、容忍数据中心停机和网络问题)、离线操作客户端、协同编辑。
- 处理写入冲突:
- 冲突检测:同步检测会失去多主优势,通常异步检测。
- 冲突避免:确保特定记录写入通过同一领导者。
- 冲突解决:包括最后写入胜利、按副本ID优先级、合并值、应用程序自定义逻辑等。
- 复制拓扑:有全部到全部、环形、星形等,全部到全部拓扑容错性较好,但可能出现写入顺序问题。
2.5 无主复制
- 写入与读取:客户端可向多个副本写入,读取时并行查询多个节点,通过版本号判断数据新鲜度。
- 数据同步机制:
- 读修复:客户端检测到陈旧数据时,将新值写回陈旧副本。
- 反熵过程:后台进程定期同步副本数据差异。
- 读写的法定人数:通过配置n(副本数)、w(写入成功所需副本数)、r(读取成功所需副本数),满足w + r > n时,大概率获取最新值,但存在边缘情况。
- 松散法定人数与带提示的接力:网络中断时,接受写入到可达节点,恢复后再转发,提升可用性但可能影响一致性。
- 并发写入检测:通过版本向量判断操作是否并发,并发写入需合并处理,如使用最后写入胜利、CRDT等方法。
3. 章节总结
本章详细介绍了分布式数据系统中复制的三种主要方式:单领导者复制、多领导者复制和无领导者复制。单领导者复制简单易实现,但存在单点写入瓶颈;多领导者复制适用于多数据中心等场景,需解决冲突问题;无领导者复制通过法定人数等机制提升可用性,也面临一致性挑战。同时,探讨了复制日志实现、复制延迟、故障处理等关键问题,以及相关的一致性保证和冲突解决策略,为分布式系统设计提供了全面的复制技术参考。
4. 知识点补充
4.1 相关知识点
- 一致性模型:除文中提到的最终一致性等,还有强一致性、顺序一致性等,强一致性要求所有节点同时看到相同的数据,顺序一致性保证操作按全局顺序执行。
- 分区与复制:分区(分片)将数据拆分到不同节点,复制是在多个节点保留相同数据,两者常结合使用,提升系统 scalability和可用性。
- 共识算法:如Paxos、Raft,用于在分布式系统中达成一致决策,可解决主库选举等问题,保证数据一致性。
- 数据中心网络:不同数据中心间网络延迟高、可靠性低,影响复制策略选择,多主复制和无主复制更能适应这种环境。
- 复制性能优化:包括批量复制、压缩传输、异步批量确认等,可减少复制开销,提升系统性能。
4.2 最佳实践
在多数据中心部署分布式数据库时,采用多领导者复制是较为合适的实践。每个数据中心内部使用主从复制,数据中心之间的主库相互同步数据。这样,本地写入可在本数据中心快速处理,减少跨数据中心网络延迟对用户体验的影响。同时,当某个数据中心发生故障时,其他数据中心可继续提供服务,提升系统可用性。
在配置时,需合理设置复制策略,对于关键业务数据,可采用半同步复制确保数据可靠性;对于非关键数据,可使用异步复制提升性能。另外,要做好冲突解决机制,由于不同数据中心可能同时修改相同数据,可采用基于业务逻辑的合并策略,如电商订单数据,若两个数据中心同时更新订单状态,可根据订单时间、操作类型等规则合并,确保数据最终一致。同时,定期监控各数据中心间的复制延迟和数据一致性,及时发现并解决问题,保证系统稳定运行。
4.3 编程思想指导
在设计涉及复制的分布式系统时,应秉持“权衡取舍”的编程思想。没有一种复制方案是完美的,需根据业务需求在一致性、可用性、性能之间找到平衡。例如,对于金融交易系统,数据一致性至关重要,应优先选择同步复制或强一致性的共识算法,即使牺牲部分性能;而对于社交网络的动态信息流,可采用最终一致性的异步复制,以换取更高的写入性能和可用性。
同时,要具备“容错设计”思维,充分考虑节点故障、网络中断等异常情况。在代码层面,实现完善的故障检测和自动恢复机制,如定期心跳检测节点状态,当发现故障时自动触发故障切换流程。对于数据复制,要做好日志记录和版本控制,确保在故障恢复时能准确追溯数据变更,避免数据丢失或不一致。
此外,应注重“简洁性”,避免过度设计。复制逻辑本身较为复杂,在实现时尽量采用成熟的算法和框架,减少自定义逻辑带来的风险。例如,使用开源的分布式数据库或复制工具,而非从零构建复制系统。同时,通过模块化设计将复制逻辑与业务逻辑分离,便于维护和扩展,当业务需求变化时,可灵活调整复制策略而不影响核心业务代码。
5. 程序员面试题
5.1 简单题
题目:什么是单领导者复制?其主要优缺点是什么?
答案:单领导者复制是指在复制系统中,指定一个副本作为领导者(主库),所有写入操作必须发送给领导者,领导者将数据变更同步给其他追随者(从库),读取操作可在领导者或追随者进行。优点是实现简单,数据一致性较易保证;缺点是领导者成为写入瓶颈,若领导者故障,需进行故障切换,可能导致服务中断或数据丢失。
5.2 中等难度题
题目:在异步复制中,如何实现读己之写一致性?
答案:可采用以下方法实现:一是读用户可能修改过的内容时从主库读取,例如用户个人信息,用户自己读取时从主库获取,读取他人信息时从从库获取;二是跟踪用户上次更新的时间戳,在上次更新后的一段时间内从主库读取,确保用户能看到自己的更新;三是客户端记住最近一次写入的版本号或日志序列号,读取时要求从库的版本不低于该版本,若当前从库版本不足,则从其他从库或主库读取。
题目:多领导者复制中可能出现写入冲突,简述几种解决冲突的方法。
答案:主要解决方法有:一是最后写入胜利,为每个写入分配唯一ID或时间戳,选择ID最大或时间最新的写入作为有效数据;二是按副本ID优先级,为每个副本分配唯一ID,ID高的副本的写入优先;三是合并值,将冲突的写入值按一定规则合并,如字符串拼接、集合求并等;四是应用程序自定义逻辑,在写入或读取时由应用程序根据业务需求处理冲突,如提示用户手动选择。
5.3 高难度题
题目:无主复制中,法定人数(w和r)的设置对系统有何影响?如何选择合适的w和r值?
答案:在无主复制中,w是写入成功所需的副本数,r是读取成功所需的副本数。当w + r > n(n为副本总数)时,读取操作大概率能获取最新值,一致性较好,但可用性降低,因为需要更多节点响应;当w + r ≤ n时,可用性提升,因为所需响应节点少,但可能读取到陈旧数据,一致性较差。
选择w和r时,需根据业务需求权衡。若追求强一致性,可设w和r为多数,如n=3时,w=2、r=2;若写入频繁且可容忍一定陈旧数据,可设w=1、r=n,提升写入性能;若读取频繁,可设r=1、w=n,提升读取性能。同时,需考虑节点故障情况,确保在部分节点不可用时,仍能满足w和r的要求,保证系统可用。
题目:比较单领导者复制、多领导者复制和无领导者复制在处理网络分区故障时的表现。
答案:单领导者复制在网络分区时,若领导者与部分追随者被分隔,未被分隔的追随者可能发起故障切换,导致脑裂,若分区恢复,可能出现数据冲突;若领导者所在分区无法与客户端通信,客户端无法写入,可用性降低。
多领导者复制在网络分区时,每个分区的领导者可独立接受写入,分区恢复后通过复制同步数据,可能产生冲突但可用性高,适合多数据中心场景,能容忍分区故障继续提供服务。
无领导者复制通过松散法定人数和带提示的接力,在网络分区时,客户端可向可达节点写入,分区恢复后同步数据,可用性较高,但可能因分区导致数据不一致,需依赖读修复和反熵过程恢复,一致性保证较弱。
本文围绕数据库复制展开,介绍了复制的概念、原因、算法及相关权衡。
- 复制概述:复制指在多台机器保留相同数据副本,原因包括减少延迟、提高可用性和读取吞吐量。难点在于处理数据变更,常见变更复制算法有单领导者、多领导者和无领导者三种。同时,复制时需权衡同步或异步复制、处理失败副本等问题。
- 基于领导者的复制:这是常见的复制模式,一个副本为领导者处理写入,其他为追随者。写入时,领导者将数据变更发送给追随者,追随者按顺序应用变更。读取可从领导者或追随者进行。复制可同步或异步,同步能保证数据一致但易致系统停滞,异步则可能丢失数据,但主库能持续处理写入。
- 设置与维护副本:设置新从库需获取主库一致性快照并复制,之后拉取后续变更。节点宕机时,从库失效可通过追赶恢复,主库失效则需故障切换,不过故障切换可能出现数据丢失、不一致及脑裂等问题。
- 复制日志实现:包括基于语句的复制,即主库记录并转发语句给从库,但因非确定性函数等问题存在局限;传输预写式日志,通过发送日志构建副本,但与存储引擎耦合;逻辑日志复制,以行粒度描述写入,与存储引擎分离,便于解析;基于触发器的复制,通过触发器实现,灵活性高但开销大。
- 复制延迟问题:异步复制虽可扩展只读请求服务容量,但可能导致从库数据过时,出现最终一致性。具体表现为读己之写、单调读和一致前缀读等问题,可通过从主库读特定数据、跟踪时间戳等方式解决。