5 数据复制
5.1 目的
-
三种架构
- 共享内存架构
- 共享磁盘架构
- 无共享系统架构(本书重点)
-
数据复制的目的:
- 使数据在地理位置上更接近用户,降低访问延迟
- 系统出现故障也可以继续工作,提高可用性,容错
- 扩展到多条机器同时提供服务,提高读吞吐量
5.2 主从复制
5.2.1 原理
- 主从复制的工作原理
- 写操作只在主节点执行,读操作在主从副本都可以执行
- 写:客户端将写请求发送给主节点,主节点写入本地后,将数据修改以日志会更改流的方式发送给副本
- 主从复制广泛应用于数据库、消息队列和网络文件系统中
5.2.2 同步复制和异步复制
- 同步复制需要等待所有从副本写入,才会向客户端返回写入完成;异步复制只需要主节点写入完成,无需等待从副本确认,立即返回给客户端
- 同步复制的优点:能在从副本上读到最新数据。缺点是会阻塞后面的操作
- 异步复制的优点是快,吞吐量高,但缺点是在从副本上不一定能读到最新数据。
- 半同步:其中一个从节点是同步的,另外的节点是异步的。当该同步的从节点发生故障时,异步的从节点会切换为同步的节点
5.2.3 增加新的从节点
- 如何增加从节点,在有不断新写入请求的情况下,确保存的从节点和主节点保持数据一致?
- 锁库的方式不可行
- 1 在某个时间点对主节点产生一个一致性快照,把该快照发送给从节点
- 2 快照拷贝到从节点,执行写入
- 3 1到2中间这段时间内,主节点上新的写请求写入到日志,并将日志发送给从节点
- 4 从节点根据3中的日志进行追赶操作
5.2.4 处理节点失效
-
目的:如何通过主从复制技术实现系统高可用?
-
从节点失效:追赶式修复
-
主节点失效:节点切换(手动切换或自动切换)
- 使用心跳延迟机制确认主节点是否失效
- 使用共识算法选举新的主节点
-
更多细微问题在8和9章分布式一致性和共识在讨论
5.2.5 复制日志的实现
- 基于语句的复制
- 将每个写请求SQL作为日志发送给从节点
- 缺点:now,random这些函数在不同节点上的执行结果不同(可以替换为执行后的结果)
- 基于预写日志(WAL)传输
- 一个WAL包含了哪些磁盘块的哪些字节发生改变(物理日志,MySQL的redo log)
- 缺点:复制和存储引擎紧密耦合
- 基于行的逻辑日志复制
- MySQL的binlog日志
- 复制和存储引擎分离
- 基于触发器的复制
- 灵活,可以选择要复制哪些数据,但开销高,容易出错
5.3 复制滞后问题
- 完全同步复制的方案性能低,可用性低
5.3.1 读我所写一致性
- 用户写完后,总能看到自己最近提交的更新,但对其他用户则没有任何保证
- 方案:
- 如果更新x分钟之内,在主节点读取;x分钟之后在从节点读取
- 客户端的读请求附带着最近更新的时间戳。系统返回大于该时间戳的数据
5.3.2 单调读一致性
- 当读取数据时,单调读保证,如果某个用户依次进行多次读取,则他不会看到回滚现象,在读取新值之后不会再读到旧值。
- 实现方法:确保某个用户总是从固定的同一个副本进行读取,而不是随机选择副本。
5.3.3 前缀一致读
A: B先生,1 + 11等于多少
B: 等于12
由于A的复制滞后性,C可能看到
B:等于12
A:B先生,1 + 11等于多少
- 对于一系列按照某个顺序发生的写请求,那么读取这些内容时,也要按照当时写入的顺序
- 实现方法:具有因果顺序关系的写入都交给一个分区来完成
5.4 多主节点复制
-
多个主节点,每个主节点又有从节点。多主节点之间,彼此还是另一个主节点的从节点
-
客户端将写请求发送到其中一个主节点,由该主节点负责将数据更改事件发送给其他主节点和自己的从节点
-
适用场景:
- 多数据中心(同一个数据中心适用多主节点无意义)
- 离线客户端操作
- 协作编辑
-
处理写冲突的方式
- 避免冲突,特定用户的更新请求总是路由到特定的数据中心,并在其主节点上进行读写
- 给每个写入分配唯一的ID,如时间戳,UUID,以最高ID的写入为胜利者,将其他写入丢弃。
- 为每个副本分配一个ID,规定ID高的副本写入始终优先于ID低的副本,可能造成数据丢失
- 保留冲突,在应用层事后解决冲突。分别写入时解决和读取时解决
-
拓扑结构
- 多主节点之间的连接方式
- 环形拓扑(MySQL只支持环形拓扑)
- 星星拓扑
- 全链接拓扑
- 环形和星型拓扑的缺点是某个节点发生故障后,会影响其他节点之间复制日志的转发
- 全链接拓扑的缺点是不同节点之间由于网络快慢,可能出现日志覆盖(慢的节点覆盖快的节点)
- 多主节点之间的连接方式
5.5 无主节点复制
-
任何副本都可以接受读写请求,去中心化
-
当客户端从数据库中读取数据时,它不是向一个副本发送请求,而是并行地发送到多个副本,在这个过程中检测和纠正某些过期数据
-
代表:Dynamo风格数据库,如Riak,Cassandra和Voldemort
-
读修复和反熵
- 客户端读取多个副本,检测哪些副本是过期的,并使用最新值进行修复。适用于读多的场景
- 反熵:后台进程修复
-
读写quorum
- 系统有n个节点,其中w个节点用于写,r个节点用于读,只要w+r>n,则读取的节点中一定包含最新值
- 配置n,w,r,以应对各种读写场景。常见的配置是w = r = (n + 1)/2,n为奇数
-
检测并发写
5.6 复制方案总结
- 主从复制简单容易理解,但有单点故障问题
- 多主节点复制和无节点复制更可靠,但更复杂,会引入一致性问题