四年運維生產經驗分享:Nordstrom的事件溯源系列之一

banq發表於2019-08-06

在Nordstrom,我們一直在探索一種特定型別的近實時資料流,稱為事件溯源/事件採購,通過結合開源專案和過去四年運維生產的功能。在此過程中,我們學到了很多東西,並希望分享我們所看到的一些機會。

什麼是事件溯源,我為什麼要關心?

在事件源架構中,整個系統的單一事實來源是有序事件分類帳(通常也稱為日誌,日誌,流(在運動時)或表(在靜止時))記錄現實世界的事件 、 觀察或決定的一切。只使用事件分類帳可以確定性地恢復所有應用程式及其檢視的應用程式狀態。

事件記錄事件發生時真實的事實,代表世界上發生的事物,並與業務相關並被其理解。例如:“週一下午3:16,SKU J012以200美元的價格售出給客戶31337。”

消費應用程式從分類帳中讀取並記錄或處理資料。一個常見的用例是生成RESTful請求 - 響應API(如“Inventory”或“Catalog”)所面向的資料的特定於領域的只讀聚合檢視。

我們從事件源架構中看到的好處包括:

  • 提高資料質量:由於您使用與業務功能團隊相同的事件進行分析,因此可大大提高機器學習和分析資料的質量。
  • 可重構的架構:您的技術設計更貼近現實世界中的技術設計,使您的技術架構更加一致,更易於理解您的業務團隊(“當這個,然後那個”)。
  • 快速反應:近乎實時(約2秒)對系統中任何位置發生的任何事情做出反應,複雜性降低。
  • 可擴充套件性:可輕鬆擴充套件到每秒數十萬個事件,並增加數百個事件使用者。
  • 業務連續性:讓每個消費者按照自己的節奏從分類賬中讀取消除背壓,併為保護下游系統和從停機中恢復創造一個自然的斷路器機會。
  • 服務供應:強大的服務解耦縮短了新服務的上市時間或舊服務的更改,包括在實時生產資料上並行執行多個版本或多個完整服務。這使您可以輕鬆遷移到新服務並丟棄舊服務(“資料庫為牛”)。
  • 技術不可知:事件不依賴於其源系統的任何技術細節,並且對業務人員來說是可以理解的,通過向任何團隊提供完整的系統知識來增加自主性(“事件不知道它們來自大型機”)。
  • 歷史記錄:建立稽核或重放歷史記錄的機會,允許重新建立歷史狀態以進行除錯或災難恢復。
  • 供應商不可知:通過在另一個服務提供商的雲中複製事件分類賬或者在預置位置上/下來減少供應商鎖定的幽靈。
  • 設定一個高標準:每個額外的消費者通過提高生產者資料質量和新鮮度的要求來推動質量進入流,從而創造一個每個人都受益的良性迴圈。

你能給我一個事件源系統的例子嗎?

當然!想想下棋。傳統的資料庫相當於正在進行的遊戲的拍照 , 從某個時刻拍下的快照,你可以看到所有作品的位置和正在玩的人,你可以計算出誰贏得勝利的概率。將其與事件源的國際象棋系統進行對比,其中焦點在於將所有單獨的移動記錄到分類帳上(在國際象棋中,稱為移動記錄符號)。對於每次移動,我們在分類帳中看到一個條目,其中包含表格編號,遊戲編號,移動作品的玩家姓名,移動的日期和時間以及移動的結果(例如,如果捕獲了任何碎片) )。

由於可以訪問所有動作的分類帳,您可以在遊戲中的任何位置(事件源架構的黃金標準)完全恢復遊戲狀態。您還可以輕鬆地為您的系統新增功能,如國際象棋時鐘,錦標賽經理,作弊檢測,玩家分析,國際象棋教練,用於檢測最有趣的遊戲以進行評論或突出顯示的系統等等。

事件源和無伺服器架構

無伺服器函式基本上是事件驅動的。觸發無伺服器函式有兩種基本方法:直接呼叫,或間接,基於世界上發生的事情。第二種方法可用於在每次發生事件時將強大的事件序列連結在一​​起 - 您可能會想到一個(有用的)Rube Goldberg機器。

一旦您對事件觸發的生態系統感到滿意,就很自然地需要一種以可靠和強大的方式跟蹤,維護和處理這些事件的方法。事件分類帳(無伺服器處理)為您提供此功能。如果你以一種強大的方式使用無伺服器系統,我預測你很可能很快會深入思考事件源架構(如果你還沒有)。

事件溯源和物聯網

在物聯網系統中,感測器(如溫度或光感測器)是事件生產者,而執行器(如燈或鎖)是事件消費者。此外,這些感測器和執行器通常依賴於不可靠的網路連線。分類帳是處理偶爾連線(或離線優先)方案並確保系統保持一致的強大工具。許多物聯網生態系統在幕後使用分類賬來處理離線情景。CRDT(融合資料型別)是確保偶爾連線裝置之間資料融合的另一個迷人方向,值得整篇部落格釋出。

我們來定義一些術語

我們將在本系列中使用許多技術術語,其中一些具有多個應用程式。我們來定義一些術語:

1. 分散式分類帳/統一日誌/日誌/流

特定事件的地方(例如:在此日期和時間,Rob以這種方式編輯文件。)按照收到的順序寫下來。分類帳僅附加(在最後寫入新事件)和不可變(用“筆”寫,永不改變)。它通常是分散式的,因為它被複制以獲得永續性並進行分割槽以實現可伸縮性。

2.分類帳

為了劃分處理事件流的工作,使用與稱為分割槽鍵的每個事件相關聯的特定屬性將分類帳分成單獨的分割槽(有時稱為分片)。

3.分割槽鍵

事件中的派生或分配欄位,用於標識最重要的排序事件的主題。(例如:如果客戶名稱/ ID用作分割槽鍵,則同一客戶的所有操作將由所有事件使用者以一致的順序處理。banq注:如果以DDD聚合設計,同一類聚合放入一個分割槽,因為聚合中的事件都必須以順序排序,類似資料庫一個庫)

4. 碎片/分割槽

一個簡單的真實世界分割槽示例可能是:由姓氏的第一個字母(例如:AG,HN,OU,VZ)拆分的老式的大學課程註冊日事件中的多個物理表。每個表(以及通向它的行)相當於分割槽或分片。通過使用事件的鍵值作為分割槽,分割槽標記作為發出事件的位置。

5. 在分割槽鍵中排序保證

在每個分割槽鍵中,我們可以保證所有事件都是有序的(Rob做A,然後是B,然後是C)。但是我們不能保證跨越分割槽鍵的排序(在Rob做C之前,Grace先做過D嗎?)。鍵之間的排序也是至關重要的,因為它允許我們讓多個不同的讀者在閱讀分類帳的任何時候都得出相同的結論。這在消費者之間提供了分散式共識,而不需要他們彼此交談。

6.事件釋出者和消費者

分別來自流的事件的傳送者和接收者。或者在物聯網環境中,系統的感測器(溫度,光檢測器,按鈕等)和執行器(電動機,顯示器,燈等)。另一種替代命名/思維方式是現實的觀察者和解釋者。

7.事件使用者的偏移/分類帳位置

消費者在流的一個或多個分片中讀取的位置。它表示消費者成功處理流的程度以及應該在何處恢復處理。

8.物化檢視/只讀聚合/直寫快取記憶體

當消費者從事件流中讀取並建立有狀態物件(如NoSQL資料庫表)時,它正在建立事件流的“物化檢視”。這方面的一個例子就是我們上面討論過的棋盤圖片。所有的遊戲移動都依據分類賬更新,並且每個快照圖片成為系統的一個物化檢視。單獨的物化檢視可以是整數陣列,表示每個玩家的國際象棋時鐘剩餘秒數。

9. 邏輯時鐘

邏輯時鐘指的是讀取器在分類帳中的位置,就其讀取位置從開頭的偏移量而言。這是一種相對的因果時間感。“通過分類帳位置2718,我們為慈善機構籌集了1,000美元。”使用任意當前物理時間概念的掛鐘時間表達是:“根據我的觀察,下午12:15我們為慈善機構籌集了1000美元。”這兩者是不同的,使用邏輯時鐘時間對於分類賬是確定性的,因為許多原因,掛鐘時間可能會有問題。(時區,漂移,閏秒,時鐘調整導致及時跳過)

10. 向量時鐘/向量時鐘

向量時鐘指的是讀取器跨多個分類帳的位置(這些分類帳可以是單個主題的多個分割槽/分片)。Slack中的一個示例 -:您在所訂閱的所有頻道中讀取的訊息偏移集合形成了您已消費內容的向量時鐘。在此示例中,使用向量時鐘(以及其他內容)來確定您是否有未讀訊息。(banq注:從客戶端角度看)

11. 最終的一致性

如果當您結束了所有的修改後,所有參與者都會得到相同的結果,那麼系統最終會保持一致。例如,當我在信用卡上收取一些費用時,銀行餘額不會立即更新,但我相信它最終會更新。這與強烈的一致性相反,每個參與者總是會有相同的結果。

 

相關文章