雙重寫入:如何解決微服務分散式系統中資料不一致? - Thorben
由於許多新應用程式是作為微服務系統構建的,因此雙重寫入已成為一個普遍的問題。它們是導致資料不一致的最常見原因之一。更糟的是,許多開發人員甚至都不知道雙重寫入是什麼。
什麼是雙重寫入?
雙重寫入描述了您在兩個個系統(例如資料庫和Apache Kafka)中更改資料時的情況,而沒有額外的層來確保兩個服務上的資料一致性。
只要兩個操作都成功,一切就OK了。即使第一筆交易失敗,也還是可以的。但是,如果您成功提交了第一筆交易而第二筆交易失敗,則說明您遇到了問題。您的系統現在處於不一致狀態,沒有容易修復的方法。
分散式事務不再是一種選擇
過去,當我們構建整體/.單體/Monolith時,我們使用分散式事務來避免這種情況。分散式事務使用兩階段提交協議。它將事務的提交過程分為兩個步驟,並確保所有系統的ACID原則。
但是,如果我們要構建微服務系統,則不會使用分散式事務。這些交易需要鎖,並且無法很好地擴充套件。他們還需要所有涉及的系統同時啟動和執行。
那你該怎麼辦呢?
3個無效的“解決方案”
當我在會議演講中或在一個研討會上與與會者討論此主題時,我經常聽到以下3條建議之一:
- 是的,我們知道此問題,我們沒有解決方案。但這還不錯。到目前為止,什麼都沒有發生。讓我們保持原樣。
- 讓我們將與Apache Kafka的互動移動到提交後監聽器。
- 在提交資料庫事務之前,讓我們將事件寫入Kafka中的主題。
好吧,很明顯,建議1的風險很大。它可能在大多數時間都有效。但是遲早,您將在服務儲存的資料之間建立越來越多的不一致之處。
因此,讓我們集中討論選項2和3。
2. 在提交後監聽器中釋出事件
在提交後監聽器中釋出事件是一種非常流行的方法。它確保僅在資料庫事務成功時才釋出事件。但是,很難解決Kafka崩潰或任何其他原因阻止您釋出事件的情況。
您已經提交了資料庫事務。因此,您無法輕鬆地還原這些更改。當您嘗試在Kafka中釋出事件時,其他事務可能已經使用並修改了該資料。
您可能會嘗試將故障保留在資料庫中,並執行常規的清理作業以嘗試恢復失敗的事件。這可能看起來像是一個合理的解決方案,但是它有一些缺陷:
- 僅當您可以將失敗的事件保留在資料庫中時,它才有效。如果資料庫事務失敗,或者您的應用程式或資料庫崩潰,然後才能儲存有關失敗事件的資訊,則將丟失它。
- 僅當事件本身沒有引起問題時,它才起作用。
- 如果在清除作業恢復失敗的事件之前,另一個操作為該業務物件建立了一個事件,則事件將混亂。
這些似乎是假設的情況,但這就是我們正在準備的事情。本地事務,分散式事務和確保最終一致性的方法的主要思想是,絕對要確保您不會造成任何(永久)不一致。
提交後偵聽器無法確保這一點。因此,讓我們看一下其他選項。
3. 在提交資料庫事務之前釋出事件
在討論了為何提交後監聽器不起作用之後,通常會建議使用這種方法。如果在提交之後釋出事件會導致問題,您只需在提交事務之前釋出它,對嗎?
好吧,不……讓我解釋一下……
如果您無法釋出事件,則在提交事務之前釋出事件使您可以回滾事務。那就對了。
但是,如果資料庫事務失敗,該怎麼辦?
您的操作可能違反唯一約束,或者同一資料庫記錄上可能有2個併發更新。提交期間將檢查所有資料庫約束,並且不能確保它們都不會失敗。資料庫事務也彼此隔離,因此如果不使用鎖,就無法阻止併發更新。但這帶來了新的可伸縮性問題。簡而言之,您的資料庫事務可能會失敗,並且您無能為力,或者對此無能為力。
如果發生這種情況,則您的活動已經發布。其他微服務可能已經觀察到它並觸發了一些業務邏輯。您無法撤回活動。
如前所述,撤消操作失敗的原因相同。您也許可以構建一個大多數情況下都可以使用的解決方案。但是您無法建立絕對安全的東西。
如何避免雙重寫入?
您可以選擇幾種方法來避免雙重寫入。但是您需要知道,如果不使用分散式事務,則只能構建最終一致的系統。
總體思路是將流程分為多個步驟。這些步驟中的每個步驟僅適用於一個資料儲存,例如資料庫或Apache Kafka。這使您能夠使用本地事務,所涉及系統之間的非同步通訊以及非同步的,可能無限的重試機制。
如果您只想在服務之間複製資料或通知其他服務已發生事件,則可以將發件箱模式與Debezium等變更資料捕獲實現一起使用。我在以下文章中詳細解釋了這種方法:
而且,如果您需要實施涉及多個服務的一致的寫入操作,則可以使用SAGA模式。我將在以下文章之一中對其進行詳細說明。
結論
雙重寫入常常被低估,許多開發人員甚至都不知道潛在的資料不一致。
如本文所述,在沒有分散式事務或確保最終一致性的演算法的情況下,寫入2個或更多系統可能會導致資料不一致。如果使用多個本地事務,則無法處理所有錯誤情況。
避免這種情況的唯一方法是將通訊分為多個步驟,並且在每個步驟中僅寫入一個外部系統。SAGA模式和變更資料捕獲實現(例如Debezium)使用這種方法來確保對多個系統的一致寫入操作或將事件傳送到Apache Kafka。
相關文章
- 分散式系統中資料儲存方案實踐分散式
- 「和耳朵」聊聊微服務與分散式系統微服務分散式
- 如何解決 Windows 和 Manjaro 雙系統時間不一致WindowsJAR
- 隨行付微服務之分散式檔案系統微服務分散式
- 分散式與微服務分散式微服務
- 分散式系統(三)——分散式事務分散式
- 微服務架構及分散式事務解決方案微服務架構分散式
- 如何解決分散式系統中的“幽靈復現”?分散式
- 分散式訊息系統如何解決訊息的順序&重複兩大硬傷?分散式
- ZooKeeper分散式專題與Dubbo微服務入門分散式微服務
- 微服務分散式事務4種解決方案實戰微服務分散式
- PHP 微服務之【分散式事務】PHP微服務分散式
- PHP 微服務之 [分散式事務]PHP微服務分散式
- 微服務架構下分散式事務解決方案-hoop(一)微服務架構分散式OOP
- 微服務分散式事務解決方案-開源軟體seata微服務分散式
- 微服務之分散式配置中心微服務分散式
- 微服務分散式企業框架微服務分散式框架
- 微服務分散式事務元件 Seata(一)微服務分散式元件
- 微服務分散式事務Saga框架微服務分散式框架
- 使用微服務前必須要了解的“分散式系統的謬誤”微服務分散式
- 分散式/微服務必配APM系統,SkyWalking讓你不迷路分散式微服務
- micro/micro:分散式微服務雲作業系統分散式微服務作業系統
- spring cloud微服務分散式雲架構-Gateway入門SpringCloud微服務分散式架構Gateway
- spring cloud微服務分散式雲架構-Spring Cloud 分散式的五大重點SpringCloud微服務分散式架構
- 安裝win10系統後重啟不能正常進入系統如何解決Win10
- 分散式檔案上傳(微服務)分散式微服務
- 分散式、微服務、叢集,個人理解分散式微服務
- 使用分散式Actor實現微服務分散式微服務
- 微服務架構 | 11. 分散式事務微服務架構分散式
- 分散式系統的資料一致性問題,你是如何解決的分散式
- Java微服務下的分散式事務介紹及其解決方案2Java微服務分散式
- 分散式系統事務一致性解決方案分散式
- 分散式、微服務必須配個日誌管理系統才優秀,Exceptionless走起~~~分散式微服務Exception
- 讀構建可擴充套件分散式系統:方法與實踐08微服務套件分散式微服務
- 一種分散式預寫日誌系統分散式
- PHP 微服務之 [分散式事務] 閱讀提示PHP微服務分散式
- PHP 微服務之【分散式事務】閱讀提示PHP微服務分散式
- 微服務實踐之分散式定時任務微服務分散式