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

VoltDB_China發表於2021-05-13

1 背景介紹

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

閱讀一致性:您(僅您自己)可以看到您所做的更改,直到您提交為止,這時其他人才可以看到它們。

遺憾的是,其較差的可伸縮性:線上事務處理(OLTP)工作負載無法很好地擴充套件。在現實情況下,將CPU核心數量加倍不會使您的容量翻倍。

這種失敗導致許多人嘗試使用NoSQL解決方案,但是隨著時間的流逝,越來越明顯的是,如果沒有這些解決方案,鎖定和讀取一致性將很難實現。
VOLTDB是唯一的資料平臺,可讓企業按比例進行鎖定和讀取一致性。

本文解釋了為什麼很難做到這一點,以及VOLTDB是如何做到這一點的。

2 為什麼縮放OLTP很難?

為了讓大家更直觀地瞭解為什麼擴充套件OLTP很難,先來讓我們看一下簡單的白板交易的典型生命週期:

  • 在表格“ a”中插入一行
  • 更新表“ b”中的行
  • 更新表“ c”中的行
  • 做外部活動
  • 更新表“ a”中的行
  • 犯罪

乍一看,可能很難看出這是如何擴充套件的。但是,讓我們看一下使用舊版RDBMS的實際實現:
圖片

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

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中國:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69903219/viewspace-2772046/,如需轉載,請註明出處,否則將追究法律責任。

相關文章