基本理论
FLP/CAP/BASE/ACID
FLP 不可能原理在异步模型中,分布式系统中只要有一个进程不可用,就可能无法达成整体的共识. 在工程中的分布式系统实现中, 通过解决活锁等问题, 来使系统在一定时间内可以达到一致性.
上图里 CP 还少一个常见的: zookeeper
ACID 对应刚性事务, 追求强一致性, 以 MySql 等 RDBMS 为代表;BASE 对应柔性事务, 牺牲强一致性来换取一定的可用性, 过种中会存在中间状态, 但会达到最终一致性, 以 Spanner 等分布式系统为代表.
CAP 理论分布式系统中 C、A、P 三者不能同时满足,最多只能满足其中两个. 通常来说, 使用网络通信的分布式系统,无法舍弃 P 性质, 会根据选择的不同去达到 AP 或 CP. 不过三者选二的情况很容易发生误解,
分区很少发生,那么在系统不存在分区的情况下没什么理由牺牲 C 或 A。
A 与 C 的取舍可以在同一系统内反复发生, A 与 C 的程度都有很多的层次, 比如可用性的变化和一致性等级的变化等
所以实际使用中可根据应用场景进行适当取舍
以 zookeeper 为例, 它的 CAP 分别为:
C: 最终一致性, 一般十几秒内可以 Sync 到各个节点
A: 数据总是可用, 超过一半的节点的数据是最新的, 但想保证读到最新的数据需手动调用 Sync 函数
P: 一是节点多了会导致写数据时同步延时非常大, 二是节点多了 Leader 选举非常耗时, 可引入 observer 节点缓解
zookeeper 是一个 CP 系统, 因为在任何时刻对它的访问请求能得到一致的数据结果, 但不保证每次服务请求的可用性(比如发生网络分区时), 所以其实它做服务发现并不如 AP 的 eureka 合适
分布式事务
实现最终一致性有三种模式
可靠事件模式, MQ 配合本地或外部事件表
业务补偿模式, 用于业务 / 技术异常时补偿
TCC 模式, 应用层的 2PC
分布式事务的需求, 主要是因为数据库的水平拆分以及应用 SOA 化, 服务调用中会使用到跨库事务. 从某种角度来说, 只有拥有复杂业务 (如金融), 全球性服务(如谷歌), 和拥有大数据量(分库) 的公司才会有这种需求的场景.
常见的一致性协议
ZAB
Raft
Viewstamped Replication
Quorum
Gossip
本质都是 Paxos 协议的变种
常见的类 Paxos 分布式事务实现
MySQL 的 XA
TCC, Try-Confirm-Cancel
很好的一篇核心金融场景分布式事务
分布式锁
通常的选择
单机 Redis 或官方分布式锁 RedLock
Zookeeper
可根据不同的业务场景来使用, 如果对锁的要求不是很高的话, 比如 1% 的重复加锁可接受, 使用单机 Redis 最简单方便
分布式的实际业务场景
微信 PaxosStore
阿里 AliSQL X-Cluster
TiDB (multi raft group)
谷歌 Spanner 等
AWS aurora, dynamo