成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

突破關系型數據庫桎梏:云原生數據庫中間件核心剖析

運維 數據庫運維 云原生
NewSQL的三種分類中,新架構和云數據庫涉及了太多與數據庫相關的底層實現,為了保證本文的范圍不至太過發散,我們重點介紹透明化分片數據庫中間件的核心功能與實現原理,另外兩種類型的NewSQL在核心功能上類似,但實現原理會有所差別。

數據庫技術的發展與變革方興未艾,NewSQL的出現,只是將各種所需技術組合在一起,而這些技術組合在一起所實現的核心功能,推動著云原生數據庫的發展。在上一篇文章《關系型數據庫尚能飯否?NoSQL、NewSQL誰能接棒?》中我們已經了解了云原生數據庫的發展背景,所以本文會有針對性地深入解讀云原生數據庫的相關內容。

NewSQL的三種分類中,新架構和云數據庫涉及了太多與數據庫相關的底層實現,為了保證本文的范圍不至太過發散,我們重點介紹透明化分片數據庫中間件的核心功能與實現原理,另外兩種類型的NewSQL在核心功能上類似,但實現原理會有所差別。

一、數據分片

傳統的將數據集中存儲至單一數據節點的解決方案,在性能和可用性兩方面已經難于滿足互聯網的海量數據場景。由于關系型數據庫大多采用B+樹類型的索引,在數據量超過閾值的情況下,索引深度的增加也將使得磁盤訪問的IO次數增加,進而導致查詢性能的大幅下降;同時高并發訪問請求也使得集中式數據庫成為系統的最大瓶頸。

在傳統關系型數據庫無法滿足互聯網場景需要的情況下,將數據存儲至原生支持分布式的NoSQL的嘗試越來越多。但NoSQL對SQL的不兼容性以及生態圈的不完善,使得它們在與關系型數據庫的博弈中始終無法完成致命一擊,關系型數據庫的地位依然不可撼動。

數據分片,指按照某個維度將存放在單一數據庫中的數據分散地存放至多個數據庫或表中,以達到提升性能瓶頸及可用性的效果。數據分片的有效手段是對關系型數據庫進行分庫或分表。分庫和分表均可以有效避免因為數據量超過可承受閾值而產生的查詢瓶頸。

除此之外,分庫還能夠用于有效分散對數據庫單點的訪問量;而分表則能夠提供盡量將分布式事務轉化為本地事務的可能。使用多主多從的分片方式,可以有效避免數據單點,從而提升數據架構的可用性。

1、垂直分片

垂直分片又稱為縱向拆分,它的核心理念是專庫專用。在拆分之前,一個數據庫由多個數據表構成,每個表對應著不同的業務。而拆分之后,則按照業務將表進行歸類,分布到不同的數據庫中,從而將壓力分擔到不同的數據庫之上,如圖:

突破關系型數據庫桎梏:云原生數據庫中間件核心剖析

2、水平分片

水平分片又稱為橫向拆分。相對于垂直分片,水平分片不是將數據根據業務邏輯分類,而是按照某個字段的某種規則將數據分散到多個庫或表中,每個分片僅包含其中的一部分數據。

例如,根據ID的最后一位以10取余,尾數是0的放入0庫(表),尾數是1的放入1庫(表)。如圖:

突破關系型數據庫桎梏:云原生數據庫中間件核心剖析

為了解決關系型數據庫面對海量數據時因數據量過大而導致的性能問題,將數據進行分片是行之有效的解決方案。

將集中于單一節點的數據拆分并分別存儲到多個數據庫或表,稱為分庫分表。分庫可以有效分散由高并發所帶來的對數據庫訪問的壓力。分表雖然無法緩解數據庫壓力,但僅跨分表的更新操作,依然能使用數據庫原生的ACID事務;而一旦涉及到跨庫的更新操作,分布式事務的問題就會變得無比復雜。

通過分庫和分表拆分數據使得各個表的數據量保持在閾值以下。垂直分片往往需要對架構和設計進行調整,通常來講,是來不及應對互聯網快速變化的業務需求的,而且它也無法真正解決單點瓶頸。而水平分片從理論上突破了單機數據量處理的瓶頸,并且擴展相對自由,是分庫分表的標準解決方案。

分庫和讀寫分離疏導流量是應對高訪問量的常見手段。分表雖然可以解決海量數據導致的性能問題,但無法解決過多請求訪問同一數據庫導致的響應變慢問題。所以水平分片通常采取分庫的方式,一并解決數據量和訪問量巨大的問題。讀寫分離是另一個疏導流量的辦法,但讀寫數據間的延遲是架構設計時需要考慮的問題。

雖然分庫可以解決上述問題,但分布式架構在獲得了收益的同時,也帶來了新的問題。面對如此散亂的分庫分表之后的數據,應用開發和運維人員對數據庫的操作變得異常繁重就是其中的重要挑戰之一。他們需要知道什么樣的數據需要從哪個具體的數據庫的分表中去獲取。

新架構的NewSQL與數據分片中間件在這個功能的處理方式上是不同的:

  • 新架構的NewSQL會重新設計數據庫存儲引擎,將同一表中的數據存儲在分布式文件系統中。
  • 數據分片中間件則是盡量透明化分庫分表所帶來的影響,讓使用方盡量像使用一個數據庫一樣使用水平分片之后的數據庫。

跨庫事務是分布式數據庫要面對的棘手事情。合理采用分表,可以在降低單表數據量的情況下,盡量使用本地事務,善于使用同庫不同表可有效避免分布式事務帶來的麻煩。在不能避免跨庫事務的場景,有些業務仍需保持事務的一致性。而基于XA的分布式事務由于性能低下,無法被互聯網公司所采納,大多采用最終一致性的柔性事務代替分布式事務。

3、讀寫分離

面對日益增加的系統訪問量,數據庫的吞吐量面臨著巨大瓶頸。對于同一時間有大量并發讀操作和較少寫操作類型的應用系統來說,將單一的數據庫拆分為主庫和從庫,主庫負責處理事務性的增刪改操作,從庫負責處理查詢操作,能夠有效的避免由數據更新導致的行鎖,使得整個系統的查詢性能得到極大改善。

通過一主多從的配置方式,可以將查詢請求均勻分散到多個數據副本,能夠進一步提升系統的處理能力。

使用多主多從的方式,不但能夠提升系統的吞吐量,還能夠提升系統的可用性,可以達到在任何一個數據庫宕機,甚至磁盤物理損壞的情況下仍然不影響系統的正常運行。

讀寫分離本質上是數據分片的一種。與將數據根據分片鍵打散至各個數據節點的水平分片不同,讀寫分離則是根據SQL語義的分析,將讀和寫請求分別路由至主庫與從庫。讀寫分離的數據節點中的數據是一致的,而水平分片每個數據節點的數據內容卻并不相同。將水平分片和讀寫分離聯合使用,能夠更加有效的提升系統性能,但同時也讓系統維護更復雜。

雖然讀寫分離可以提升系統的吞吐量和可用性,但同時也帶來了數據不一致的問題,這包括多個主庫之間的數據一致性及主庫與從庫之間的數據一致性問題。并且,讀寫分離也帶來了與數據分片同樣的問題,它也會使得應用開發和運維人員對數據庫的操作和運維變得更加復雜。

透明化讀寫分離所帶來的影響,讓使用方盡量像使用一個數據庫一樣使用主從數據庫,是讀寫分離的主要功能。

4、核心流程

數據分片核心是由SQL解析、SQL路由、SQL改寫、SQL執行及結果歸并的流程組成。為了保持原有的應用程序實現低接入成本,則需兼容對數據庫的訪問,因此需要進行數據庫協議的適配。

協議適配

NewSQL對傳統關系型數據庫的兼容性,除了SQL之外,兼容數據庫的協議可以降低使用方的接入成本。開源的關系型數據庫均能通過實現它的協議標準,將自己的產品裝扮成原生的關系型數據庫。

由于MySQL和PostgreSQL流行度較高,很多NewSQL會實現它們的傳輸協議,讓使用MySQL和PostgreSQL的用戶能夠無需修改業務代碼就自動接入NewSQL產品。

MySQL協議

MySQL是當前最為流行的開源數據庫。要了解它的協議,可以通過MySQL的基本數據類型、協議包結構、連接階段和命令階段這4方面入手。

基本數據類型

MySQL協議包中所有的內容均由MySQL所定義的基本數據類型組成,具體數據類型參見下表:

突破關系型數據庫桎梏:云原生數據庫中間件核心剖析

MySQL基本數據類型

在需要將二進制數據轉換為MySQL可理解的數據時,MySQL協議包將根據數據類型預先定義的位數讀取,并轉換為相應的數字或字符串;反之亦然,MySQL會將每個字段按照規范中規定的長度寫入協議包。

協議包結構

MySQL協議由一個或多個MySQL協議包(MySQL Packet)組成。無論類型如何,它均由消息長度(Payload Length)、序列主鍵(Sequence ID)和消息體(Payload)這3部分組成:

  • 消息長度為int<3>類型。它表示隨后的消息體所占用的字節總數。需要注意的是,消息長度并不包含序列主鍵的占位在內。
  • 序列主鍵為int<1>類型。它表示一次請求后返回的多個MySQL協議包中,每個協議包的序號。占位為1字節的序列主鍵最大值為0xff,即十進制的255,但這并非表示每次請求最多只能包含255個MySQL協議包,超過255的序列主鍵將再次從0開始計數。例如一次查詢可能返回幾十萬的記錄,那么MySQL協議包只需保證其序列主鍵連續,將大于255的序列主鍵重置為0,重新開始計數即可。
  • 消息體的長度為消息長度所聲明的字節數。它是MySQL協議包中真正的業務數據,根據不同的協議包類型,消息體的內容也不同。

連接階段

連接階段用于創建MySQL的客戶端與服務端的通信管道。該階段主要執行交換并匹配MySQL客戶端與服務端的版本功能描述(Capability Negotiation)、創建SSL通信管道及驗證授權這3個任務。下圖以MySQL服務端為視角繪制了連接創建流程圖:

MySQL連接階段流程圖

該圖并未包含MySQL服務端與客戶端的交互。實際上,MySQL的連接創建是由客戶端發起的。

MySQL服務端在接收到客戶端的連接請求后,先進行服務端和客戶端版本間所具有的功能信息的交換和匹配(Capability Negotiation),然后根據兩端的協商結果生成不同格式的初始化握手協議包,并向客戶端寫入改協議包。協議包中包括由MySQL服務端分配的連接主鍵、服務端當前版本功能描述(Capabilities)以及為驗證授權生成的密文。

MySQL客戶端在接收到服務端發送的握手協議包后,將發送握手協議響應包。該協議包中主要包含的信息是用于數據庫訪問的用戶名及加密后的密碼密文。

MySQL服務端接收到握手協議響應包之后,即進行授權校驗,并將校驗結果返回至客戶端。

命令階段

連接階段成功之后,則進入命令執行的交互階段。MySQL一共有32個命令協議包,具體類型參見下圖:

MySQL命令包

MySQL的命令協議包分為4個大類,分別是:文本協議、二進制協議、存儲過程及數據復制協議。

協議包消息體中的首位用于標識命令類型。協議包根據名稱即可望文生義,在這里無需一一解釋它們的具體用途,下文會解析幾個重點的MySQL命令協議包:

  • COM_QUERY

COM_QUERY是MySQL用于以明文格式查詢的重要命令,它對應JDBC中的java.sql.Statement。COM_QUERY命令本身較為簡單,它由標識符和SQL組成:

1 [03] COM_QUERY

string[EOF] the query the server shall execute

COM_QUERY的響應協議包則較為復雜,見下圖:

MySQL查詢命令流程圖

COM_QUERY根據其場景有可能返回4種類型,它們是:查詢結果、更新結果、文件執行結果及錯誤結果。

當執行過程中出現如網絡斷開、SQL語法不正確等錯誤時,MySQL協議要求將協議包首位設置為0xff,并將錯誤信息封裝至ErrPacket協議包返回。

通過文件執行COM_QUERY的情況并不常見,此處不再過多說明。

對于更新請求,MySQL協議要求將協議包首位設置為0x00,并返回OkPacket協議包。OkPacket協議包需要包含本次更新操作所影響的行記錄數及最后插入的主鍵值信息。

查詢請求最為復雜,它需要將讀取int<lenenc>的方式獲得結果集字段的數目創建為獨立的FIELD_COUNT協議包返回。然后再依次將返回字段的每一列詳細信息分別生成獨立的COLUMN_DEFINITION協議包,查詢字段的元數據信息最終以一個EofPacket結束。之后便可以開始逐行生成數據協議包Text Protocol Resultset Row,它本身并不關注數據的具體類型,會統一將其轉換為string<lenenc>格式。數據協議包最終依然以一個EofPacket結束。

對應于JDBC中java.sql.PreparedStatement的操作,則是由MySQL協議包中的二進制協議組成,它們由COM_STMT_PREPARE、COM_STMT_EXECUTE、COM_STMT_ CLOSE、COM_STMT_RESET和COM_ STMT_SEND_LONG_DATA這5個協議包組成。其中最為重要的是COM_STMT_PREPARE和COM_STMT_ EXECUTE,它們分別對應JDBC中的connection.prepareStatement方法以及connection.execute&connection.executeQuery&connection.executeUpdate方法。

  • COM_STMT_PREPARE

COM_STMT_PREPARE協議包與COM_QUERY協議包類似,同樣是由命令標識符和SQL組成:

1 [16] COM_STMT_PREPARE

string[EOF] the query to prepare

COM_STMT_PREPARE協議包的返回值并非查詢結果,而是由statement_id、列數目和參數數目等信息組成的響應協議包。statement_id是由MySQL分配給完成預編譯之后的SQL的唯一標識,通過statement_id即可從MySQL中獲取相應的SQL。

由COM_STMT_PREPARE命令注冊過的SQL,只需將statement_id傳給COM_STMT_EXECUTE命令即可,無需將SQL本身再次傳入,節省了無謂的網絡帶寬消耗。

而且MySQL可以根據COM_STMT_PREPARE傳入的SQL預編譯為抽象語法樹以供復用,進而提升SQL的執行效率。采用COM_QUERY的方式執行SQL,則需要將每條SQL重新編譯。這也是PreparedStatement比Statement效率更佳的原因所在。

  • COM_STMT_EXECUTE

COM_STMT_EXECUTE協議包主要由statement-id和與SQL的配對的參數組成。它使用了一個名為-bitmap的數據結構,用于標識參數中的空值。

COM_STMT_EXECUTE命令的響應協議包與COM_QUERY命令的響應協議包類似,都是采用字段元數據和查詢結果集的格式返回,中間依然使用EofPacket間隔。

有所不同的是,COM_STMT_EXECUTE命令的響應協議包使用Binary Protocol Resultset Row來代替Text Protocol Resultset Row,它不會無視數據的類型統一轉換為字符串,而是根據返回數據的類型,寫入相應的MySQL基本數據類型,進一步節省網絡傳輸的帶寬。

其他協議

除了MySQL協議,PostgreSQL協議和SQLServer協議也是完全開源的,可以通過同樣的方式實現。而另一個常用的數據庫Oracle協議并不開源,無法通過這種方式實現。

SQL解析

相對于其他編程語言,SQL是比較簡單的。不過,它依然是一門完善的編程語言,因此解析SQL語法與解析其他編程語言(如:Java語言、C語言、Go語言等)并無本質區別。

解析過程分為詞法解析和語法解析。先通過詞法解析將SQL拆分為一個個不可再分的單詞。再使用語法解析器將SQL轉換為抽象語法樹。最后通過訪問抽象語法樹,提煉出解析上下文。

解析上下文包括表、選擇項、排序項、分組項、聚合函數、分頁信息、查詢條件。如果是分片中間件類型的NewSQL還需要記錄可能修改的占位符標記。

將SQL:select username, ismale from userinfo where age > 20 and level > 5 and 1 = 1解析為抽象語法樹:

抽象語法樹

生成抽象語法樹的第三方工具有很多,ANTLR是不錯的選擇。它可以通過開發者定義的規則生成抽象語法樹的Java代碼并提供訪問者接口。相比于代碼生成,手寫抽象語法樹在執行效率方面會更加高效,但是工作量也比較大。對性能要求高的場景中,可以考慮定制化抽象語法樹。

請求路由

根據解析上下文匹配數據分片策略,并生成路由路徑。對于攜帶分片鍵的SQL路由,根據分片鍵的不同可以劃分為單片路由(分片操作符是等號)、多片路由(分片操作符是IN)和范圍路由(分片操作符是BETWEEN)。不攜帶分片鍵的SQL則采用廣播路由。

分片策略通常可由數據庫內置或由用戶方配置。數據庫內置的方案較為簡單,內置的分片策略大致可分為尾數取模、哈希、范圍、標簽、時間等;由用戶方配置的分片策略則更加靈活,可以根據使用方需求定制復合分片策略。

SQL改寫

新架構的NewSQL無需SQL改寫,這部分主要是針對分片中間件類型的NewSQL。它用于將SQL改寫為在真實數據庫中可以正確執行的語句。包括將邏輯表名稱替換為真實表名稱,將分頁信息的起始取值和結束取值改寫,增加為排序、分組和自增主鍵使用的補列,將AVG改寫為SUM/COUNT等。

結果歸并

將多個執行結果集歸并并統一對應用端輸出。結果歸并包括流式歸并和內存歸并:

  • 流式歸并用于簡單查詢、排序查詢、分組查詢及排序和分組但排序項和分組項完全一致的場景,流式歸并結果集的遍歷方式是通過每一次調用next方法取出,無需占用額外的內存。
  • 內存歸并則需要將結果集中所有數據加載至內存處理,如果結果集數據過多,會占用大量內存。

二、分布式事務

前文提到過,數據庫事務是需要滿足ACID(原子性、一致性、隔離性、持久性)這四個特性的:

  • 原子性(Atomicity)指事務作為整體來執行,要么全部執行,要么全不執行。
  • 一致性(Consistency)指事務應確保數據從一個一致的狀態轉變為另一個一致的狀態。
  • 隔離性(Isolation)指多個事務并發執行時,一個事務的執行不應影響其他事務的執行。
  • 持久性(Durability)指已提交的事務修改數據會被持久保存。

在單一數據節點中,事務僅限于對單一數據庫資源的訪問控制,稱之為本地事務。但在基于SOA的分布式應用環境下,越來越多的應用要求對多個數據庫資源、多個服務的訪問都能納入到同一個事務當中,分布式事務應運而生。

關系型數據庫雖然對本地事務提供了完美的ACID原生支持。但在分布式的場景下,它卻成為系統性能的桎梏。如何讓數據庫在分布式場景下滿足ACID的特性或找尋相應的替代方案,是分布式事務的重點工作。

1、XA協議

最早的分布式事務模型是由X/Open國際聯盟提出的X/Open Distributed Transaction Processing(DTP)模型,簡稱XA協議。

DTP模型中通過一個全局事務管理器與多個資源管理器進行交互。全局事務管理器負責管理全局事務狀態和參與事務的資源,資源管理器則負責具體的資源操作,DTP模型與應用程序的關系見下圖:

DTP模型

XA協議使用兩階段提交來保證分布式事務原子性。它將提交過程分為準備階段和提交階段。

  • 在準備階段時,全局事務管理器向每個資源管理器發送準備消息,用于確認本地事務操作的成功與否;
  • 在提交階段時,若全局事務管理器收到了所有資源管理器回復的成功消息,則向每個資源管理器發送提交消息,否則發送回滾消息。資源管理器根據接收到的消息對本地事務進行提交或回滾操作。

下圖展示了XA協議的事務流程:

XA事務流程

二階段提交是XA協議的標準實現。它將分布式事務的提交拆分為兩階段:prepare和commit/rollback。

開啟XA全局事務后,所有子事務會按照本地默認的隔離級別鎖定資源,并記錄undo和redo日志,然后由TM發起prepare投票,詢問所有的子事務是否可以進行提交:當所有子事務反饋的結果為“yes”時,TM再發起commit;若其中任何一個子事務反饋的結果為“no”,TM則發起rollback;如果在prepare階段的反饋結果為yes,而commit的過程中出現宕機等異常時,則在節點服務重啟后,可根據XA recover再次進行commit補償,以保證數據的一致性。

基于XA協議實現的分布式事務對業務侵入很小,它最大優勢就是對使用方透明,用戶可以像使用本地事務一樣使用基于XA協議的分布式事務。XA協議能夠嚴格保障事務ACID特性。

但嚴格保障事務ACID特性是一把雙刃劍。

事務執行在過程中需要將所需資源全部鎖定,它更加適用于執行時間確定的短事務,對于長事務來說,整個事務進行期間對數據的獨占,將導致對熱點數據依賴的業務系統并發性能衰退明顯。因此,在高并發的性能至上場景中,基于XA協議的分布式事務并不是最佳選擇。

2、柔性事務

如果將實現了ACID事務要素的事務稱為剛性事務的話,那么基于BASE事務要素的事務則稱為柔性事務。BASE是基本可用(Basically Available)、柔性狀態(Soft state)和最終一致性(Eventually consistent)這三個要素的縮寫:

  • 基本可用保證分布式事務參與方不一定同時在線;
  • 柔性狀態允許系統狀態更新有一定的延時,這個延時對客戶來說不一定能夠察覺;
  • 最終一致性通常是通過消息可達的方式保證系統的最終一致性。

在ACID事務中對隔離性的要求很高,在事務執行過程中,必須將所有的資源鎖定。柔性事務的理念則是通過業務邏輯將互斥鎖操作從資源層面上移至業務層面。通過放寬對強一致性要求,來換取系統吞吐量的提升。

由于在分布式系統中,可能會出現超時重試的情況,因此柔性事務中的操作必須是冪等的,需要通過冪等來避免多次請求所帶來的問題。實現柔性事務的方案主要有最大努力送達、Saga和TCC。

最大努力送達

是最簡單的一種柔性事務,它適合對于數據庫的操作最終一定能夠成功的場景。由NewSQL自動記錄執行失敗的SQL,并反復嘗試,直至執行成功。使用最大努力送達型的柔性事務是沒有回滾功能的。

這種類型的柔性事務實現最為簡單,但是對場景的要求十分苛刻。這種策略的優點是無鎖定資源時間,性能損耗小。缺點是嘗試多次提交失敗后,無法回滾,它僅適用于事務最終一定能夠成功的業務場景。因此它是通過事務回滾功能上的妥協,來換取性能的提升。

Saga

Saga源于1987年由Hector Garcaa-Molrna和Kenneth Salem發表的論文。

論文參考鏈接:www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf

Saga事務更適合使用長事務的場景。它由多個本地事務所組成,每個本地事務有相應的執行模塊和補償模塊,任何一個本地事務出錯時,可以通過調用相關的補充方法達到事務的最終一致性。

Saga模型將一個分布式事務拆分為多個本地事務,每個本地事務都有相應的執行模塊(Transaction)和補償模塊(Compensation)。當Saga事務中的任一本地事務執行失敗時,可以通過調用其相關補償方法恢復之前的事務,以達到事務最終的一致性。

當每個Saga子事務T1,T2,…,Tn都有對應的補償定義C1,C2,…,Cn-1,那么Saga系統可以保證:

  • 子事務序列T1,T2,…,Tn得以完成 。這是事務的最佳情況,即無需回滾的情況。
  • 或者序列T1,T2,…,Tx, Cx,…,C2,C1,(其中x小于n)得以完成。它能夠保證當回滾發生時,補償操作按照正向操作相反的順序依次執行。

Saga模型同時支持正向恢復以及逆向恢復。正向恢復是指重試當前失敗的事務,它的實現前提是每個子事務都能夠最終執行成功;向后恢復則是前文提及的,在任一子事務失敗時,補償所有已完成的事務。

顯然,正向恢復沒有必要提供補償事務,如果在業務中的子事務最終總會成功,那么向前恢復則能夠降低Saga模型的使用復雜度。另外,如果補償事務難以實現,則正向恢復也是不錯的選擇。

雖然在理論上來講,補償事務永不失敗。然而,在分布式的世界中,服務器可能會宕機、網絡可能會失敗,甚至數據中心也可能會停電。因此,需要提供故障恢復后回退的機制,比如人工干預。

Saga模型沒有XA協議中的準備階段,因此事務沒有實現隔離性。如果兩個Saga事務同時操作同一資源則會產生更新丟失,臟數據讀取等問題。這就需要使用Saga事務的應用程序需要在應用層面加入資源鎖定的邏輯。

TCC

TCC(Try-Confirm-Cancel)分布式事務模型通過對業務邏輯的分解來實現分布式事務。顧名思義,TCC事務模型需要業務系統提供以下三段業務邏輯:

  • Try。完成業務檢查,預留業務所需資源。Try操作是整個TCC的精髓所在,可靈活選擇業務資源鎖的粒度。
  • Confirm。執行業務邏輯,直接使用Try階段預留的業務資源,無需再次做業務檢查。
  • Cancel。釋放Try階段預留的業務資源。

TCC模型僅提供兩階段原子提交協議,保證分布式事務原子性。事務的隔離交給業務邏輯來實現。TCC模型的隔離性思想就是通過業務的改造,從數據庫資源層面加鎖上移至業務層面加鎖,從而釋放底層數據庫鎖資源,放寬分布式事務鎖協議,提高系統的并發性。

雖然在柔性事務中,TCC事務模型的功能最強,但需要應用方負責提供實現Try、Confirm和Cancel操作的三個接口,供事務管理器調用。因此業務方改造的成本較高。

以A賬戶向B賬戶匯款100元為例,下圖展示了TCC對業務的改造:

匯款服務和收款服務分別需要實現,Try-Confirm-Cancel接口,并在業務初始化階段將其注入到TCC事務管理器中。

匯款服務

Try

  • 檢查A賬戶有效性,即查看A賬戶的狀態是否為“轉帳中”或者“凍結”;
  • 檢查A賬戶余額是否充足;
  • 從A賬戶中扣減100元,并將狀態置為“轉賬中”;
  • 預留扣減資源,將從A往B賬戶轉賬100元這個事件存入消息或者日志中。

Confirm

  • 不做任何操作。

Cancel

  • A賬戶增加100元;
  • 從日志或者消息中,釋放扣減資源。

收款服務

Try

  • 檢查B賬戶賬戶是否有效。

Confirm

  • 讀取日志或者消息,B賬戶增加100元;
  • 從日志或者消息中,釋放扣減資源。

由此可以看出,TCC模型對業務的侵入較強,改造的難度較大。

消息驅動

消息一致性方案是通過消息中間件保證上下游應用數據操作的一致性。基本思路是將本地操作和發送消息放在一個本地事務中,下游應用向消息系統訂閱該消息,收到消息后執行相應操作。本質上是依靠消息的重試機制,達到最終一致性。下圖是消息驅動的事務模型:

消息驅動的缺點是:耦合度高,需要在業務系統中引入消息中間件,導致系統復雜度增加。

總的來說,基于ACID的強一致性事務和基于BASE的最終一致性事務都不是銀彈,只有在最適合的場景中才能發揮它們的最大長處。詳細對比一下它們之前的區別,以幫助開發者進行技術選型。由于消息驅動與業務系統的耦合度較高,因此不列入對比表格:

一味的追求強一致性未必是最合理的解決方案。對于分布式系統來說,建議使用“外柔內剛”的設計方案。外柔指的是在跨數據分片的情況下使用柔性事務,保證數據最終一致即可,并且換取最佳性能;內剛則是指在同一數據分片內使用本地事務,以達到ACID的效果。

三、數據庫治理

1、基礎治理

前文講述的服務治理,在數據庫的基礎治理部分大都是通用的。主要包括配置中心、注冊中心、限流、熔斷、失效轉移、調用鏈路追蹤等:

  • 配置中心用于配置集中化以及動態配置更新及通知下發;
  • 注冊中心用于服務發現,這里的服務是指數據庫中間層實例本身,通過它可以實現狀態監測及自動通知,進而使得數據庫中間件具備高可用和自我治愈能力;
  • 限流用于流量的過載保護,分為數據庫中間件本身的流量過載保護和對數據庫的流量過載保護;
  • 熔斷也是流量過載的保護措施之一,它的不同之處在于熔斷整個客戶端對數據庫的訪問,以保護數據庫能夠為其他流量正常的系統繼續提供服務,可以通過前文講的熔斷器模式實現自動熔斷機制;
  • 失效轉移用于多數據副本的情況,在數據完全一致的多數據節點中,當某一節點不可用后,可通過失效轉移的機制讓數據庫中間件訪問至另外有效的數據節點操作數據;
  • 調用鏈路追蹤則是將對數據庫訪問的調用鏈路、性能、拓撲關系等指標以可視化的方式展現出來。

2、彈性伸縮

數據庫治理與服務治理不同的關鍵點在于,數據庫是有狀態的,每個數據節點都有自己持久化的數據,因此很難像服務化一樣做到彈性伸縮。

當系統的訪問量和數據量超過之前評估的預期時,往往涉及到對數據庫的重新分片。雖然使用日期分片等策略時,可以在無需遷移遺留數據的情況下直接擴容,但在大部分場景中,數據庫中的遺留數據往往無法直接映射到新的分片策略中。分片策略的修改則需要進行數據的遷移。

在傳統的系統中,停止服務進行數據遷移,遷移結束之后再重啟服務是行之有效的解決方案。但這種方案使得業務方的數據遷移成本非常高,需要業務方工程師精準的評估數據量。

在互聯網場景中,系統可用性要求極高,而且業務爆發性增長的可能性較傳統行業也更加常見。在云原生的服務架構模型中,彈性伸縮是常見的需求,并且可以比較輕松的實現。因此與服務對等的數據彈性伸縮功能,是云原生數據庫的重要能力。

除了系統預分片之外,彈性伸縮的另一個實現方案是在線數據遷移。在線數據遷移經常被比喻為“在飛行過程中給飛機換引擎”,它最大的挑戰是如何保證遷移過程使服務不受影響。在線數據遷移可以在修改了數據庫的分片策略之后(比如將根據主鍵%4分為4個庫的分片方式改為根據主鍵%16的16個庫的分片方式),通過一系列的系統化操作,保證數據正確的遷移到新的數據節點的同時,讓依賴數據庫的服務完全無需感知。它可以分為以下4個步驟:

  • 同步線上雙寫。即同時將數據寫入分片策略修改前的原數據節點及分片策略修改后的新數據節點。可以通過一致性算法來保證雙寫的一致性,如前文介紹過的Paxos或Raft算法;
  • 歷史數據遷移。以離線的方式,將需要遷移到新數據節點部分的歷史存量數據從原有數據節點遷移過去。可以通過SQL的方式,也可以通過binlog等二進制方式進行處理;
  • 數據源切換。將讀寫請求切換至新的數據源,并停止對原數據節點的雙寫;
  • 清理冗余數據。在舊數據節點中,清理已遷移至新數據節點的相關數據。

在線數據遷移不僅可以做數據擴容,也可以通過同樣的方式在線進行DDL操作。由于數據庫原生的DDL操作是不支持事務的,而且在對包含大量數據表做DDL時會導致長時間鎖表,因此,通過在線數據遷移的方式,是能夠支持在線DDL操作的。在線DDL操作與數據遷移步驟是一致的,只需要在遷移之前新建一個DDL修改后的空表,然后根據上述4步驟進行即可。 

作者介紹

張亮,京東數科數據研發負責人。熱愛開源,目前主導兩個開源項目Elastic-Job和Sharding-Sphere(Sharding-JDBC)。擅長以Java為主分布式架構以及以Kubernetes和Mesos為主的云平臺方向,推崇優雅代碼,對如何寫出具有展現力的代碼有較多研究。2018年初加入京東數科,現擔任數據研發負責人。目前主要精力投入在將Sharding-Sphere打造為業界一流的金融級數據解決方案之上。

責任編輯:龐桂玉 來源: 今日頭條
相關推薦

2018-02-24 19:37:33

Java8數據庫中間件

2017-11-27 05:36:16

數據庫中間件TDDL

2017-11-27 05:06:42

數據庫中間件cobar

2017-12-01 05:04:32

數據庫中間件Atlas

2017-05-23 18:55:05

mysql-proxy數據庫架構

2011-08-10 13:03:58

CJDBC數據庫集群

2024-12-06 08:29:29

2020-10-15 08:34:32

數據庫中間件漫談

2022-11-14 18:23:06

亞馬遜

2017-07-26 09:41:28

MyCATSQLMongoDB

2021-09-06 10:24:12

鴻蒙HarmonyOS應用

2022-04-01 10:55:30

數據庫混合云建設

2022-03-07 10:27:21

云原生云計算數據庫

2023-01-26 00:18:53

云原生數據庫云資源

2017-07-18 17:07:40

數據庫 MyCATJoin

2017-07-18 17:35:16

數據庫MyCATPreparedSta

2017-11-03 11:02:08

數據庫中間件

2017-11-30 08:56:14

數據庫中間件架構師

2017-11-27 06:01:37

數據庫中間件中間層

2017-12-01 05:40:56

數據庫中間件join
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜激情免费 | 久久久婷婷 | 久久久久久综合 | 狠狠操网站| 欧美精品一区在线发布 | 久久久久久久亚洲精品 | 欧美激情在线一区二区三区 | 久草视频网站 | 最新国产精品精品视频 | 在线视频一区二区 | 九九在线精品视频 | 亚洲综合无码一区二区 | 在线视频国产一区 | 成av人电影在线 | 欧美激情精品久久久久久 | av黄色在线观看 | 国产97碰免费视频 | 91久久精品视频 | 亚洲一级在线 | 成人av电影网 | 人操人人| 亚洲精品视频在线 | 日本不卡一区二区三区 | 91高清在线观看 | 91精品国产91久久久久久 | 毛片免费看 | 福利视频网 | 中文字幕二区 | 精品视频一区二区在线观看 | 国产乱码高清区二区三区在线 | 激情综合五月 | 伊人网伊人网 | 日韩不卡一区二区 | 欧美一级片免费看 | 久久久久久色 | 天堂网av在线 | 成人蜜桃av | 国产精品视频免费播放 | 一区二区三区在线免费观看 | 亚洲一区中文字幕 | 欧美一区二区免费 |