資料庫大牛李海翔詳解全域性讀一致性技術

騰訊技術工程發表於2019-05-09

作者簡介:李海翔,網名“那海藍藍”,騰訊金融雲資料庫技術專家。中國人民大學資訊學院工程碩士企業導師。著有《資料庫事務處理的藝術:事務管理和併發訪問控制》、《資料庫查詢最佳化器的藝術:原理解析與SQL效能最佳化》、《大資料管理》,廣受好評。

2019年5月8日,騰訊資料庫TDSQL技術專家李海翔為中國資料庫技術大會DTCC帶來了騰訊最新的資料庫核心技術:TDSQL原創的全域性讀一致性技術。

資料庫大牛李海翔詳解全域性讀一致性技術

李海翔在會議現場

騰訊專家工程師李海翔在DTCC上做了主題為“騰訊TDSQL全域性讀一致性”的技術內容分享。本次分享,基於資料庫事務處理的核心技術併發訪問控制技術和分散式系統CAP理論中的一致性,TDSQL原創性提出了全面地解決讀一致性的演算法,是的,分散式事務的一致性和分散式系統的一致性統一在一起。

如下是本次分享的主要內容,從如下八個角度全面分享了全域性一致性的前世今生、光輝未來。

  1. 資料庫的事務處理技術,解決了什麼問題?

  2. 分散式事務型資料庫,出現了什麼新問題?--讀半已提交資料異常

  3. 業界是怎麼解決讀半已提交資料異常問題的?

  4. 分散式事務型資料庫,解決了讀半已提交資料異常,就一勞永逸了嗎?

  5. TDSQL的事務處理模型

  6. 什麼是全域性一致性?

  7. TDSQL是怎麼解決各種資料異常的?

  8. 展望未來

一 、資料庫的事務處理技術,解決了什麼問題?

資料庫是一個高併發系統,所有的操作,透過事務的語義加以約束。而事務的語義,表現為事務的四個特性,ACID。而一個資料庫系統,其最核心的技術,就是事務處理技術,為了保障ACID,資料庫使用了多種複雜技術,其中,核心技術的核心是併發訪問控制演算法。

事務處理技術,有兩個初衷:一是資料正確性,二是併發高效率。

資料庫的操作,把SQL語句的語義簡化後,只有讀操作和寫操作兩種。併發操作,就是讀寫操作的併發,組合後分為四種:讀讀、讀寫、寫讀、寫寫。其中,讀寫、寫讀、寫寫三種會產生多種“資料異常現象”。常見的資料異常如圖1,發生了這些資料異常,就不能保證上述的資料準確性。

資料庫大牛李海翔詳解全域性讀一致性技術

圖1 事務型資料庫系統的常見資料異常

這麼多資料異常(圖1列出11種),會帶來什麼問題呢?其表現,是在資料項上,出現了邏輯上不應該出現的“不一致性”現象。說不一致,抽象難理解,看不出其危害,所以我們用“髒讀資料異常”舉個簡單例子:

一個騙子T2轉帳1000元給事務T1,事務T1檢查自己的賬戶,入賬了1000元,然後事務T1把一件衣服賣給了騙子T2,之後騙子T2拿到衣服後回滾了轉賬1000元的操作,然後逃之夭夭了。事務T1既沒有拿到錢還丟失了衣服,損失很大。所以要避免這樣的異常發生。

所以,資料庫的事務處理機制,就是要避免商業交易(併發的互動行為)出現各種使交易任何一方受損的事情發生。

於是,事務型資料庫提出了多種併發訪問控制演算法(如圖2)和其他相關技術,確保商業交易正常。用資料庫的術語講,就是確保ACID四個特性。圖2中的多種演算法,在單機事務隔離級別的可序列化隔離級別,能夠確保圖1中的各種資料異常不會發生。(小問題,請思考:分散式事務型資料庫中的併發訪問控制演算法,能否確保圖1中的各種資料異常不會發生呢?)

資料庫大牛李海翔詳解全域性讀一致性技術

圖2 事務型資料庫的常見併發訪問控制演算法

二  、分散式事務型資料庫,出現了什麼新問題?--讀半已提交資料異常

在金融支付等業務場景中,對賬業務,是支付體系中最重要的一環,也是保證交易、資金安全的最後一道防線。涉及金融的業務,一定要對賬。

使用資料庫做對賬,如圖3,有兩個物理的節點,Na和Nb分別有兩個賬戶X和Y(X和Y也代表賬戶餘額),現在第一個寫事務,要從X賬戶向Y賬戶轉賬10元,當此寫事務在Na節點完成提交,但Nb節點尚沒有提交(如網路延遲發生、或Nb節點負載重尚沒有能執行事務的提交操作)。此時,另外一個分散式事務讀事務要做對賬操作,其在Na節點讀到了已經提交的“X-10”的值,而在Nb節點讀到的是“Y”(未提交的不能讀),則總賬為“X-10+Y”,這個就是資料不一致,因為總賬目少了10元錢。資料庫系統據不能容忍這種事情發生。資料庫大牛李海翔詳解全域性讀一致性技術

圖3 分散式事務型資料庫的讀半已提交資料異常

對於任何一個分散式事務型資料庫,如果基於封鎖併發訪問機制實現併發事務的可序列化排程,是不會存在這裡所討論的問題的。其原因在於:一旦Na節點寫完畢資料,則表明Nb節點至少在Y賬戶這個資料項上施加了寫鎖,而新的對賬讀事務是不能讀取Y資料項的值的,其只能等待,因此不會發生對賬不平的問題。騰訊TDSQL就是這樣的,換句話說,沒有實現可序列化的資料庫,大機率會存在讀半已提交資料異常(小問題,請思考:為什麼這裡說大機率呢?答案參見圖4中的2次讀演算法)。

但是,如果純粹使用封鎖併發訪問控制機制實現可序列化,事務處理的併發度降低,分散式資料庫的事務處理吞吐量就會底,這違背了事務處理技術的另外一個初衷:高效。所以類似TDSQL的分散式資料庫,使用者通常不使用可序列化隔離級別,原因就在於想要使得資料庫高效。而如OceanBase、Oracle等資料庫,乾脆沒有實現可序列化隔離級別,而是直接把出現資料異常的危險拋給了使用者

現在,我們再來討論一下,TDSQL會不會出現“讀半已提交資料異常”?

TDSQL除了支援可序列化隔離級別外,還支援可重複讀(RR)、讀已提交(RC),但這2個隔離級別,同另外一種併發訪問控制演算法、MVCC技術緊密繫結,繫結的原因,是為了提高併發度,使得讀寫、寫讀操作互不影響。就是在MVCC機制下,TDSQL出現了“讀半已提交資料異常”,為什麼呢?

因為前述“在Nb節點讀到的是“Y”(未提交的不能讀)”就是Y的舊版本,而不是未提交的新版本,這是MVCC機制決定的(小問題,請思考:是不是所有使用MVCC技術的,都得小心是不是存在“讀半已提交資料異常”啦?是哈,得小心+小心。要不然,賬目不平可就解釋不清楚了)。

三 、業界是怎麼解決讀半已提交資料異常問題的?

其實,業界目前沒有特別好的解決方式。如圖4,典型的解法如下5類:

第一種:全域性事務管理器架構。典型的例子如PostgreSQL-XC,其存在一個全域性的事務處理節點,用於解決整個分散式系統分為內的所有事務衝突,這樣需要把各個子節點的事務相關資訊都傳送給全域性唯一的事務處理節點,不光通訊量大,而且存在單點瓶頸,限制了事務的處理能力。

第二種:TDSQL以封鎖機制實現全域性可序列化。前述已經分析過,不再贅述。

第三種:物理時鐘,全序排序事務降低併發度典型的例子如著名的Spanner。Spanner徹底地解決了所有資料異常,這是透過實現所有以事務為單位的事件全序排序來完成的。換句話說,實現了線性一致性和事務的可序列化隔離。但是,Spanner以Truetime機制全序排序事務的方式,降低了併發度,導致其分散式事務的吞吐量很低,效率甚至低於基於封鎖的併發訪問控制下的可序列化實現(即:以線性一致性串起了事務一致性,所以理論上看,Spanner每秒數百個的事務的吞吐量使得效率低到了極限)。

第四種:混合時間戳機制,實習區域性偏序排序典型的例子如仿Spanner的CockroachDB,透過SSI實現了可序列化解決了事務型別的資料異常,但是不能解決全域性讀一致性的問題(需要全域性排序才能解決全域性讀一致性問題,但混合時鐘機制做不到全域性有序)。另外,如果選擇非可序列化隔離級別,則和Spanner一樣,還是可能會出現“讀半已提交資料異常”。

第五種:特定的解決機制--兩次讀機制。2次讀機制,源自學術界《Scalable atomic visibility with ramp transactions》這篇paper。其核心思想,是在Na和Nb節點第一次分別讀到“X-10”和“Y”這兩個版本後,透過特定演算法識別這兩個資料不是出於一個一致的點,所以重新去Nb節點再讀一次,這時,因為一段時間過去了,Nb節點大機率完成提交,讀到的資料很可能是“Y+10”,因而可以保持對賬不出現差錯(X-10+Y+10=X+Y,賬目保持平衡)。但是,兩次讀延遲了事務的執行,降低了整個事務的吞吐量;更重要的是,這種解決問題的方式,只針對“讀半已提交資料異常” (小問題,請思考:如果有新的資料異常,還需要讀2次資料嗎?)。

資料庫大牛李海翔詳解全域性讀一致性技術

圖4 資料庫界對“讀半已提交資料異常”主流的解法

四 、分散式事務型資料庫,解決了讀半已提交資料異常,就一勞永逸了嗎?

如標題所言,分散式事務型資料庫,解決了如圖1和圖3提及的各種資料異常之後,是不是就完美了呢?答案是否定的。

一波未平一波又起。

很不幸,圖5有給出了新的資料異常。在《Distributed snapshot isolation: global transactions pay globally, local transactions pay locally》這篇Paper中,稱之為“Cross資料異常”。

圖5列出兩類分散式系統下的資料異常,,其中第一類本質上就是“讀半已提交資料異常”,而第二種“Cross資料異常”,其發生的背景,依然可以放到金融對賬的業務背景中來理解。請看圖5右子圖部分,有兩個物理節點,分別執行了本地事務和分散式事務。事務s和t是本地事務,修改了不同的資料項;事務x和事務y是兩個分散式事務,都在讀取資料;兩個分散式資料讀取資料被本地事務影響,讀到了不一致的資料,事務x讀到的是(a0,b1),事務y讀到的是(b0,a1),而資料的一致狀態要麼是(a0,b0)要麼是(a1,b1)。從業務的角度看,事務x和事務y都發起對賬,結果對出來的結果不僅不同而且還是一個臨時狀態對應的結果,這就是資料異常,對賬業務不能容忍此類事情發生。

資料庫核心層,解決這樣的資料異常,通常的方式,是透過建立事務之間的讀寫依賴關係圖,從中看是否有環存在,如果有則表明資料異常出現,因而需要打破環,即回滾其中某個事務,避免問題出現(小問題,請思考:會不會還有新的資料異常呢?資料異常如果也層出不窮該怎麼辦?)。

資料庫大牛李海翔詳解全域性讀一致性技術

圖5 新的資料異常—Cross異常圖

五 、TDSQL的事務處理模型

先來分享一下TDSQL的事務處理框架,這個框架,可以用圖2來做大的知識背景。

首先,TDSQL第一代的事務處理模型,採取了圖2中的基於封鎖的併發訪問控制協議和MVCC併發訪問控制協議,混合解決併發衝突問題。所以圖6中給出的SS2PL整體就是封鎖的併發訪問控制協議,然後用2PC技術來實現提交階段的原子寫操作。這是整體架構。

在具體實現衝突解決的時候,需要結合MVCC和隔離級別,來解決各種資料異常。這就要區分寫寫衝突、讀寫衝突和寫讀衝突三種具體的情況。

寫寫衝突,通常依靠封鎖機制。原理較為簡單,不再贅述。

讀寫衝突和寫讀衝突,則藉助MVCC來避免鎖造成的延遲事務執行的問題,使得後者能繼續繼續,提高了併發度,所以主流的資料庫基本上都實現了MVCC機制。

資料庫大牛李海翔詳解全域性讀一致性技術

圖6 TDSQL第一代分散式事務處理架構圖

其次,TDSQL第二代的事務處理模型,新支援了圖7基於OCC(樂觀併發訪問控制技術)和DTS(動態調整時間戳的併發訪問控制技術)的技術,使得TDSQL的分散式事務處理能力產生了質的飛躍(OCC使得併發度提高,DTS使得併發訪問控制演算法去中心化),分散式事務處理效能提升數倍,並減少了對中心化時間戳節點的依賴,在分散式事務處理的去中心化的道路上,邁出一大步。

資料庫大牛李海翔詳解全域性讀一致性技術

圖7 TDSQL第二代分散式事務處理架構圖

六 、什麼是全域性一致性?

還記得標題四中的小問題不?小問題,請思考:會不會還有新的資料異常呢?資料異常如果也層出不窮該怎麼辦?

現在,我們正面來談談,什麼是全域性讀一致。目的就是一勞永逸的解決各種資料異常。

在單機資料庫時代,資料庫理論中有個“可序列化”技術,對應到了隔離級別中的可序列化隔離級別,因為理論上把所有事務都排序,消除了併發,因而不會再有資料異常產生。

但是,在分散式資料庫時代,為了提高效率不想使用全域性事務管理器限制併發,就採用了去中心化的架構設計分散式資料庫;不想使用有額外成本的原子鐘等,但又得解決各種資料異常,因此“可序列化”就不夠用了(“可序列化”的本質就是在排序)。

再加上,分散式系統,存在各種不確定性,如網路發生分割槽、瞬間閃斷、延時等,使得發生在分散式系統內的讀和寫事件反序(與發生的順序相反)到達某個節點,這就又為分散式資料庫識別事件之間的先後邏輯關係帶來困難。為了規避這些問題帶來的“邏輯認識上的困擾”,分散式系統中提出各種“一致性”,如線性一致性、因果一致性、單調寫、寫後讀等各種問題(這些問題參見圖8左子圖)。

因此,分散式事務型資料庫其核心要解決的問題就是:同時滿足2個一致。一是分散式讀一致性,二是分散式事務一致性。我們把這兩種一致性,稱為“全域性一致性”(注意不是全域性讀一致性哦)。

分散式讀一致性(即全域性讀一致性),從外部使用者的視角,觀察資料庫內部發生的事件產生的結果之間的順序要與事件發生的實際順序保持一致,不能A事件先於B事件發生,但先不到B事件的結果後才可能看到A事件的影響。這意味著,需要對實際發生的事件進行排序。

而對於分散式事務型資料庫,是從資料庫核心層的角度,保證併發的事務之間,能造成資料異常的情況(讀寫依賴關係圖形成了環)下部分事務被回滾或阻止其發生。及確保事務的可序列化。

如上兩者都被保證的情況下,資料異常可被杜絕。Spanner就是從分散式讀一致性中的線性一致性出發,約束了事務使之序列提交而保證無資料異常的,這好比用一根竹籤先後串起了兩種一致性需求(但效率因事務提交需要等待而低下),確保所有的事件全序排序杜絕任何異常。

但是,正式提出一個問題:大問題,請思考:有沒有高效的方式確保全域性一致性?

答案是:有。請看下一節,TDSQL的解決技術。

注意本文的概念變化:標題是全域性讀一致性,這是引子;但到本節發展成為了全域性一致性;概念的變遷,有其內在的因素,請多體會哦。

資料庫大牛李海翔詳解全域性讀一致性技術

圖8 全域性一致性圖

七 、TDSQL是怎麼解決各種資料異常的?

讓我們回顧一下TDSQL的發展史,TDSQL2017年推出分散式事務處理技術,2018年推出全時態資料庫系統。在全時態資料庫技術中,提出一個“全態資料可見性判斷演算法”。

這個演算法,初衷意在解決“分散式事務型資料庫中,全態資料在任何時間點上怎麼能夠讀到一致的資料”這樣的問題(演算法參考騰迅論文《Efficient time-interval data extraction in MVCC-based RDBMS》)。但是,以這個演算法為基礎,還可以做到全域性一致性。更多技術,請參考VLDB 2019,騰訊論文《A Lightweight and Efficient Temporal Database Management System in TDSQL》。

如圖9左上子圖所示:

  1. 初始時刻t0:r11、r21、r31三個初始的資料項分散式在不同的物理節點上,此時這三個資料項處於一個“一致的”狀態。

  2. t1時刻:r11被修改為r12,此時之後,r12、r21、r31三個資料項處於一個“一致的”狀態;虛線表示了他們處於一致狀態。

  3. t2時刻:r21、r31同時被同一個事務修改,分別變為了r22、r32,所以事務提交後,r12、r22、r32這三個資料項處於一個“一致的”狀態。

  4. 其他時刻依次類推。

  5. 不支援全時態的資料庫,只有當前態,所以DML類操作,只讀取最新資料即可。

  6. 支援了全時態的資料庫,需要從歷史上任何一個點出發,找出這個出發點對應的處於一致性狀態的資料。所以怎麼標識哪些資料的所有值(當前值、歷史值)和事務之間的關係,是全時態資料庫當初解決的一個問題。

  7. 現在,有了如上這個基礎,做到全域性一致性,就容易了很多。所用技術如圖9右子圖部分。

    1. 寫寫衝突封鎖機制互斥:對於前面我們提到的寫寫衝突,還是依靠封鎖機制解決,避免丟失更新等資料異常發生。

    2. MVCC從新版本到舊版本:基於MVCC,可以使得讀寫和寫讀衝突併發執行,提高了事務處理的效率,不然資料庫系統效能一塌糊塗不可使用。另外,使用MVCC,讀區版本的順序是有講究的,從最新版本開始讀就要求構造版本鏈的時候版本由新到舊。

    3. 區域性節點處於Prepared狀態:在MVCC背景下,修改可見性判斷演算法,當資料在2PC階段所有節點同意提交後,正常情況下事務就一定能夠提交(系統故障發生後可被恢復),這時,資料即對滿足快照的事務可見。

    4. 全域性事務Committed狀態:設立全域性事務提交狀態,當協調器在2PC階段所有節點同意提交後,即可設定事務狀態的全域性標誌為Committed(注意不是Prepared),然後通知子節點設定各自狀態為Prepared的。只有全域性提交標誌為Committed,事務讀取到的資料才是合法資料,可參考如圖8中的左下子圖部分,表示了分散式父子事務之間狀態導致可見性的關係。如上2點,避免了前述的讀半已提交資料異常。

    5. 非同步、批次設定本地事務狀態:協調器上全域性事務狀態資訊,非同步地發給涉及的各個子節點,完成子節點上原子事務狀態的Committed化。這點是效能最佳化的問題。

    6. 全域性邏輯時鐘(非跨城/洲分佈):使用全域性邏輯時鐘,為事務建立全域性一致的快照,即用SI技術(快照技術),確保全域性讀一致性。

    7. 衝突可序列化:協調器同時判斷是否存在衝突環,以解決Cross型別的資料異常。(小問題,請思考:還有沒有別的辦法解決cross異常?)

  8. 如此,TDSQL實現了全域性一致性,即達到了外部強一致性和事務一致性的統一。這裡介紹了主幹流程,為了提高效率,TDSQL又做了很多最佳化點,以提高事務的吞吐量。

資料庫大牛李海翔詳解全域性讀一致性技術

圖9 TDSQL全時態資料庫的核心技術—全態資料可見性判斷演算法

但是,再次正式提出一個問題:大問題,請思考:有沒有更高效的方式確保全域性一致性?

八 、展望未來,為什麼TDSQL在事務處理技術上是領先的?

TDSQL一直走在探索分散式事務處理的道路上,走過的路充滿挑戰(圖10)。團隊同時享受到了戰勝挑戰帶來的“不可言而此處無聲勝有聲的與我心有慼慼焉”樂趣。

前進的途中,TDSQL攜手中國人民大學教育部資料工程和知識工程重點實驗室,採用動態時間戳解決事務衝突並去中心化全域性時間戳依賴、用data-drive技術減少事務衝突、用細粒度減少事務衝突等,實現分散式事務處理能力,提升TDSQL分散式事務處理的效率。期待有機會就這些技術進行分享。資料庫大牛李海翔詳解全域性讀一致性技術

圖10 TDSQL分散式事務、分散式一致性處理技術展望

特別感謝中國人民大學教育部資料工程和知識工程重點實驗室,與騰訊TDSQL攜手,共同研發了本文分享的技術。

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

相關文章