2021-06-27

分布式数据库如何做到异地多活?

Views: 1382 | 2 Comments

前段时间写过一篇文章"分布式数据库系统如何做到平滑缩扩容?", 讲了分布式数据库在扩容(集群服务器开机关机)过程中, 如何保证服务 100% 不中断. 那篇文章主要是从客户端的角度去考虑问题, 正如该文章所说的, 一个分布式系统, 必须服务端和客户共同协作, 才能实现服务不中断. 本文从服务端, 也即狭义理解的"数据库系统"的角度, 分析一个分布式数据库系统是如何做到 100% 高可用的.

注意, 高可用, 异地多活, 多主(Leaderless), 这些词汇, 本质上是指同一个东西, 都是指在单一节点宕机时, 客户端可以切换(切主)到其它节点访问, 或者说, 客户端在平时可以访问任意一个节点(多主) -- 切主多主是一回事, 只要可以做到足够快速地切主, 即使表面上一个系统是有 Leader Based 的, 那么它和 Leaderless 没有区别. 阅读本文之后, 相信你能加深对这些概念的理解.

首先说一个定理: 只有强一致性的多副本系统, 才能异地多活.

相信有人立即反对了, 说 MySQL 异步复制的 master-slave 结构, 不也可以切主吗? 你仔细想想, 切主的时候, 人类(运维人员)在其中起到了什么作用? 是不是要求人类确认 master 和 slave 上的数据是一致的之后才能操作? 如果把人类也算做是系统的一部分, 那么这个系统就是强一致性的!

计算机科学的东西就是这样, 只要你选择正确的角度, 就能用正确的理论去解释. 对这个思想感兴趣的同学可以看看关于增加抽象层级的资料.

All problems in computer science can be solved by another level of indirection.

根据前面的定理, 可以得到一个逆定理(逆否定理): 不能异地多活的多副本系统, 一定不是强一致性的.

同样, 对这个定理的理解, 一定要站在正确的角度. 例如支付宝可能使用了自称是强一致性的 OceanBase 分布式数据库, 但是, 当某个城市的数据出现宕机时, 这个城市的几十万用户依然无法使用支付宝. 从这个事实来看, 支付宝所使用的数据库系统, 在城市和城市之间不是强一致性的, 当然也不是"异地多活"的. 支付宝所谓的异地, 是指很小距离范围内的异地, 例如杭州城内的两个机房.

接下来我们讨论一下, 为什么必须强一致, 才能异地多活(切主)呢?

多副本强一致性只有唯一的一种实现方法: 读修复.

读修复是非常重要的技术, 是数据库内核和分布式数据库系统领域是基石. 读修复是指, 在读的时候, 判断多副本是否一致(某些时候是指相同), 如果不一致, 尝试修复(立即修复, 或者异步修复), 然后返回合并后的结果(一致性结果).

读修复必然涉及到读多副本, 所以必须进行网络通信, 在做判断之前, 整个读流程被阻塞. 所以, 纯朴的强一致性实现手段常常是"慢"的, 因此, 人们发明了 Leader Based 技术做优化, 让 Leader 独立做判断, 避免了网络通信阻塞.

纯朴的观念认为 Leader Based 的系统会让 leader 成为系统的单点, 但这种观点是静止的, 在更大的层面并不适用. 正如我们前面提到的 Indirection 概念, 虽然 leader 节点宕机会让系统不可用, 但只要我们发现 leader 宕机之后立即选出新的 leader 节点, 那么站在整个系统的角度, 这并没有任何影响. 至于如何立即发现 leader 宕机并选举 leader, 这都是有成熟的技术方案, 不讨论了.

我的意思是, 我们的观念不要静止不动, 要动态发展, 在工程上合适的时机, 在有条件时, 增加一层 Indirection.

如果多副本不是强一致的, 那么系统是无法切换 leader 的. 因为选举新的 leader 的过程, 必须对多副本的一致性做一个判断. 如果能判断, 那么在这个层面系统就是强一致性的, 如果不能判断, 那么就不是强一致的. 我们既然说多副本不是强一致的, 那么当然就不能判断, 也就无法选举出新的 leader.

有一种错误的观念认为 Paxos 是 leader less 的, 这种观念是狭隘的, 在工程的角度也是错误的. 因为, Paxos 的 phase 1, 本质上就是对多副本的一致性进行判断, 这种行为就是 leader 行为. 有一种说法, 指 Basic Paxos 本质上每一次交互流程都是在选主.

Leader Based 是必须的, 只要在 Leader Based 上面增加一层 Indirection, 那么这一层就可以做到 Leaderless. 或者说, 某个 Leaderless 的系统, 进入其内部, 必然是 Leader Based 的. 所以 Leader Based 和 Leaderless 是统一的, 关键在于你看问题的视角在哪里.

总结

只有强一致性的多副本系统, 才能异地多活. Leader Based 和 Leaderless 是统一的. Indirection 可以解决所有问题, 但是 Indirect 层级太多的问题无法解决[ref].

Related posts:

  1. 为什么 Leader Based 的分布式协议 Raft 是更好的
  2. Leader based 的集群也可以100%高可用
  3. 分布式系统核心三要素
  4. 为什么极少有开源的Paxos库?
  5. MySQL 在线增加从库
Posted by ideawu at 2021-06-27 23:24:48 Tags: ,

2 Responses to "分布式数据库如何做到异地多活?"

Leave a Comment