分布式数据系统——DDIA(二)

数据复制

目的

  • 高可用。容忍单个副本故障、网络分区。
  • 可扩展。多副本提高读吞吐量。
  • 低延时。距用户较近,交互更快。

主从复制

  • 写:主节点。读:从节点。
    200329.lead.follower.png
  • 到主节点网络问题影响所有写入。
复制形式
  • 同步复制。从节点确认写入后返回。
    • 从节点数据最新版本,可瞬间故障切换。
  • 异步复制。从节点无需确认。
    • 从节点不会影响主节点吞吐量。
  • 半同步复制。一个从节点同步,其余异步。
复制日志
  • 基于语句。INSERT等。
    • 非确定性语句,now等执行结果不同。
    • 依赖现有数据的操作,如UPDATE,需要保证副本按照相同顺序执行。
  • 基于物理日志WAL,如redo。
    • 和存储引擎耦合,偏底层。如果存储格式不前后兼容,无法滚动升级。
  • 基于逻辑日志,如binlog。
    • 复制和存储逻辑解耦。向后兼容,方便异构数据。
    • 包含行前后值。记录因果关系,处理并发。
  • 基于触发器
    • 灵活但是增加数据库压力。
运维变更
  • 新增从节点。
    • 一致性快照 -> 复制日志追赶变更。
  • 从节点失效。根据复制日志追赶式恢复。
  • 主节点失效。节点切换。
    1. 确认主节点失效。如心跳超时。
    2. 选新的主节点。选举->共识算法推送,节点和主节点差异小优先。
    3. 新主节点生效。写请求转发,原主节点恢复后降级成从节点。
  • 节点切换风险。
    1. 脑裂。老主节点上线未失效,写冲突。
    2. 数据丢失。异步复制从节点落后,如果外部依赖这部分数据,危险。
    • 使用自增主键,外部映射到该主键关系错误。
    1. 频繁切换。超时时间选取,可使用手工切换。
副本一致性
  • 读写一致。从节点读到自己主节点写的数据。
    • 从主节点读取用户可能修改的数据。
    • 读取时带时间戳(版本号或时钟),副本需要覆盖写入的时间戳,否则重选副本。
  • 单调读一致。读到新版本后不再读到旧版本。
    • 根据用户id路由指定副本。
  • 因果一致。先发生先读。
    • 有因果关系的写入从一个副本读。
    • happens-before追踪因果。

多主复制

200329.mulleader.png

适用场景
  • 多数据中心。
    • 性能。就近写,不用跨广域网。
    • 容错。切换数据中心。
      • 数据中心失效。
      • 到数据中心的网络失效。
  • 离线客户端。等价于单节点数据中心+极不可靠的网络。
  • 协作编辑。
处理写冲突

异步检查:主节点各自写入的优势。
同步检查:简单。

  • 避免冲突。用户路由到单节点写,但漫游或网络故障可能重新路由产生冲突。
  • 收敛于一致。
    • 最后写入者获胜(LWW)。
      • 保留写入版本号最大记录。
      • 保留节点版本号最大记录。
    • 合并并发写入,依赖应用层(自动)、用户(手动)解决冲突。
      • 版本号标记操作的因果关系。

无主复制

  • 用户写入多个节点并从多个节点读取。
    200402.leaderless.png
  • 通过数据版本号确认最新的有效值。
quorum一致
  • 读写quorum。n个节点,w个写入确认,r个读取,w+r>n保证读写节点有重合,可以读到最新值。
  • 读修复。读取到旧版本回写新版本。
  • 反熵。后台进程check更新数据版本。
quorum一致局限

部分成功、复制滞后导致。

  • 读写并发。写操作部分完成,读取不确定。
  • 部分写失效。写操作成功数<w,操作失败但是能读取新值。
  • 宽松quorum条件无法保证读写节点有重合。
    • 网络分区导致可达节点<w个,临时节点暂存数据,保证总共写入w个,网络问题解决后数据回传。

数据分区

  • 目的:提高扩展性,大数据集分散在多个节点上,分担查询负载。
  • partition同义词。
    • shard:ES,MongoDB
    • region:Hbase
    • tablet:Bigtable
    • vnode:Cassandra

分区方式

  • 基于关键字分区。
    • 区间查询特性良好。每个分区可以关键字顺序查找。
  • 基于关键字hash分区。
    • 数据均匀分布。特定模式会数据倾斜,造成热点。
  • 折中。如Cassandra。
    • 复合主键第一列可hash分区,其他列用作SSTable的排序。
    • 第一列分布均匀,其他列支持区间查找。

一致性哈希:特殊的动态分区方式。

  • 适合缓存不适合持久化存储。
  • 分区再平衡涉及节点少。

二级索引

  • 基于文档。利于写,ES、Cassandra。
    • 本地索引。每个分区独立,维护自己的二级索引。
    • 并行查询,读延迟放大。
  • 基于词条。利于读。
    • 分区的全局索引。
    • 单个文档更新,如果涉及多个不同分区的二级索引,写放大显著,通常异步。

分区再平衡

  • 原因:
    • 查询压力增加,需要更多CPU。
    • 数据规模增加,需要更多硬盘。
    • 节点故障,需要其他节点接管。
  • 目标:
    • 负载、存储在集群中分布均匀。
    • 平衡过程中正常提供读写服务。
    • 避免不必要的迁移,加快过程减少网络磁盘I/O影响。
  • 触发方式:
    • 自动。节点负载过重可能被认为失效,再平衡会加重负载,可能雪崩。
    • 手动。
取模

mysql分库分表

  • 迁移过程中数据在节点间复制,需要双写或者复制停写,读写受影响。
  • 再平衡成本高。
    • 节点N发生变化,每个节点都有数据迁移。
    • 节点N发生多次变化,同一条数据多次迁移。
固定数量分区

ES

  • 初始创建远超节点数的分区,节点->分区一对多。
  • 新增节点时只需要调整分区、节点映射关系。
    • 不影响节点的读写。
    • 成本低。
动态分区

Hbase

  • 初始预分区,或者集中在一个分区,节点->分区一对多。
  • 分区数据量大于阈值则分裂,小于阈值则合并。
按节点比例分区

Cassandra

  • 初始时每个节点具有固定数量的分区。Cassandra默认1节点->256个分区。
  • 新增节点加入时,随机选择现有分区分裂拿走一半数据。

请求路由

  1. 客户端连接任意节点,节点转发到目标节点。
  • gossip协议同步集群状态,如Cassandra。
  1. 客户端连接路由层,路由层转发到目标节点。
  • zk同步集群状态,如hbase、codis。
  1. 客户端感知分区节点,直连目标节点。

事务

  • ACID
  • 事务隔离级别
  • 重试中止事务的问题:
    • 超时认为已成功的事务未成功,重试需要保证幂等。
    • 系统负载导致错误,重试更糟,需要重试上限、指数回退。
    • 永久系统故障导致,重试无意义。
    • 重试有除DB外的操作,如短信,需要分布式事务。
    • 重试失败,需要补偿。

分布式系统问题

  • 故障->部分失效。

不可靠网络

  • client->network->server->network->client,都有可能出问题。
    200412.unreliable.png
  • 超时是检测故障唯一可行的方法。
  • 网络采用分组传输,动态分区。是可变性和可靠性的权衡。
    • 优点是可以用较高的资源利用率应对突发流量。
    • 缺点是数据可能包拥堵排队,造成延迟的波动,这种异步网络的延迟是没有上界的。

不可靠时钟

分类
  • 墙上时钟。绝对时钟,可以和NTP同步。
    • System.currentTimeMillis()从1970.1.1开始的毫秒,不含闰秒。
    • 同步时如果本地时钟远快于NTP服务器,会直接回拨本地时钟。
  • 单调时钟。相对时钟,可以测量时间间隔(超时),NTP不同步。
    • System.nanoTime
依赖时钟的风险
  • 依赖绝对时间戳,时间不同步,可能产生因果倒序。优先考虑基于递增计数器、时钟置信区间。
    • LWW前因覆盖后果。
      200419.clocklww.png
  • 依赖相对时间戳,进程暂停,产生冲突。
    • 根据时间校验租约->暂停->处理。可能暂停完租约过期,和其他节点处理冲突。
      200419.lockexpire.png
    • 可以暂停前通知其他节点、大对象不回收定期重启等应对进程暂停问题。

不可靠信息

真相由多数节点决定,节点不能根据自己的信息判断自身状态。//TODO zk故障全公司服务重启

  • 无意误操作。如进程暂停,进程误以为自己还是Master。
    • 应对:Fencing令牌,拒绝旧令牌的操作。
      200419.fencing.png
  • 拜占庭故障。如软件bug、恶意攻击。
    • 应对:鉴权、加密等。

抽象模型

  • 计时模型。网络是否有上界延迟。
    • 同步模型。
    • 部分同步模型。
    • 异步模型。
  • 节点失效模型。
    • 崩溃终止
    • 崩溃恢复。
    • 拜占庭失效。

普遍情况:部分同步+崩溃恢复。

一致性与共识

  • 事务隔离:处理事务并发时的各种临界条件。
  • 分布式一致性:针对延迟、故障等协调副本状态。

可线性化

  • 最强一致性模型。
  • 基本思想:一个系统看起来只有一个副本,所有操作都是原子的。
  • 使用场景:
    • 加锁和主节点选举。
    • 唯一性约束。主键、用户名等。
    • 跨通道的时间依赖。消息消费在图片存储完成之后。
      200423.channel.png
  • 实现方式。考虑容错必须多冗余,涉及复制,只有共识算法可靠。
    • 共识算法。VSR,Paxos,Raft,Zab
    • 主从复制。从唯一节点读取。
      • 使用快照隔离、脑裂则非线性化。
    • 多主复制。非线性化。
    • 无主复制。dynamo风格。
      • 如果网络延迟,在写确认之前读取,仍然非线性化。
        200423.quorum.png

顺序保证

  • 因果一致性弱于可线性化。偏序关系。
    • 因果关系可以被排序(happens-before)
    • 并发关系无法被排序
  • Lamport时间戳。
    • 唯一:计数器-存储节点ID的键值对
    • 因果一致:节点追踪并维护接触的最大计数器,请求中带上该计数器。
      200424.lamport.png

事务与共识

  • 共识的等价问题:
    • 线性化的CAS寄存器
    • 原子事务提交
    • 全序广播
    • 锁与租约
    • 成员协调
    • 唯一性约束
  • 解决方式
    • 单个主节点。
    • 主节点失效:等待恢复、认为介入、共识算法选新主节点。
  • 共识算法的要求:
    • 安全性:
      • 协商一致性。所有节点接收相同的决议。
      • 诚实性。所有节点只能做一次决定。
      • 合法性。结论一定是某个节点提出的。
    • 活性:
      • 可终止性。少于一半节点崩溃可达成结论。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值