如何解決微服務的數據一致性分發問題?

介紹

系統架構微服務化以后,根據微服務獨立數據源的思想,每個微服務一般具有各自獨立的數據源,但是不同微服務之間難免需要通過數據分發來共享一些數據,這個就是微服務的數據分發問題。Netflix/Airbnb等一線互聯網公司的實踐[參考附錄1/2/3]表明,數據一致性分發能力,是構建松散耦合、可擴展和高性能的微服務架構的基礎。

本文解釋分布式微服務中的數據一致性分發問題,應用場景,并給出常見的解決方法。本文主要面向互聯網分布式系統架構師和研發經理。

為啥要分發數據?場景?

數據分發場景

我們還是要從具體業務場景出發,為啥要分發數據?有哪些場景?在實際企業中,數據分發的場景其實是非常多的。假設某電商企業有這樣一個訂單服務Order Service,它有一個獨立的數據庫。同時,周邊還有不少系統需要訂單的數據,上圖給出了一些例子:

一個是緩存系統,為了提升訂單數據的訪問性能,我們可以把頻繁訪問的訂單數據,通過Redis緩存起來;

第二個是Fulfillment Service,也就是訂單履行系統,它也需要一份訂單數據,借此實現訂單履行的功能;

第三個是ElasticSearch搜索引擎系統,它也需要一份訂單數據,可以支持前臺用戶、或者是后臺運營快速查詢訂單信息;

第四個是傳統數據倉庫系統,它也需要一份訂單數據,支持對訂單數據的分析和挖掘。

當然,為了獲得一份訂單數據,這些系統可以定期去訂單服務查詢最新的數據,也就是拉模式,但是拉模式有兩大問題:

一個是拉數據通常會有延遲,也就是說拉到的數據并不實時;

如果頻繁拉的話,考慮到外圍系統眾多(而且可能還會增加),勢必會對訂單數據庫的性能造成影響,嚴重時還可能會把訂單數據庫給拉掛。

所以,當企業規模到了一定階段,還是需要考慮數據分發技術,將業務數據同步分發到對數據感興趣的其它服務。除了上面提到的一些數據分發場景,其實還有很多其它場景,例如:

第一個是數據復制(replication)。為了實現高可用,一般要將數據復制多分存儲,這個時候需要采用數據分發。

第二個是支持數據庫的解耦拆分。在單體數據庫解耦拆分的過程中,為了實現不停機拆分,在一段時間內,需要將遺留老數據同步復制到新的數據存儲,這個時候也需要數據分發技術。

第三個是實現CQRS,還有去數據庫Join。這兩個場景我后面有單獨文章解釋,這邊先說明一下,實現CQRS和數據庫去Join的底層技術,其實也是數據分發。

第四個是實現分布式事務。這個場景我后面也有單獨文章講解,這邊先說明一下,解決分布式事務問題的一些方案,底層也是依賴于數據分發技術的。

其它還有流式計算、大數據BI/AI,還有審計日志和歷史數據歸檔等場景,一般都離不開數據分發技術。

總之,波波認為,數據分發,是構建現代大規模分布式系統、微服務架構和異步事件驅動架構的底層基礎技術。

雙寫?

如何保證雙寫的事務性?

對于數據分發這個問題,乍一看,好像并不復雜,稍有開發經驗的同學會說,我在應用層做一個雙寫不就可以了嗎?比方說,請看上圖右邊,這里有一個微服務A,它需要把數據寫入DB,同時還要把數據寫到MQ,對于這個需求,我在A服務中弄一個雙寫,不就搞定了嗎?其實這個問題并沒有那么簡單,關鍵是你如何才能保證雙寫的事務性?

請看上圖左邊的代碼,這里有一個方法updateDbThenSendMsgInTransaction,這個方法上加了事務性標注,也就是說,如果拋異常的話,數據庫操作會回滾。我們來看這個方法的執行步驟:

第一步先更新數據庫,如果更新成功,那么result設為true,如果更新失敗,那么result設為false;

第二步,如果result為true,也就是說DB更新成功,那么我們就繼續做第三步,向mq發送消息

如果發消息也成功,那么我們的流程就走到第四步,整個雙寫事務就成功了。

如果發消息拋異常,也就是發消息失敗,那么容器會執行該方法的事務性回滾,上面的數據庫更新操作也會回滾。

初看這個雙寫流程沒有問題,可以保證事務性。但是深入研究會發現它其實是有問題的。比方說在第三步,如果發消息拋異常了,并不保證說發消息失敗了,可能只是由于網絡異常抖動而造成的拋異常,實際消息可能是已經發到MQ中,但是拋異常會造成上面數據庫更新操作的

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716332.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716332.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716332.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在嵌入式設備中用多項式快速計算三角函數和方根

慣性傳感器的傾角計算要用到三角函數. 在 MCS-51, Cortex M0, M3 之類的芯片上編程時, 能使用的資源是非常有限, 通常只有兩位數KB的Flash, 個位數KB的RAM. 如果要使用三角函數和開方就要引入 math.h, 會消耗掉10KB以上的Flash空間. 在很多情況下受硬件資源限制無法使用 math.…

【 10X summary report】怎么看?詳細解讀筆記

報告內容 在開始正式的分析之前,需要查看在對齊和計數過程中生成的任何總結統計信息。下圖是由Cell Ranger工具創建的10X總結報告,在從10X scRNA-seq實驗生成計數矩陣時會生成。 The left half of the report describes sequencing and mapping statist…

賣wordpress網站模板的網站

WP模板牛 http://www.wpniu.com 上面有很多免費wordpress模板資源的網站,除了免費模板,還有付費模板。 My模板(我的模板) http://www.mymoban.com 老牌網站模板資源站,上面有wordpress模板、帝國CMS模板、WooCommerce模板可以直接免費下載…

Linux whois命令教程:查詢域名所有者信息(附案例詳解和注意事項)

Linux whois命令介紹 whois命令是一個用于查詢域名所有者信息的工具。它可以直接從命令行進行查詢,這對于沒有圖形用戶界面的系統或者需要在shell腳本中進行查詢的情況非常有用。 Linux whois命令適用的Linux版本 whois命令在大多數Linux發行版中都可以使用&…

C++之stack

1、stack簡介 stack是實現的一個先進后出,后進先出的容器。它只有一個出口,只能操作最頂端元素。 2、stack庫函數 (1)push() //向棧壓入一個元素 (2)pop() //移除棧頂元素 (3…

基于springboot+vue的中國陜西民俗網

博主主頁:貓頭鷹源碼 博主簡介:Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰,歡迎高校老師\講師\同行交流合作 ?主要內容:畢業設計(Javaweb項目|小程序|Pyt…

在 Angular 中使用 Renderer2

Renderer2 類 Renderer2 類是 Angular 提供的一個抽象服務,允許在不直接操作 DOM 的情況下操縱應用程序的元素。這是推薦的方法,因為它使得更容易開發可以在沒有 DOM 訪問權限的環境中渲染的應用程序,比如在服務器上、在 Web Worker 中或在原…

Java如何剪切視頻

背景:如何使用Java批量切割視頻 FFmpeg 是一個強大的開源多媒體處理工具,被廣泛應用于音視頻的錄制、轉碼、編輯等方面。它支持幾乎所有主流的音視頻格式,能夠在各種操作系統平臺上運行,包括 Windows、macOS 和 Linux。FFmpeg 提…

nginx,php-fpm

一,Nginx是異步非阻塞多進程,io多路復用 1、master進程:管理進程 master進程主要用來管理worker進程,具體包括如下4個主要功能: (1)接收來自外界的信號。 (2)向各worker進…

SAP PP學習筆記04 - BOM2 -通過Serial來做簡單的BOM變式配置,副明細,BOM狀態,BOM明細狀態,項目種類,遞歸BOM

本章繼續講BOM。 本章講通過Serial來做簡單的BOM變式配置。還講了BOM的相關概念:副明細,BOM狀態,BOM明細狀態,項目種類,遞歸BOM 等。 1,通過Serial(序列號)來做簡單的 VC&#xff0…

spring自定義注解之-ElementType.METHOD方法級注解聲明

自定義注解類型和常用場景 可以參考之前的文章 : ElementType.FIELD字段級注解聲明 如果在項目中,多處地方都需調用到同一個方法進行邏輯處理,且與方法的業務邏輯無關,比如監控,日志等,則可用自定義的方法…

【JavaSE】面向對象——繼承性

繼承性 繼承性的概念 所謂繼承,就是程序猿在保持原有類特性的基礎上進行擴展,增加新功能,這樣的類被稱為派生類或者子類,原有類被稱為超類或者基類。 在對于繼承性概念進行書寫前,我曾查閱許多資料來保證對其表達的…

Some collections -- 2024.3

一、TensorFlow Android (dataset: Mnist) We used TensorFlow to define and train our machine learning model, which can recognize handwritten numbers, called a number classifier model in machine learning terminology. We transform the trained TensorFlow mod…

C++學習第五天(內存管理)

1、內存分布 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(sizeof(int) * 4);int…

2024.03.01作業

1. 基于UDP的TFTP文件傳輸 #include "test.h"#define SER_IP "192.168.1.104" #define SER_PORT 69 #define IP "192.168.191.128" #define PORT 9999enum mode {TFTP_READ 1,TFTP_WRITE 2,TFTP_DATA 3,TFTP_ACK 4,TFTP_ERR 5 };void get_…

高維中介數據:基于交替方向乘子法(ADMM)的高維度單模態中介模型的參數估計(入門+實操)

全文摘要 用于高維度單模態中介模型的參數估計,采用交替方向乘子法(ADMM)進行計算。該包提供了確切獨立篩選(SIS)功能來提高中介效應的敏感性和特異性,并支持Lasso、彈性網絡、路徑Lasso和網絡約束懲罰等不…

npm 鏡像源切換與設置

項目背景 依賴安裝中斷或響應特別慢。 可以看到當前所用的鏡像是 https://registry.npmjs.org 。 切換淘寶鏡像之后總算能夠安裝下來 命令行模式 查看當前鏡像源 # 查看當前鏡像源 npm config get registry 可以看到默認情況下是官方默認全局鏡像 https://registry.npmjs.o…

競爭加劇下,登頂后的瑞幸該做什么?

瑞幸咖啡僅用短短18個月時間從品牌創立到納斯達克上市,刷新全球最快上市記錄。2020年因交易造假事件被勒令退市股價暴跌80%,有人說這個創造了赴美IPO奇跡的“巨嬰”將是下一個倒下的ofo。2023年瑞幸咖啡以逆勢超速增長領跑咖啡賽道有力回應了市場的質疑&…

Vector中的begin和end函數是左閉右開的區間

vector::end() 函數的語法 vector::end(); 參數&#xff1a; none——它什么都不接受。 返回值&#xff1a; iterator– 它返回一個指向向量的 past-the-end 元素的迭代器。 實際上Vector中的begin和end函數是左閉右開的區間。 例&#xff1a; Input: vector<int>…

Java多線程實現發布和訂閱

目錄 簡介 步驟 1: 定義消息類 步驟 2: 創建發布者 步驟 3: 創建訂閱者 步驟 4: 實現發布-訂閱模型 前言-與正文無關 生活遠不止眼前的苦勞與奔波&#xff0c;它還充滿了無數值得我們去體驗和珍惜的美好事物。在這個快節奏的世界中&#xff0c;我們往往容易陷入工作的漩渦…