數據庫的 Consistency 與 Leaky Abstraction

最近在學習各大互聯網公司是如何處理數據一致性的。由於以前從事的不是這個方向的工做,因此並不是什麼經驗之談,只是一些學習筆記。全部資料來自互聯網。sql

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下)

我以爲有一個不太被重視的研究方向是架構的選擇與開發者的生產效率的關係:app

  • 數據庫只給你一個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的各類蛋疼之處:工具

lloyd2.png

原本評論的順序是:
Alice: 我把戒子丟了
Alice: 歐,在樓上找到了
Bob:真爲你高興學習

從西海岸同步到東海岸的IDC以後,由於亂序和到達延遲,可能就變成這樣了google

Alice:我把戒子丟了
Bob:真爲你高興

暈倒,Bob這是起啥哄呢?你不要覺得這個例子是編出來的哦。目前主流的解決方案是把評論合到一個key內存儲,每次跨idc同步是把一個key總體同步。評論歸屬於一個主idc,修改只在那個idc發生。要是評論超級長呢?一個key能夠存儲的數據量是有上限的哦。

lloyd3.png

這個例子是SNS裏爲數很少須要強一致的場景。student和advisor是朋友,表明了一種受權。這種權限的變動若是不是當即生效的,就會致使用戶隱私的泄漏。

原本的順序:
student刪除了隱私圖片
student把advisor加爲好友

實際的順序:
student把advisor加爲好
[期間advisor能夠看到student的全部圖片,包括隱私圖片]
student刪除了隱私圖片

一種更常見的形式是先把另一我的拉黑,而後發朋友圈。這就要求關係鏈的變動不能是Eventual Consistent。

lloyd4.png

alice上傳了照片
alice建立了一個專輯
alice把照片整理到專輯裏

實際的順序:

alice把照片整理到專輯裏(這時既沒有照片,也沒有專輯)
alice建立了一個專輯
alice上傳了照片
最終照片沒有整理到專輯裏

lloyd5.png

共同帳戶裏原本有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已經能夠作到北美東西南三片區強一致容災了,猜想其真正須要跨大洋的事務用途仍是不多的

最後再次強調一下

由於以前從事的不是這個方向的工做,因此並不是什麼經驗之談,只是一些學習筆記。全部資料來自互聯網。

相關文章
相關標籤/搜索