同步复制 -> 强一致性, 弱可用性 一旦某个从节点宕机则写失败
解决方案:一个从节点同步复制,其他异步复制,一旦同步节点宕机提升一个异步节点为同步节点
新强一致性复制算法: chain replication
异步复制 -> 强可用性,弱一致性
增加从节点:
挑战:主节点数据仍在写入,直接复制会导致数据不一致
方案:
复制数据时锁主节点不允许写 ,太粗暴
更好的方案分3步:
从节点宕机恢复:
从宕机前复制日志位置开始追赶
主节点宕机 -> FAILOVER 机制
比较复杂,一般需要3步:
复制日志实现:
复制延时的问题:
最终一致性: 以较弱的一致性换取读的可扩展性
一致性多弱取决于复制延时和读取策略
read-your-own-write-consistency (read-after-write consistency): 确保自己写入的数据一定会被随后的读请求读到
实现方式:
如果用户只修改自身的数据并知道自身数据的ID, 自身数据从主节点读,其他数据从随机节点读
如果用户可以修改许多其他的数据,需要客户端记录 key -> last modify time. 在一定时间范围内只从主节点读, 否则从随机节点读. 或者客户端把 key+last modify time 发给查询节点, 查询节点比较时间戳,等待赶上再返回结果或者将读请求
多数据中心: 路由读请求到同一数据中心
monotonic read: 确保第二次读结果不会比第一次旧
实现方式:
对同一主键每次读从同一副本(可能出现数据倾斜)
通过分布式事务解决复制延时问题.
支持多点写入
每个LEADER对于另一个LEADER是FOLLOWER
主要应用场景是多数据中心
每个数据中心有一个LEADER, 数据从LEADER复制到本数据中心的FOLLOWER和另一个数据中心的LEADER.
性能:写请求可由LOCAL 数据中心的LEADER处理. 不用跨广域网
数据中心容错: 一个数据中心宕机后另一个数据中心仍可独立运行,数据中心恢复后再将数据复制过去
网络容错:跨广域网异步复制,暂时网络不稳定不会影响写入
缺点:必须解决写冲突
设计时必须考虑自增主键冲突. TRIGGER, 数据完整性约束等
写冲突检测和解决
解决冲突的时机:
写时:一旦冲突发生,只能后台解决无法让用户干预 (Bucardo)
读时: 保存冲突数据,在下次读的时候自动解决或提示用户(CouchDB)
事务中的每个写冲突会单独解决,无法保持事务边界
自动冲突解决:
Conflict free replicated data types
Mergeable persistent data structures (GIT)
Operational transformation
多主复制拓扑:(超过两个MASTER)
星状
环状
所有对所有
需要防止循环复制(写请求记录经过的节点编号)
星状或者环状复制某个节点宕机会导致不可写
所有对所有 容易因延迟导致数据一致性问题或写失败
没有副本概念,客户端直接写多个节点
多数节点响应写请求则成功
读请求也发送到多个节点,版本号保证读取最新的数据
保证: 写成功节点数(W) + 读节点数(R) > 集群节点数(N)
读写并行发往所有节点, W, R 为响应的节点数量
如果 W + R < N 牺牲一致性换取低延时和高可用性
一般选择 W > N/2, R > N/2,容许最多N/2 节点宕机
W + R > N 依然有可能读到旧数据:
监控数据陈旧程度很困难, 无法像主从复制一样监控REPLICATION LAG. 写顺序不确定
Sloppy quorum: 部分节点宕机导致无法写入通常写入的节点(读写迁移)
Hinted handoff: 节点恢复后读写迁移的节点将临时写入数据写回通常写入节点
Sloppy quorum 提高了可用性但是降低了读到最新数据的可能
无主复制也适合多数据中心的场景: 写请求发送多数据中心但只等待本数据中心确认
保证宕机节点最终一致性:
Read repair: 客户端发现读版本冲突自动更新版本比较旧的节点
Anti-entropy process: 后台进程自动比较数据版本并修复 (不一致时间长)
写冲突可能发生在以下情况:
写冲突处理:
Design Data Intensive Applications 笔记 (复制)
原文:https://blog.51cto.com/shadowisper/2448260