2021-06-23

分布式数据库异地多活不是你想的那样

Views: 4080 | Add Comments

在分布式数据库领域, "异地多活"是一个非常诱人的特性, 被广泛用于商业广告宣传. 但是, "异地多活"未必是你所想象的那种"多活". 因为分布式数据库的三个重要特性:

  • 多副本
  • 多写入点
  • 低延迟

"异地多活"占据了前两个, 根据"不可能三角"理论, 一旦选择了前两个特性, 那么低延迟便不再是一个选项, 而是一个结果, 给你多大的延迟(多慢), 你就得接受多大的延迟, 你无法选择.

这里涉及到一个基础科学思维的问题, "结果"是一种客观存在的东西, 而"选择"是一种主观决定的东西. 根据"不可能三角"理论, 你无法同时选择三个特性, 不代表一旦你选择其中两个, 就一定会得到极差的第三个特性, 而是说, 一旦你选择了其中两个特性, 那么第三个特性就已经完全固定, 无法再改变.

多副本

多副本是指不同节点的数据是完全一样的(镜像), 如果没有特殊说明, 我们说多副本, 是指强一致性(线性一致性)的多副本, 不是指弱一致性的. 因为, 弱一致性(例如最终一致性)的多副本无法实现"多活"(多写入点), 必须是强一致性的多副本才能实现"多活".

多写入点

多写入点一般也被称为多主(多 Master), 也就是所谓的"多活". 多写入点必须基于强一致性多副本, 如果没有多副本, 或者多副本不是强一致性的, 那么便不能达到多写入点的目的. 不基于强一致性多副本的多写入点系统, 是"伪多活".

常见的"伪多活"的例子有: 某个网游划分了电信和网通两个大区, 完全独立, 电信区挂了不影响网通区, 因为"二"(数量), 所以"多", 是"多活". 这就是经典的伪多活, 这种例子是 Sharding(分区), 不是多活, "多活"是指狭义的"多活", 不能随便诡辩地扩展到广义上来.

不同的分区是完全独立的, 但是, 不同的分区的数据可以进行复制合并, 在隔离外界输入的情况下, 有可能在某个时间点让所有分区的数据达到完全相同(最终一致性). 最终一致性是最经典的伪多活, 因为虽然它经常很快能达到完全相同, 但它只表示一种概率, 一种可能性, 你必须付出时间成本, 而且时间成本没有上限值. 后面会提到的支付宝的例子.

延迟的高低由什么决定?

延迟的高低由光速决定, 也即由地理距离决定. 多个副本之间的地理距离越远, 系统的延迟越高. 所以"异地多活"的系统, "异地"越"异", 系统延迟越高, 如果延迟不高, 必然是异地不够异. 例如, 广州和深圳算异地吗? 北京的南五环机房和北五坏机房两个机房算异地吗?

如果一个数据库系统覆盖全中国(最远两个异地达5千公里), 那么, 它要么做了 Sharding, 要么极其慢, 不可能异地多活还低延迟.

鲜活的例子 - 支付宝

如果你知道支付宝偶尔会在某个城市完全停止服务的新闻, 那么就应该知道, 支付宝(它使用 OceanBase 数据库)所谓的"异地多活", 并不是你所想的那种"多活". 一个城市的用户完全使用不了支付宝长达数小时, 这算什么纯朴观念的"多活"? 它所谓的"多活", 是指整个系统不会全部宕机(全球所有用户完全使用不了支付宝). 只要全球不同时宕机就是多活? 全球一半完全宕机也算多活? 东半球宕机一小时然后西半球宕机一小时交替宕机也算多活? 是不是和你纯朴观念理解的"多活"不一样?

没错! 现实的"多活"系统, 只是某种广义意义上的"多活".

当然, 支付宝的宕机情况不会那么差, 一次宕机影响几十亿人. 但它确确实实影响了几十万人, 这几十万人数小时完完全全无法使用支付宝, 对于这几十万人来说, "诡辩"的"多活"没有任何意义, 虽然他们的数量(占全球几十亿人的比例只有万分之一)只是一粒灰, 但宕机的大山压了他们几个小时无法动弹.

为什么支付宝无法让这几十万了享受其"异地多活"的好处呢? 不能, 因为, 支付宝做了 Sharding, 不同的分区之间的数据不是强一致的. 前面已经说了, Sharding 之间不存在"多活"一说.

"多活"的定义

狭义的"多活"是指原子分区(Shard)内部的多活, 广义的"多活"是指组成一个系统的多个分区不会同时全部宕机. 分区之间, 即使是一个系统内部的多个分区之间, 没有所谓的"多活".

Related posts:

  1. 并发编程两原则
  2. 分布式数据库如何做到异地多活?
  3. 分布式系统Redirect和Proxy的区别
  4. 我所理解的分布式系统
  5. 分布式系统核心三要素
Posted by ideawu at 2021-06-23 23:56:43

Leave a Comment