分散式事務

来源:https://www.cnblogs.com/learningchencheng/archive/2019/03/12/10518164.html
-Advertisement-
Play Games

近來經常用到分散式事務,這裡總結一下,我們目前的使用場景基本都是採用事務消息方式。那麼說到分散式不得不談的CAP CAP理論概述 一個分散式系統最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。 ...


近來經常用到分散式事務,這裡總結一下,我們目前的使用場景基本都是採用事務消息方式。那麼說到分散式不得不談的CAP

CAP理論概述

一個分散式系統最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。

CAP的定義

Consistency 一致性

一致性指“all nodes see the same data at the same time”,即更新操作成功並返回客戶端完成後,所有節點在同一時間的數據完全一致。

對於一致性,可以分為從客戶端和服務端兩個不同的視角。從客戶端來看,一致性主要指的是多併發訪問時更新過的數據如何獲取的問題。從服務端來看,則是更新如何複製分佈到整個系統,以保證數據最終一致。一致性是因為有併發讀寫才有的問題,因此在理解一致性的問題時,一定要註意結合考慮併發讀寫的場景。

從客戶端角度,多進程併發訪問時,更新過的數據在不同進程如何獲取的不同策略,決定了不同的一致性。對於關係型資料庫,要求更新過的數據能被後續的訪問都能看到,這是強一致性。如果能容忍後續的部分或者全部訪問不到,則是弱一致性。如果經過一段時間後要求能訪問到更新後的數據,則是最終一致性。

Availability 可用性

可用性指“Reads and writes always succeed”,即服務一直可用,而且是正常響應時間。

對於一個可用性的分散式系統,每一個非故障的節點必須對每一個請求作出響應。也就是,該系統使用的任何演算法必須最終終止。當同時要求分區容忍性時,這是一個很強的定義:即使是嚴重的網路錯誤,每個請求必須終止。

好的可用性主要是指系統能夠很好的為用戶服務,不出現用戶操作失敗或者訪問超時等用戶體驗不好的情況。可用性通常情況下可用性和分散式數據冗餘,負載均衡等有著很大的關聯。

Partition Tolerance分區容錯性

分區容錯性指“the system continues to operate despite arbitrary message loss or failure of part of the system”,即分散式系統在遇到某節點或網路分區故障的時候,仍然能夠對外提供滿足一致性和可用性的服務。

分區容錯性和擴展性緊密相關。在分散式應用中,可能因為一些分散式的原因導致系統無法正常運轉。好的分區容錯性要求能夠使應用雖然是一個分散式系統,而看上去卻好像是在一個可以運轉正常的整體。比如現在的分散式系統中有某一個或者幾個機器宕掉了,其他剩下的機器還能夠正常運轉滿足系統需求,或者是機器之間有網路異常,將分散式系統分隔未獨立的幾個部分,各個部分還能維持分散式系統的運作,這樣就具有好的分區容錯性。

CAP的證明

如上圖,是我們證明CAP的基本場景,網路中有兩個節點N1和N2,可以簡單的理解N1和N2分別是兩台電腦,他們之間網路可以連通,N1中有一個應用程式A,和一個資料庫V,N2也有一個應用程式B2和一個資料庫V。現在,A和B是分散式系統的兩個部分,V是分散式系統的數據存儲的兩個子資料庫。

在滿足一致性的時候,N1和N2中的數據是一樣的,V0=V0。在滿足可用性的時候,用戶不管是請求N1或者N2,都會得到立即響應。在滿足分區容錯性的情況下,N1和N2有任何一方宕機,或者網路不通的時候,都不會影響N1和N2彼此之間的正常運作。

如上圖,是分散式系統正常運轉的流程,用戶向N1機器請求數據更新,程式A更新資料庫Vo為V1,分散式系統將數據進行同步操作M,將V1同步的N2中V0,使得N2中的數據V0也更新為V1,N2中的數據再響應N2的請求。

這裡,可以定義N1和N2的資料庫V之間的數據是否一樣為一致性;外部對N1和N2的請求響應為可用行;N1和N2之間的網路環境為分區容錯性。這是正常運作的場景,也是理想的場景,然而現實是殘酷的,當錯誤發生的時候,一致性和可用性還有分區容錯性,是否能同時滿足,還是說要進行取捨呢?

作為一個分散式系統,它和單機系統的最大區別,就在於網路,現在假設一種極端情況,N1和N2之間的網路斷開了,我們要支持這種網路異常,相當於要滿足分區容錯性,能不能同時滿足一致性和響應性呢?還是說要對他們進行取捨。

假設在N1和N2之間網路斷開的時候,有用戶向N1發送數據更新請求,那N1中的數據V0將被更新為V1,由於網路是斷開的,所以分散式系統同步操作M,所以N2中的數據依舊是V0;這個時候,有用戶向N2發送數據讀取請求,由於數據還沒有進行同步,應用程式沒辦法立即給用戶返回最新的數據V1,怎麼辦呢?有二種選擇,第一,犧牲數據一致性,響應舊的數據V0給用戶;第二,犧牲可用性,阻塞等待,直到網路連接恢復,數據更新操作M完成之後,再給用戶響應最新的數據V1。

這個過程,證明瞭要滿足分區容錯性的分散式系統,只能在一致性和可用性兩者中,選擇其中一個。

CAP權衡

通過CAP理論,我們知道無法同時滿足一致性、可用性和分區容錯性這三個特性,那要捨棄哪個呢?

CA without P:如果不要求P(不允許分區),則C(強一致性)和A(可用性)是可以保證的。但其實分區不是你想不想的問題,而是始終會存在,因此CA的系統更多的是允許分區後各子系統依然保持CA。
CP without A:如果不要求A(可用),相當於每個請求都需要在Server之間強一致,而P(分區)會導致同步時間無限延長,如此CP也是可以保證的。很多傳統的資料庫分散式事務都屬於這種模式。
AP wihtout C:要高可用並允許分區,則需放棄一致性。一旦分區發生,節點之間可能會失去聯繫,為了高可用,每個節點只能用本地數據提供服務,而這樣會導致全局數據的不一致性。現在眾多的NoSQL都屬於此類。

對於多數大型互聯網應用的場景,主機眾多、部署分散,而且現在的集群規模越來越大,所以節點故障、網路故障是常態,而且要保證服務可用性達到N個9,即保證P和A,捨棄C(退而求其次保證最終一致性)。雖然某些地方會影響客戶體驗,但沒達到造成用戶流程的嚴重程度。

對於涉及到錢財這樣不能有一絲讓步的場景,C必須保證。網路發生故障寧可停止服務,這是保證CA,捨棄P。貌似這幾年國內銀行業發生了不下10起事故,但影響面不大,報到也不多,廣大群眾知道的少。還有一種是保證CP,捨棄A。例如網路故障事只讀不寫。
孰優孰略,沒有定論,只能根據場景定奪,適合的才是最好的。

分散式事務

微服務的盛行,到處都是分散式事務。比如我們的訂單系統和庫存系統怎麼保證扣庫存生成訂單的原子性。

分散式事務解決方案

這裡分成兩大類來介紹

過程型的強一致性

兩階段提交(或三階段提交)

兩階段提交是基於XA(分散式事務協議),由資料庫實現XA介面,只要資料庫實現了協議,使用比較簡單,不過併發性能不理想,在此不詳述;

結果型的最終一致性

TCC編程模式

分為三個階段TRYING-CONFIRMING-CANCELING。每個階段做不同的處理。

TRYING階段主要是對業務系統進行檢測及資源預留

CONFIRMING階段是做業務提交,通過TRYING階段執行成功後,再執行該階段。預設如果TRYING階段執行成功,CONFIRMING就一定能成功。

CANCELING階段是回對業務做回滾,在TRYING階段中,如果存在分支事務TRYING失敗,則需要調用CANCELING將已預留的資源進行釋放。

拿訂單庫存來舉例:Try(扣庫存),Confirm(更新訂單),如果更新訂單失敗,就進入Cancel階段回滾(恢復庫存),回滾階段由業務編碼實現(再來一個sql把庫存加回去),不同場景不同考慮,不好復用;

消息機制(RocketMQ 4.3+已支持)

發送方首先把消息發送到MQ Server,狀態是”未提交“,主要是起到數據落地的作用,為後續可能出現的回查過程存根。至於是否真的要投遞這個消息取決於隨後的事務提交狀態。
使用TransactionSynchronizationManager.registerSynchronization(TransactionSynchronization synchronization)註冊事務同步器,擴展點由Spring提供,一般為一個通用實現。核心邏輯如下(偽代碼,並非實際實現,只表達核心思路):

  public void afterCompletion(int status) {
       boolean committed = false;
       if (status == 0) {
            committed = true;
        } else {
            if (status != 1) {
                //事務狀態unknown,等回查
                return
            }
            committed = false;
        }

        //通知MQ Server本地事務結果
        send(committed)
  }

如上,同步器會將本地事務的執行結果發送給MQ Server,異常情況交給回查方法來解決。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、Promise 的含義 Promise 是非同步編程的一種解決方案,所謂Promise,簡單來說就是一個容器,裡面保存著一個非同步操作的結果。 Promise對象有以下兩個特點: 1、對象的狀態不受外界的影響。Promise對象代表一個非同步操作,有三種狀態:pending(進行中)、fulfille ...
  • 前沿 項目地址 "vue admin" 歡迎 star 近幾個月,接手了一個老項目的重構規劃,有多老呢?就是前端青銅時代的項目,一個前後端都在同一個鍋里的項目、完全沒有使用任何的打包工具。 後臺 + 渲染頁面 前端 、`css js jQuery` 複製粘貼就是乾。 前端不夠後端來湊。如果前端有一些 ...
  • 插槽用於內容分發,存在於子組件之中。 插槽作用域 父級組件作用域為父級,子級組件作用域為子級,在哪定義的作用域就在哪。 子組件之間的內容是在父級作用域的,無法直接訪問子組件裡面的數據。 插槽元素 <slot></slot> 或 <slot name="名稱">預設值</slot> 1:如果定義了sl ...
  • 原文地址 本文主要講述了使用JavaScript創建對象的幾種方式,分別是傳統的Object構造函數、對象字面量、工廠模式、構造函數模式、原型模式、組合模式,以及es6的class定義類。然後從babel的角度探究es5與es6創建對象的區別。 1.創建對象的幾種方式 (1).Object構造函數和 ...
  • 推薦8款最好用的前端開發工具供美工或者前端開發人員使用,當然若你是NB的全棧工程師也可以下載使用。 ...
  • 1.代碼 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5 <title>OpenLayers</title> 6 <link re ...
  • 我們都都知道kafka的消費組要rebalance,需要觸發以下3個條件之一: 組成員變更,比如新consumer加入組,或已有consumer主動離開組,再或是已有consumer崩潰時則出發rebalance. 組訂閱topic數發生變更,比如使用基於正則表達式的訂閱,當匹配正則表達式的新top ...
  • 一、如何安裝Angular 在文件夾中打開cmd,輸入nmp init創建一個package.json。這個可以一路回車跳過(如果沒有特別要註明)。nmp是前臺的包,用於管理後臺。成功創建package.json後再輸入nmp install bower -g,bower推薦安裝到全局,這裡bowe ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...