数据库的 Consistency 与 Leaky Abstraction

来旺
• 阅读 7534

最近在学习各大互联网公司是如何处理数据一致性的。因为之前从事的不是这个方向的工作,所以并非什么经验之谈,只是一些学习笔记。所有资料来自互联网。

Consistent => Eventual Consistent

这个是陈词滥调了。很多文章已经讲过什么是CAP,什么是BASE了。互联网业务“需要”Eventual Consistency貌似已经是共识了。Eric Bewer最近接受的一次采访,很好的总结了现状(https://medium.com/s-c-a-l-e/google-systems-guru-explains-why-containe...

You allow things to be inconsistent and then you find ways to
compensate for mistakes, versus trying to prevent mistakes altogether.

并且举了一个金融行业的例子:ATM机与银行是联网的,当网络中断了你去ATM上取钱,ATM仍然会吐钱给你。这就说明了即便是银行也选择了availability而不是consistency。但是你取第二笔就会拒绝掉。

Eventual Consistent => Consistent

这是一个比前一个趋势有趣得多的现象。Eventual Consistent是数据层的不负责任,把hard work上推给了应用层的开发:

  • 要么设计各种规则,去compensate边边角角的异常情况
  • 要么在有限一致性约束下,work around一些设计(比如只有单key的一致性的数据库,要一致就得放到一个key下)

我觉得有一个不太被重视的研究方向是架构的选择与开发者的生产效率的关系:

  • 数据库只给你一个k/v模型,业务的逻辑的需求多种多样,无比怀念sql啊
  • 数据库只有eventual consistency,要设计各种对账逻辑去compensate,无比蛋疼啊
  • 异步I/O到处都是callback,逻辑被切成了意大利面条啊
  • 到处鼓吹micro service,跨服务的事务你来搞啊?

最近在hacker news上看到关于technical debt的文章,排第一位的不是bad code,而是unfit architecture(小孩子才分对错)很说明了群众的情绪 https://news.ycombinator.com/item?id=9963994

这篇文章(http://queue.acm.org/detail.cfm?ref=rss&id=2610533)详细描述了Eventual Consistent的各种蛋疼之处:

数据库的 Consistency 与 Leaky Abstraction

本来评论的顺序是:
Alice: 我把戒子丢了
Alice: 欧,在楼上找到了
Bob:真为你高兴

从西海岸同步到东海岸的IDC之后,因为乱序和到达延迟,可能就变成这样了

Alice:我把戒子丢了
Bob:真为你高兴

晕倒,Bob这是起啥哄呢?你不要以为这个例子是编出来的哦。目前主流的解决方案是把评论合到一个key内存储,每次跨idc同步是把一个key整体同步。评论归属于一个主idc,修改只在那个idc发生。要是评论超级长呢?一个key可以存储的数据量是有上限的哦。

数据库的 Consistency 与 Leaky Abstraction

这个例子是SNS里为数不多需要强一致的场景。student和advisor是朋友,代表了一种授权。这种权限的变更如果不是立即生效的,就会导致用户隐私的泄漏。

本来的顺序:
student删除了隐私图片
student把advisor加为好友

实际的顺序:
student把advisor加为好
[期间advisor可以看到student的所有图片,包括隐私图片]
student删除了隐私图片

一种更常见的形式是先把另外一个人拉黑,然后发朋友圈。这就要求关系链的变更不能是Eventual Consistent。

数据库的 Consistency 与 Leaky Abstraction

alice上传了照片
alice创建了一个专辑
alice把照片整理到专辑里

实际的顺序:

alice把照片整理到专辑里(这时既没有照片,也没有专辑)
alice创建了一个专辑
alice上传了照片
最终照片没有整理到专辑里

数据库的 Consistency 与 Leaky Abstraction

共同账户里本来有1000
cindy在idc1从共同账户里取了1000
dave同时在idc2从共同账户取了1000
两个idc的数据同步之后发现账户的余额是-1000了

Spanner

Google Spanner 在其paper里的这段话最能说明这种反思的情绪:

We believe it is better to have application programmers deal with
performance problems due to overuse of transactions as bottlenecks
arise, rather than always coding around the lack of transactions

就是你可以说一致性会导致延迟上升,可以说可用性变差,但是不能直接拿走强一致这种选项。目前已知的有这么几种数据库做到geo replicated情况下的强一致性:

Leaky Abstraction

这些数据库是银弹了吗?是不是有了这种号称全球分布的强一致数据库之后就不用考虑数据是分布的事实了呢?考虑这样一个极端情况:

我们写了一个x信。A君在深圳,B君在加拿大。A君给B君发了一条消息,就是在数据库里修改了两条记录。然后因为数据库是consistent的,内部把改动replicate到了北美,B君就可以看到消息了。

总感觉哪里有点不对。x信做为一个类似的电话公司的机构,两个用户跨大洋的通信居然不是其业务层的逻辑(比如长途费啥的),而是由底层的数据库部门来完成。这不是很奇怪的事情么?更极端的假设

我们写了一个y信,可以在地球和kepler 452b之间进行通信。A君在地球,B君在4000光年外的kepler
452b上。A向B上发消息就是修改了两条数据库记录,因为数据库是consistent的,B君就收到了。

这就显然不对了。我们知道星际间的通信绝对不可能被一个consistent的假象屏蔽掉的。说到底,数据库怎么也是一个leaky abstraction

  • 你可以提供一个consistent的假象,但是必须明白这背后的是至少一个跨idc的rtt的延时代价
  • 你可以提供一个全球分布的假象,到头来什么用户的数据放在哪个idc是业务决定(就近访问降低延迟,另外也有法律规定)也不是数据库的决定
  • 因为光速的不可超越,所以大部分不要求强一致的场景(比如关系链变更v.s.消息收发)还是要用queue的方式去做。只是这个queue一定是database的replication queue,还是业务层的event queue的区别而已。一个通信企业,其核心的跨洋通信管道是database replication queue,都不算业务逻辑,你感受一下这和当年用Database trigger写业务逻辑的区别

所以哪怕有spanner:

  • 用做一种高级的容灾工具
  • 偶尔在需要全局强一致的情况下,做横跨大洋的事务
  • 大部分的事务是在同一个zone内的,zone间的通信仍然是业务逻辑可见的queue
  • 国内的企业已经利用spanner类似的工具可以做到同城三园区强一致容灾了,跨城仍然是eventual consistent的,部分业务场景特殊work around
  • google利用spanner已经可以做到北美东西南三片区强一致容灾了,猜测其真正需要跨大洋的事务用途还是很少的

最后再次强调一下

因为之前从事的不是这个方向的工作,所以并非什么经验之谈,只是一些学习笔记。所有资料来自互联网。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
MySQL总结(十一)子查询
!(https://oscimg.oschina.net/oscnet/upa344f41e81d3568e3310b5da00c57ced8ea.png)子查询1\.什么是子查询需求:查询开发部中有哪些员工selectfromemp;通
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
JOptionPane修改图标
1.在Linux平台下.JOptionPane会显示Java默认的图标,在window平台不显示图标,如何替换这个图标了?2JOptionPane.setIcon(Icon)修改的是内容区域的icon,而不是左上角的Icon.所以需要通过修改Jdialog/Frame的图标来达到修改默认图标的问题.3.代码:if(JOptio
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
什么是数据库
数据库是计算机系统的三大核心基础软件之一。数据库是计算机系统的三大核心基础软件之一。它是存储在数据数据库中的基本对象,包括数字、图像、音频等形式。它被一步一步抽象后存储在数据库中,通常由数据库管理系统(DBMS)控制。DBMS充当数据库与其用户或程序之间的
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
专注IP定位 专注IP定位
3年前
什么是127.0.0.1,如何使用这个IP地址
127.0.0.1是一个非常有名的IP地址——你甚至可能在T恤上见过它。但它到底是什么,为什么这么有名?互联网上的保留地址互联网由数十亿台设备组成。它们使用IP地址相互识别和通信,IP地址在概念上类似于电话号码。互联网协议版本4(IPv4)已经使用了几十年,允许近43亿个这样的地址。IPv4的继任者IPv6拥有超过10^38个可用地址——足以满足地球上的每一
来旺
来旺
Lv1
举杯邀明月,对影成三人。
文章
3
粉丝
0
获赞
0