全球分布式数据库遇到的经典问题

标签: 分布式 数据库 | 发表时间:2021-04-09 22:03 | 作者:ideawu
出处:http://www.ideawu.net/blog

全球分布式数据库因为地理距离较远(上万公里), 网络通信延迟一般在 100ms 级别, 所以只能采取异步复制的方案. 采取异步复制方案, 那就决定了最终数据被复制的时效性无法得到保证, 例如正常情况仅仅比网络延迟多几毫秒(100ms+). 但坏情况时, 例如, 因为网络线路不好, 数据可能要花费数秒甚至数分钟才能同步. 这就导致了非常恼人的用户体验.

考虑这样的场景:

某网络游戏平台的用户 A 在中国, 而用户 B 是他曾经的邻居, 目前在美国. 某日, 用户 A 将游戏中的道具转给了用户 B, A 在游戏中看到了明确的操作成功的提示, 而且刷新也确认道具已经转交.

A 在私下用微信告知了这个操作, 然后让 B 在游戏中查看自己的道具背包.

该游戏平台在中国有一个数据库, 在美国也有一个数据库, 两地的数据库是异步复制(最终一致性)的. 因为游戏平台自己的网络线路问题, 这个操作的数据一直没有同步到美国. 但是, 微信所使用的网络线路没有问题, B 收到了 A 的微信消息.

B 在美国不断地刷新, 一直看不到道具, 这让他非常疑惑. 明明 A 说道具已经转交了呀, 而且还发截图了.

这就是经典的异步复制(最终一致性)导致的问题. 要怎么解决呢? 有很多方案, 但是, 正如”没有银弹”一样, 每一种方案都有缺陷. 我们一种一种地分析.

首先, 我们把结构简化, 整个系统只有两个数据库, 分别在中国和美国, 还有两个用户, A 和 B 分别在中国和美国. A 和 B 虽然通过游戏平台的业务逻辑代码访问数据, 但我们简化, 让他们直接访问数据, 让他们可以直接看到数据库的数据.

方案1 - 用户读回源

这个方案很直观, 既然 A 是在中国做的操作, 写的是中国的数据库, 那么 B 也应该访问中国的数据, 而不是美国的数据库. 如果这样做, 绝对不会出现不一致的情况. 也就是说, 单点存储没有一致性问题.

但是, B 在什么情况下应该回源访问中国的数据库呢? 如果他每一次查看背包, 都要访问中国的数据库, 那么他会觉得游戏平台的服务非常”慢”. 而平台在美国部署的数据库没有起作用, 因为部署美国数据库的一个初衷就是让美国的用户访问速度”快”起来.

方案2 - 用户写多处

这个方案也很直观, 用户 A 不仅仅写中国的数据库, 还主动连接美国的数据库写, 双写. 所以, 只要写成功, B 在美国就能立即看到, 因为已经写了美国的数据库啊…

这个方案也有问题, 第一个问题是慢的问题, A 要连接美国的数据库写数据, 显然会很慢. 但是, 没办法, 要么读慢, 要么写慢, 一致性只能用通信来保证, 而通信又受光速所限, 逃不掉.

第二个问题是, 如果写中国数据库成功, 而写美国数据成功, 那么用户应该认为写操作了还是没成功呢? 这个问题没有唯一解, 只能用户自己决定. 如果用户认为成功了, 那么就会出现开头例子所说的不一致的问题. 如果认为没成功, 那么用户只能不断重试. 哈哈, 这就是经典的 CAP 理论, 想要一致性, 就必须要放弃严格的一致性. 不过, 我们开头举的例子是追求一致性的, 所以, 结论是: 不成功, 用户重试.

方案3 - 数据库强一致性读写

前面的两种方案, 不仅有缺陷, 重要的是, 把责任全推给用户. 其实, 数据库本身可以做很多事, 如果数据库做了这些事, 用户就能省功夫. 所以, 我们看看数据库系统能做什么.

如果把中国和美国两个数据库共同组成一个 raft 复制组(集群), 这样的话, 似乎能解决问题? 等等, raft 具有单一的固定 leader, 所以, 如果 leader 在中国, 美国用户肯定要回源到中国写数据. 但是, 我们可以提供配套的 SDK, 用户不需要关心自己有没有回源.

读操作也要回源, 无论用 raft 还是 paxos, 都是基于通信, 所谓通信, 就是回源. 不过, 可以优化回源的数据量, 例如, raft 就可以通过 ReadIndex 技术只回源 binlog 序号, 减少了通信数据量.

这个方案无论是写还是读, 都很慢, 方案不好. 这也违反了”小范围同步复制(强一致), 大范围异步复制(最终一致)”的原则.

方案4 - 数据库提供同步(sync)原语

“小范围同步复制(强一致), 大范围异步复制(最终一致)”, 这个原则是真理, 不能违反. 所以, 数据库自己不能解决全部问题, 还是需要用户一起配合.

借鉴 Memory Barrier 思想, 数据库可以提供一些同步(sync)原语, 以确保数据能同步到期望的地方. 数据同步仍然由数据库来做, 脏活累活由数据库来做, 用户只需要提出请求.

数据库提供 sync_write 原语, 用户 A 在中国写入数据库之后, 请求数据库 sync_write. 数据库收到该请求, 立即获取本地的 binlog 序号, 然后向美国查询 binlog 序号, 如果美国的序号比中国的序号小, 说明之前的写入操作可能还没有同步到美国, 等待, 然后继续轮询. 直到确认同步状态后, 再返回响应给用户 A. 这时, 用户 A 再私下通过微信告诉 B 去查看游戏背包, B 一定会立即看到更新.

数据库提供 sync_read 原语, 用户 B 在美国读取数据前, 先请求数据库 sync_read. 数据库收到该请求, 立即向中国查询最新的 binlog 序号, 然后和自己本地的序号比较. 如果美国的序号比中国的序号小, 那么就 等待, 然后继续比较一次. 直至确认美国的序号等于或者大于刚才查询到的中国的序号, 这才返回响应. B 拿到响应后, 再去查看游戏背包, 一定会看到更新. 注意: 查询中国的序号只做一次.

只要用户 A sync_write, 或者用户 B sync_read, 就能满足一致性, 不需要两人同时做. 而其它的正常请求, 不需要这两个同步原语, 不会有速度慢的问题.

总结

因为地理距离较远而造成网络通信延迟, 这是无法避免. 只要想避免出现不一致的情况, 就必须进行回源(通信). 可以在写的时候通信, 也可以在读的时候通信. 数据库可以提供灵活的手段让用户选择, 让用户自己决定. 而用户(应用开发)自己要区分哪些操作需要一致性, 哪些不需要. 脏活累活可以交给数据库做, 但用户自己也要做细分.

没有银弹, 切不可痴心妄想!

Related posts:

  1. Raft 选主优化之 PreVote
  2. “一致性”是镜花水月
  3. Paxos和Raft读优化 – Quorum Read 和 Read Index
  4. 分布式存储名词解析 – 一致性
  5. 为什么 Leader Based 的分布式协议 Raft 是更好的

相关 [全球 分布 数据库] 推荐:

Google Spanner原理- 全球级的分布式数据库

- - 我自然
Google Spanner简介. Spanner 是Google的全球级的分布式数据库 (Globally-Distributed Database). Spanner的扩展性达到了令人咋舌的全球级,可以扩展到数百万的机器,数已百计的数据中心,上万亿的行. 更给力的是,除了夸张的扩展性之外,他还能同时通过同步复制和多版本来满足外部一致性,可用性也是很好的.

EMC颜开分析Google全球级分布式数据库Spanner

- - InfoQ cn
完成 对Google Dremel原理的分析后,EMC中国研究院的研究员 颜开又在自己博客上 分析了Google的全球级分布式数据库Spanner,他重点分析了Spanner的背景、设计和并发控制. Spanner的扩展性达到了令人咋舌的全球级,可以扩展到数百万的机器,数已百计的数据中心,上万亿的行.

全球分布式数据库遇到的经典问题

- - idea's blog
全球分布式数据库因为地理距离较远(上万公里), 网络通信延迟一般在 100ms 级别, 所以只能采取异步复制的方案. 采取异步复制方案, 那就决定了最终数据被复制的时效性无法得到保证, 例如正常情况仅仅比网络延迟多几毫秒(100ms+). 但坏情况时, 例如, 因为网络线路不好, 数据可能要花费数秒甚至数分钟才能同步.

全球10大数据库

- - 译言-电脑/网络/数码科技
原文: Fiorenttini   译者: julie20098. [非商业性转载必须注明译者julie20098和相关链接. ,否则视为侵权,追究转载责任. 世界气候数据中心:气候全球数据中心, 220TB 的网络数据, 6PB 的其它数据. 国家能源研究科学计算中心,有 2.8PB 容量.

NoSQL数据库的分布式算法

- - NoSQLFan
本文英文原文发表于知名技术博客《 Highly Scalable Blog》,对NoSQL数据库中的 分布式算法和思想进行了详细的讲解. 文章很长,由@ 可观 进行翻译投稿. 英文原文:《 Distributed Algorithms in NoSQL Databases》. 译文地址:《 NoSQL数据库的分布式算法》.

当数据库遇到分布式

- - DockOne.io
数据库通常有着完善的事务支持,但是局限于单机的存储和性能,于是就出现了各种分布式解决方案. 最近读了《Designing Data-Intensive Applications》这本书,所以做一个总结,供大家做个参考,有什么不对的请大家指正,一起讨论. 数据模型可以说软件开发中最重要的部分,因为影响着我们的思考方式、解题思路以及代码的编写方式.

2016全球最强数据库年度排名盘点

- - 数据库 - ITeye博客
说到盘点,首先肯定得看看DB-Engines的全球数据库排名. 下表是2017年1月份前20名数据库引擎最新排名. DB-Engines 2017-01数据库前20名列表. ​DB-Engines这个排名在业界引用得非常多,权威性也很高,总体来说比较客观,它不像很多咨询机构采用市场调查,或者某个数据库厂商发布的数据,而是通过以下6个方面的统计数据来综合评估各个数据库产品得分并给出综合排名:.

Sensei:分布式, 实时, 半结构化数据库

- - ITeye博客
在未出现开源搜索引擎以前, Doug Cutting整了个Lucene, 随后Yonik Seeley写了一个Solr, 在2010年 Shay Banon发布了ElasticSearch, 大概在两年前, 我们迎来了Sensei, 最近他们发布了1.0版本, 下面通过 @sematext对LinkedIn的搜索架构师John Wang的一个采访.

HBase – 基于Hadoop的分布式数据库

- - ITeye博客
  修改:dataDir=/home/ysc/zookeeper. mkdir /home/ysc/zookeeper(注:dataDir是zookeeper的数据目录,需要手动创建). hbase存在系统时间同步的问题,并且误差要再30s以内. HBase是数据库,会在同一时间使用很多的文件句柄,大多数linux系统使用的默认值1024是不能满足的,还需要修改 hbase 用户的nproc,在压力很大的情况下,如果过低会造成 OutOfMemoryError异常.