當前位置:首頁 > 其他

DRDS 柔性事務漫談

由科技界小哥 發表于 其他2022-05-17

DRDS 是阿里雲提供的一款分散式資料庫產品,它的原型是在阿里內部使用了 10 年的資料庫中介軟體 TDDL。DRDS 在 TDDL 提供的資料切分和 SQL 路由能力上,強化了分散式查詢,事務和水平擴容能力。

什麼是柔性事務?

在分散式資料庫中,資料儲存在多個節點將引入兩個問題:

分散式事務 - 業務需要更新多個節點的資料。

全域性二級索引 - 查詢無法準確的定位資料位於哪個節點。

由於全域性二級索引的同步依賴於事務,因此 分散式事務 是所有分散式資料庫產品都需要解決的核心問題。這一問題的關鍵是 —— 資料儲存在多個節點,原本在單機資料庫上不難實現的 ACID 特性在分散式環境下變得困難:

因為網路通訊的不可靠,事務的原子性需要用多次日誌和網路通訊來保證。

儲存節點的增加,放大了單個儲存節點在事務過程中出現故障的風險。

用鎖實現的事務隔離性,在故障或網路抖動時嚴重影響效能。

因此,在高可用與高效能的應用場景,分散式事務的最佳實踐是放棄 ACID,遵循 BASE 的原則重構業務流程:

DRDS 柔性事務漫談

區別於 ACID 特性的資料庫事務,這種放棄強一致性,採取最終一致方式執行的分散式事務稱為 “柔性事務” (Flexible Transactions)。

在阿里巴巴,“柔性事務” 已經是重構分散式事務的標準方法,覆蓋了商品、交易、支付各個大規模應用場景,並且經受了雙十一的考驗。阿里內部最常用的柔性事務方案有 “訊息事務” 與 “TCC 事務” (Try / Confirm / Cancel),它們的基本原理是一致的:

將業務中的分散式事務分解成一個個在獨立分庫上執行的子事務。

用非同步重試的方式執行這些子事務,由框架或應用保證重試的 “冪等”(相同的業務邏輯不會被重複執行)。

如果需要回滾,以同樣方式執行另一組子事務組成的補償操作,恢復事務前的業務狀態。

柔性事務放棄了隔離性,減小了事務中鎖的粒度,使得應用能夠更好的利用資料庫的併發效能,實現吞吐量的線性擴充套件。非同步執行方式可以更好的適應分散式環境,在網路抖動、節點故障的情況下能夠儘量保障服務的可用性 (Availability)。因此在高可用、高效能的應用場景,柔性事務是最佳的選擇。

但是,現有的柔性事務方案都存在一個共同問題:它們是以框架或者中介軟體的形式存在,應用需要付出較大的改造成本:

框架和中介軟體的介面帶來了學習成本。

使用者需要理解一些概念(例如 “可靠訊息” “冪等”)才能正確的使用。

需要業務流程去適配工具,應用不但在架構上要大幅調整,而且還影響業務流程的直觀性。

有沒有更好的方案?

有。 DRDS / TDDL 在新發布的 5。3 版本開始提供兩種型別的分散式事務:柔性事務 (FLEXIBLE) 和兩階段提交事務 (XA)。前者將柔性事務與傳統資料庫的使用方式相結合,提供了簡單易用、低成本、高效能的 DRDS 分散式事務功能。

使用 DRDS 柔性事務

開啟 DRDS 柔性事務只需要一行程式碼:

DRDS 柔性事務漫談

除了一行程式碼,DRDS 柔性事務的使用方法和普通事務完全相同:應用首先用 SET autocommit = 0和 SET drds_transaction_policy = ‘flexible’ 開啟柔性事務;然後在同一個會話中執行事務的 SQL 語句 —— 最後當應用發起 commit 或 rollback 後,DRDS 將保證這些 SQL 語句執行的原子性:全部成功,或者全部失敗。

相比 TCC 或訊息事務, DRDS 不需要業務編寫補償操作的回滾語句。DRDS 會根據事務中 SQL 語句的語義,自動生成相應的補償操作。

例如,如果業務執行的是一條典型的資金扣減操作:

DRDS 會自動生成對應的反向退款操作:

由於柔性事務的弱隔離性,應用通常會擔心:提交失敗後,非同步回滾操作是否會覆蓋併發的更新,造成 “Lost update” 或者 “回滾覆蓋” 問題。在傳統 TCC 或訊息事務中,回滾覆蓋問題需要由應用引入狀態、版本號、或樂觀鎖機制來規避。

DRDS 柔性事務則使用了一些創新的方式來解決這個問題:

1。 增量回滾

前面的例子已經展示了增量回滾是如何工作的:如果 DRDS 識別應用的 UPDATE 語句中包含 “增量操作”,例如:balance = balance - 100,則會在回滾語句中使用 balance = balance + 100 進行補償。由於增量操作的結果與順序無關,即使事務非同步回滾,也不會覆蓋任何一筆業務的更新結果。

增量操作的定義是 UPDATE 語句符合以下格式:

增量回滾對賬戶、積分、庫存這樣的欄位非常有用,而這些欄位又通常是需要用分散式事務嚴格保證一致性的關鍵資料。建議在應用中儘量對這一類欄位採用 “增量操作” 的方式更新,既節省了一次資料庫操作(SELECT),又避免了柔性事務 “回滾覆蓋” 的風險。

2。 關鍵事務

另一個防止回滾覆蓋的方法是 “關鍵事務”。

在 DRDS 柔性事務中,應用第一次在事務內執行的 DML(INSERT/UPDATE/DELETE) 操作被放入 “關鍵事務” 內執行。在柔性事務的執行流程中,“關鍵事務” 總是第一個開始,最後一個提交。

DRDS 柔性事務漫談

DRDS “關鍵事務” 的執行機制與單機事務相同,不需要記錄補償操作,也不需要非同步回滾。因此,把具有回滾覆蓋風險的 UPDATE 操作放入 “關鍵事務” 內執行,是一個防止非同步回滾的好方法。

“關鍵事務” 的設計,可以讓一個 DRDS 單機事務自然切換到分散式事務。在傳統的柔性事務方案中,應用需要識別業務場景是不是存在分散式事務,然後再根據場景採用不同的事務方式。而 DRDS 的特殊設計,可以做到開啟柔性事務,執行單機事務也不產生任何額外代價。

3。 後置執行

第三個方法是使用 “後置執行” 最佳化事務流程,防止產生回滾。

DRDS 提供了一個全新的 SQL 執行方式:“後置執行”。用來最佳化分散式事務中不影響業務最終執行結果的跨庫操作。在分散式事務理論中,這一類最佳化被稱為 “Best Efforts 1PC”:

DRDS 柔性事務漫談

使用 “後置執行” 非常簡單,只需要在 SQL 語句的頭部加入 /*TDDL:DEFER*/:

UPDATE account SET balance = balance + 100 WHERE id = 123

DRDS 保證後置執行的 SQL 僅僅執行一次,不需要應用關心出錯重試或者冪等的問題。

“後置執行” 將事務中同步執行的操作轉移至非同步執行,減少了分散式事務中持有鎖的時間,提高了事務執行的並行度,因此可以很好的提升分散式事務的效能。同時,由於 “後置執行” 用非同步重試替代了回滾,它也是解決回滾覆蓋問題的另一個方法。

使用 DRDS XA 事務

新版本 DRDS 也支援 XA 事務,在柔性事務的基礎上提供了強一致能力。

DRDS 柔性事務漫談

DRDS XA 事務使用兩階段提交協議 (XA Protocol) 保護子事務的提交與回滾,消除了柔性事務的非同步回滾問題。由於 XA Protocol 在提交與回滾階段始終加鎖,避免了事務結束前的髒讀和覆蓋,但是對效能有較大影響。

“後置執行” 功能在 DRDS XA 事務中同樣可用,能夠減少 XA 協議中的鎖,提供了進一步的效能最佳化空間。

由於 MySQL XA 實現機制的限制,我們建議只有在 DRDS 後端是 MySQL 5。7 版本以上才啟用 XA 事務功能。

低成本、高效能

從穩定性和成本出發,DRDS 柔性事務不引入額外的服務和儲存節點,而是利用後端的 RDS/MySQL 儲存事務日誌和回滾資訊。在實現上,DRDS 儘可能的減少了事務過程中的資料傳輸和日誌開銷,以提升分散式事務的效能。

使用 sysbench 壓測工具表明,在標準的 8core 16G 規格 DRDS 例項上,開啟柔性事務可以達到 9000 QPS 的優異效能。相比不開啟事務的 sysbench 壓測結果,效能差異不到 10%。

DRDS 柔性事務漫談

小結

從分散式事務的原理出發,最終一致的 “柔性事務” 與提供 ACID 保證的 “強一致事務” 是兩個獨立的發展方向。前者實現了更高的水平擴充套件能力與效能,代價是應用需要付出額外的開發成本;後者提供了強一致的資料訪問和更好的開發體驗,但存在效能上的限制。

作為行業領先的雲原生分散式資料庫,DRDS 同時在兩個方向拓展產品的邊界:

降低應用使用 “柔性事務” 的開發成本。

持續創新,提升 “強一致事務” 的效能和擴充套件性。

DRDS 新版本提供的分散式事務功能(柔性事務以及 XA 事務)正是第一階段的成果。

未來的 DRDS 產品將為企業使用者提供更多、更好的選擇:作為基礎的 “強一致事務”、標準的全域性事務隔離級別、基於分散式 MVCC 的一致性讀、以及為高效能應用提供的 “柔性事務” 。在預設配置下,DRDS 將提供標準的事務 ACID 保證,以及高於業界水準的效能;而應用只需要付出較少的代價,就可以適配 DRDS 的特性,獲得更高的水平擴充套件能力和效能保證。

喜歡的小夥伴,點個關注吧,每天分享新的內容!


標簽:
事務  DRDS  柔性  分散式  回滾 

或許網Copyright © 版權所有