簡體   English   中英

基於微服務的架構中的最終一致性暫時限制了功能

[英]Eventual Consistency in microservice-based architecture temporarily limits functionality

我將用 Twitter 說明我的問題。 例如,Twitter 具有基於微服務的架構,這意味着不同的進程在不同的服務器上,擁有不同的數據庫。

一條新推文出現,服務器 A 在它自己的數據庫中存儲了一些數據,生成新事件並觸發它們。 此時服務器 B 和 C 沒有收到這些事件,也沒有在它們的數據庫中存儲任何內容,也沒有處理任何內容。

創建推文的用戶想要編輯該推文。 為了實現這一點,所有三個服務 A、B、C 都應該處理所有事件並將所有需要的數據存儲到數據庫中,但服務 B 和 C 還不一致。 這意味着我們目前無法提供編輯功能

正如我所看到的,一種可能的解決方法是切換到立即一致性,但這會剝奪所有基於微服務的架構優勢,並且可能會導致緊耦合問題。

另一種解決方法是在一段時間內限制用戶的操作,直到所有必要服務的數據不一致。 可能是一個解決方案,取決於客戶和他的業務需求。

另一種解決方法是添加額外的邏輯或可能的服務 D,將編輯存儲為用戶的操作,並僅在它們一致時將它們應用於數據。 缺點是非常增加了系統的復雜性。

並且有兩階段提交,但那是 1) 不太可靠 2) 慢。
我認為在 Twitter 有這種負載的情況下,緩慢是一個巨大的缺點。 但它可能是可以解決的,而可靠性的缺乏同樣不能不增加解決方案的復雜性。

所以,問題是:

  1. 有沒有什么好的解決方案可以解決所示的情況,或者只有我提到的解決方法? 也許一些編程平台或數據庫?
  2. 我是否誤解了某些內容並且某些解決方法不正確?
  3. 除了最終一致性之外,還有其他方法可以保證所有數據都將被存儲並且所有必要的操作將由其他服務執行嗎?

為什么為這個用例選擇了最終一致性 正如我所看到的,如果我們談論的是事件驅動的方法,當某些服務將在某些事件被觸發時開始工作,那么現在這是保證某些數據將被存儲或將執行某些操作的唯一方法,並且按照我的示例,該事件將是“tweet is created”。 因此,如果服務 B 和 C 出現故障,我需要能夠在它們再次啟動時成功執行操作。

我想實現的目標是:可靠性、承受高負載的能力、解決方案的足夠復雜性。 任何相關主題的任何鏈接將不勝感激。

如果這種方法有自然的局限性,並且使用這種范式無法實現我想要的東西,那也沒關系。 我只需要知道這個問題確實還沒有解決。

這都是關於權衡的。 在您的示例中使用最終一致性可能意味着用戶可能在幾秒鍾內無法編輯,因為大多數最終一致性技術不會花費太長時間來跨節點復制數據。 所以在這個用例中,這是絕對可以接受的,因為用戶的動作非常緩慢。

例如 :

MongoDB 默認是一致的:讀取和寫入都發給副本集的主要成員。 應用程序可以選擇從輔助副本讀取,默認情況下數據最終是一致的。

來自官方 MongoDB 常見問題解答

另一種越來越流行的替代方法是使用流媒體平台,例如 Apache Kafka,其中流消費者處理數據的速度(為了最終一致性)取決於您的架構設計。 由於流平台非常快,因此大多數情況下只能達到流處理器的速度才能在正確的位置提供數據。 因此,在大多數情況下,我們談論的是毫秒,甚至不是秒。

在這類架構中,關鍵是讓每個服務在寫入時都是自治的:即使其他應用程序級服務都沒有啟動,它也可以進行寫入。

因此,在類似 twitter 的服務的示例中,您可以將其建模為

Service A manages the content of a post

因此,當用戶發布帖子時,服務 A 的數據庫中會發生寫入,並且從那一刻起可以編輯帖子,因為編輯只是對 A 的請求。

如果有一些其他服務使用來自 A 的“發布內容”更改事件,並且在“新發布”事件公開某些功能之后,則在該服務看到該事件之前不會公開該功能(是同義反復)。 但這只是物理學:五分鍾前太陽可能已經變成超新星,我們不能采取任何行動(不是我們本來可以采取的),直到我們“看到光明”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM