深度剖析 | 關於數據鎖定和讀取一致性問題

1 背景介紹

傳統的 RDBMS 系統在三件事上值得注意:
鎖定:即鎖定記錄的功能,以便其餘人沒法更改它們。數據庫

閱讀一致性:您(僅您本身)能夠看到您所作的更改,直到您提交爲止,這時其餘人才能夠看到它們。服務器

遺憾的是,其較差的可伸縮性:在線事務處理(OLTP)工做負載沒法很好地擴展。在現實狀況下,將CPU內核數量加倍不會使您的容量翻倍。網絡

這種失敗致使許多人嘗試使用NoSQL解決方案,可是隨着時間的流逝,愈來愈明顯的是,若是沒有這些解決方案,鎖定和讀取一致性將很難實現。
VOLTDB是惟一的數據平臺,可以讓企業按比例進行鎖定和讀取一致性。多線程

本文解釋了爲何很難作到這一點,以及VOLTDB是如何作到這一點的。併發

2 爲何縮放OLTP很難?

爲了讓你們更直觀地瞭解爲何擴展OLTP很難,先來讓咱們看一下簡單的白板交易的典型生命週期:機器學習

  • 在表格「 a」中插入一行
  • 更新表「 b」中的行
  • 更新表「 c」中的行
  • 作外部活動
  • 更新表「 a」中的行
  • 犯罪

乍一看,可能很難看出這是如何擴展的。可是,讓咱們看一下使用舊版RDBMS的實際實現:
圖片ide

在此圖中,有這樣幾件事變得顯而易見:微服務

1.此操做不會當即完成高併發

您須要12次網絡運行,每次運行都須要花費很多時間。在任意一段時間內,「現實世界的設備」都會關閉,並會作任何須要作的事情。
簡而言之:即便一切工做正常,此事務的耗時也將是幾毫秒。性能

2. 長時間運行的數據交換將是數據庫服務器的挑戰

每次更改數據庫服務器中的內容時,您都須要作更多工做,由於全部其餘正在進行的數據交換都須要查看錶的「舊」版本,直到提交爲止。
出於實際目的的考量,每一個不完整的交易都須要本身的數據庫版本,該數據庫由現有數據及其未提交的更改組成。這意味着,若是您每秒運行一千筆交易,而且每筆交易的端到端須要 10 毫秒(即每次網絡行程少於 1 毫秒),則隨時將至少有 100 種不一樣版本的數據庫存在,而且必須仔細檢查任何新交易,以確保它不會與其餘人的更改衝突。
不管您使用SELECT FOR UPDATE,MVCC仍是任何其餘機制,此開銷仍然存在。

3.當您增長CPU芯數時,遞減收益法則就會生效
隨着工做量的增長,常規解決方法是添加更多的CPU內核並將工做分散在它們之間。
雖然這在短時間內會有所幫助,但它會帶來另外一個問題:當您只有一個CPU內核時,能夠確定的是,當嘗試處理會話請求時,數據庫的其餘100個實時版本不會改變。這正是咱們正在作的。
可是,添加第二個CPU內核後,數據庫須要協調它們的活動。這引入了一個全新的層的開銷,每當您在「幫助」中添加另外一個CPU內核時,問題就會以幾何級的速度變得更糟。
最終的結果是造成了一個惡性循環,在其中添加CPU內核以提升TPS,可是每一個新內核都須要關聯消耗全部其餘核心,最終將消耗您經過添加額外核心得到的CPU容量。
若是額外的CPU容量來自羣集中的另外一個節點,那麼事情將會出錯。由於CPU內核之間相互爭論的問題如今變成了到另外一個數據庫節點的網絡訪問。

4.隨着容量的增長,性能變得愈來愈不穩定
實際經驗告訴咱們,即便您在各方面都作到最佳,您仍然會在實際環境中遇到鎖定問題,由於實際數據使用模式可能與測試場景大不相同。
一個典型的例子是網站訪問者在添加購物車或購物籃並按下「從新加載」時會不耐煩,這可能會致使如下狀況:舊請求已鎖定記錄,而新請求則通知用戶「其餘人」已鎖定它。物聯網(IoT)和電信應用程序尤爲容易出現這種狀況,由於許多API的默認行爲是在未收到即時響應時自動重試。
這可能會致使徹底違背直覺的狀況,即減小請求數量將大大增長成功完成的交易數量,由於交易妨礙對方的機會較少。現實生活中發生的是,任何阻止其餘更多交易完成的單個交易均可能致使活動量激增,尤爲是當應用程序開始盲目重試時。

5.應用服務器或微服務器成爲系統中的薄弱環節
市場上幾乎每臺數據庫服務器都具備某種形式的高可用性,可是應用程序服務器和微服務器一般被視爲「無狀態」,由於數據庫服務器負責管理狀態。可是,若是您全部的客戶都被路由到單個組件,而且該組件有大約100筆未完成的交易,那麼若是死機了該怎麼辦?
數據庫服務器從已鏈接的會話的角度看待世界,其中一些會話已鎖定。在已結束組件的會話持有數百個行級鎖的世界中,您能夠指望數據庫服務器在幾分鐘內遵照該鎖定,直到最終弄清該組件已結束並關閉所涉及的會話,釋放他們的鎖定狀態。
這意味着,即便您已經準備好另外一個應用服務器或容器當即承擔其已結束前置的工做量,不然它將沒法對鎖定了幾分鐘的任何記錄進行任何更改,這意味着「有效」多組數據將凍結幾分鐘,在此期間它將沒法進行修改。

6.沒有任何明顯的方法能夠解決此問題
嘗試擴展OLTP的最簡單方法是切換到NoSQL存儲,該存儲要求客戶端在進行更改以前發送證實已讀取特定版本的記錄的證據。
這將爲您帶來更快的性能,直到人們開始爭用數據爲止。最多見的實現是將值的哈希值與值自己一塊兒發送回客戶端。而後,將該哈希做爲一種密碼經過網絡發送,以證實該更改是對先前狀態的合法修改。若是哈希錯誤,則意味着其餘人同時更改了該值,您須要從新開始。
這是一個不能使人滿意的解決方案,由於當多我的開始同時更改同一條記錄時,它會致使與傳統系統相同的負載下不穩定的性能。這也意味着,在上述狀況下,您可能須要操縱兩個或甚至三個鍵值對。實際上,您要作的就是將事務複雜性下降到客戶端層。
顯然,您須要另外一種解決方案。

3 VOLTDB是如何作到這一點的?

VoltDB的建立者,包括圖靈獎得到者Michael Stonebraker,都考慮到了這一特定問題,開發了VoltDB數據平臺,並有效地解決了該問題。
VoltDB數據平臺在作三件事上有不一樣之處:

1.IT分區將工做負載分配給每一個分區,而這是控制CPU核心的單一物理線程的專有責任
是的,許多現代數據平臺都在劃分工做負載。可是,咱們僅需將分區與在單個CPU內核上運行的單線程對齊便可,這意味着該內核無需擔憂另外一個內核在作什麼,所以,VoltDB當即消除了上述幾何可伸縮性問題。

2.它容許任意數量的SQL語句和每一個TRIP的邏輯關聯到VOLTDB
儘管您能夠愉快地將JDBC與VoltDB一塊兒使用,可是當您嘗試將事例名稱和您使用的參數傳遞到 VoltDB 上的服務器側邏輯時,您能夠減小網絡訪問次數和VoltDB必須跟蹤的中間狀態數量。

3.它代表每次訪問都以提交結束
這彷佛有些劇烈,但對性能有重大影響。
在任什麼時候候,VoltDB分區都僅僅處理一個事務,由於它只有單個線程「擁有」其中的全部數據。經過堅持全部事務都是「提交」或「返回」狀態,VoltDB沒必要從客戶的角度跟蹤存儲狀態數據庫的任何額外「副本」。所以,在上面的實例中,VoltDB實現無需跟蹤數據庫的100個版本, 每一個分區僅使用一個活動副本。

綜上,這些更改既爲您提供了傳統RDBMS的功能,而且具備出色的可伸縮性,其性能是同一個硬件的大約9倍。
如今,讓咱們看一下同一筆交易在VoltDB中是如何進展的。
圖片

這能夠經過兩次調用VoltDB來完成。第一次調用執行前三個更改,並將會話ID /到期日期添加到另外兩個軟鎖列中。這容許其餘交互查看正在進行的交易,並自行決定要作什麼。當外部任務完成時,第二個調用觸發,並清除軟鎖列。
圖片

讓咱們比較兩種方法的統計信息:
如您所見,VoltDB的真實事務是經過更少的網絡行程,更少的客戶端API調用以及經過避免應用服務器節點丟失的明確方法來完成的。但這並不意味着沒有其餘可考慮的狀況。讓咱們看看有關VoltDB如何進行鎖定和讀取一致性的常見問題。

4 Q & A

1.若是數據庫服務器出故障了怎麼辦?
咱們在序列圖中未顯示的是,分區每次收到請求時,都會當即同步將該請求轉發到位於另外一臺物理服務器上的一個或多個「備份」分區。而後,全部分區將同時開始處理同一任務。
這意味着,若是一個節點死亡,則在羣集中的其餘節點上會存在該分區的可行且最新副本,數據庫將以最小的時間損失和機上交易損失,從新啓動。
2.若是應用程序服務器出現故障,該怎麼辦?
只要客戶可使用正確的鎖標識符找咱們,咱們的處理將照常進行。在傳統的RDBMS中,當涉及到鎖定時,狀態將有效地保留在客戶端和服務器上,由於服務器已使用客戶端會話惟一的標識符標記行。
可是,若是客戶端銷戶,則該會話將無效。這意味着您須要等待服務器將數據庫鏈接標識爲過去狀態並結束它,而後其餘人才能修改該記錄。
在VoltDB的系統裏,咱們經過容許多個SQL語句和關聯的邏輯在服務器上運行,來「設計」大多數應用場景。若是邏輯交易在關聯的交易事件完成以前依然沒法完成,您可使用簡單的 SQL 自行鎖定邏輯,從而從新控制狀況並知足您的 SLAs 。
3.VoltDB是否會自動執行此操做?
不會,可是它在數據庫表中多了兩列,並增長了大約十二行代碼。與處理傳統 RDBMS 或 NoSQL 交易和鎖定行爲所需的開發人員時間相比,這是徹底合理的。

4.咱們仍然可使用JDBC嗎?

是的,咱們的許多應用程序代碼是基於JDBC的。在大多數應用程序中,20% 的開發人員時間用於編寫 80% 的 SQL,這些 SQL 是友好的或直接的。其餘 20% 涉及複雜的交易,正是這種方法使其變得很是有價值。
5.「每一個內核一個分區一個線程」爲什麼比共享工做負載的多線程和多內核更快?
乍一看,彷佛任何核心可以處理任何問題看起來是最佳選擇。可是,正如咱們上面討論的那樣,隨着您線性地添加多個內核,協調多個內核活動所需的努力會以幾何方式升級。而將事務強制進入虛擬隊列並讓每一個隊列進行單個線程。這個過程要高效得多。

5 結論

鎖定和讀取一致性是當今世紀的兩個重要領域,RDBMS和較新的NoSQL系統都沒法知足其需求,提供合理答案。在VoltDB,咱們的使命是專一於可預測的、符合嚴苛標準的大規模交易。雖然咱們理解咱們的一些設計決策可能看起來很是規,但這些決策倒是由多年的實際經驗決定的。
若是您還有其餘疑問,或者想了解更多有關VoltDB如何在保持低延遲的狀況下支持現代應用程序的信息,請聯繫咱們吧!

關於VoltDB
VoltDB支持強ACID和實時智能決策的應用程序,以實現互聯世界。沒有其它數據庫產品能夠像VoltDB這樣,能夠同時須要低延時、大規模、高併發數和準確性相結合的應用程序加油。
VoltDB由2014年圖靈獎得到者Mike Stonebraker博士建立,他對關係數據庫進行了從新設計,以應對當今不斷增加的實時操做和機器學習挑戰。Stonebraker博士對數據庫技術研究已有40多年,在快速數據,流數據和內存數據庫方面帶來了衆多創新理念。
在VoltDB的研發過程當中,他意識到了利用內存事務數據庫技術挖掘流數據的所有潛力,不但能夠知足處理數據的延遲和併發需求,還能提供實時分析和決策。VoltDB是業界可信賴的名稱,在諾基亞、金融時報、三菱電機、HPE、巴克萊、華爲等領先組織合做有實際場景落地案例。

VoltDB中國:https://www.voltdb-china.cn/

相關文章
相關標籤/搜索