Airbnb的變更資料捕獲系統,實現資料突變實時響應

大資料文摘發表於2018-09-25

乾貨前的小情景劇:

小長假馬上就要到啦!Karim決定要好好享受這個假期。他登陸Airbnb為去舊金山的旅行訂房間,偶然發現Dany登出的好房子,這可真是太好啦。

沒過一會兒,Dany收到了房間被預定的提示。他檢查了下日程表,確定自己已經把這些日期預留了出來。也注意到那個時段房間的推薦價格上漲了一些。“這個假期一定有很多人來舊金山玩兒啊”,他自言自語道。Dany把這個周其他幾天的房間也顯示可用。

這時在美國另一邊的東海岸,Sara正在位於曼哈頓切爾西區的公寓裡喝茶,為她去舊金山公司總部的商務旅行做準備。她在Airbnb上找了一會兒房子,並沒有看到什麼好的,正打算休息的時候,看到Dany的房間出現在了搜尋頁面上。看了看介紹,Sara覺得這個房間太適合了!她馬上給Dany發了訊息:“親愛的Dany,我要去舊金山旅行,你的房間看起來非常棒…”

在過去的幾年中,適應資料演變已經成為Airbnb許多新興應用的經常需求。上面的場景是個很好的示例,其中動態定價,房間可用性和預留工作流需要近乎實時地響應系統中不同部分的變化。

從基礎架構的角度來看,設計我們的架構以擴充套件是必要的,因為我們的資料和服務數量不斷增長。然而,作為努力面向服務架構的一部分,在微服務之間傳播有意義的資料模型突變的有效方式同時保持保留資料所有權邊界的解耦架構同樣重要。

作為迴應,我們創造了SpinalTap;一種可擴充套件,高效能,可靠,無損的變更資料捕獲(CDC)服務,能夠檢測跨不同資料來源型別的低延遲的資料突變,並將它們作為標準化事件傳播給下游的消費者。SpinalTap已經成為Airbnb基礎架構和衍生資料處理平臺中不可或缺一部分,幾個關鍵應用流水線都依賴於此。在這篇文章中,我們將概述它的系統體系結構,使用案例,效能保證以及它是怎樣擴充套件的。

背景介紹

變更資料捕獲(CDC)是一種設計模式,可以捕獲資料更改並通知參與者,以便他們做出相應的反應。這遵循釋出--訂閱模型,其中資料集的更改是關鍵。

系統要求

我們的這些使用案例需要該系統擁有這些高階要求:

  • 無損:對資料丟失零容忍,這是針對基於流的會計審計應用程式的需求

  • 可擴充套件性:水平擴充套件以適應日益增長的負載和資料叢集,以避免隨著增長重複設計系統

  • 效能:變更近乎實時地反饋給訂閱的使用者(亞秒級)

  • 一致性:強制維持排序和時間線一致性以保留特定資料記錄的更改順序

  • 容錯:具有可配置的冗餘度,可以抵禦故障

  • 可延伸性:可適應不同資料來源和接收器型別的通用框架

曾考慮過的解決方案

文獻中有用於構建CDC系統的幾種解決方案,其中最常用是:

  • 輪詢:通過跟蹤狀態屬性(例如上次的更新或版本),可以使用時間驅動策略定期檢查是否已將任何更改記錄在資料儲存中

  • 觸發器:對於支援資料庫觸發器的儲存引擎(例如:MySQL),它們是基於行觸發儲存過程,可以以無縫方式將更改傳播到其他資料表

  • 雙重寫入:在請求期間,資料更改可被傳遞給應用程式層中的訂閱消費者,例如通過發出事件或在寫入提交後排程RPC

  • 審計跟蹤:大多數資料儲存解決方案使用事務日誌(或更改日誌)來記錄和跟蹤提交到資料庫的更改。這通常用於群集節點之間的複製和恢復操作(例如意外伺服器關閉或故障轉移)

使用資料庫更改日誌來檢測更改有幾個好處:與觸發器和輪詢策略相比,從日誌中讀取允許採用非同步非侵入式方法來捕獲更改。它還支援提交時的強一致性和排序保證,並保留事務邊界資訊,這兩點都是雙寫操作無法實現的。它允許從特定時間點重放事件。考慮到這一點,SpinalTap是基於此設計的。

構架

Airbnb的變更資料捕獲系統,實現資料突變實時響應工作流程概述

在高層次上,SpinalTap被視為一個通用解決方案,它抽象了變更捕獲工作流程,足以輕鬆適應不同的基本架構(資料儲存,事件匯流排,客戶服務)。該方案由3個主要元件構成,有助於實現這些特性:

來源

Airbnb的變更資料捕獲系統,實現資料突變實時響應

左圖:源元件圖;右圖:源事件工作流程

源表示來自特定資料儲存的變更事件流的來源。只要有可訪問的更改日誌來流式傳輸事件,就可以使用不同的資料來源型別輕鬆擴充套件源抽象。從更改日誌解析的事件將被過濾,處理並轉換為相應的突變。

突變是應用程式層級的,表示資料實體的單個更改(插入,更新或刪除)。它包括更改前後的實體值,唯一識別符號,事務資訊和來自源事件的後設資料。源還負責檢測資料模式演變,並借用相應的突變傳播模式資訊。這對於確保在客戶端反序列化實體值或從早期狀態重放事件時的一致性非常重要。

目的地

Airbnb的變更資料捕獲系統,實現資料突變實時響應左圖:目的地元件圖;右圖:目的地事件工作流程

在處理並轉換為標準化事件之後,目標表示突變的接收器。目的地還跟蹤最後成功釋出的突變,該突變用於將源狀態位置匯出到檢查點。該元件抽象出所使用的傳輸介質和格式。在Airbnb,Apache Kafka作為活動匯流排,在基礎設施中廣泛使用。Apache Thrift被用作資料格式,定義標準化的變異模式並提供跨語言支援(Ruby和Java)。

通過對系統進行基準測試確定了主要瓶頸是變異釋出。考慮到系統設定有利於延遲的強一致性,這種情,我們採用了一些優化措施:

Airbnb的變更資料捕獲系統,實現資料突變實時響應

緩衝目標:為了避免在等待發布突變時阻塞源,我們使用記憶體中有界佇列來緩衝從源發出的事件(消費者-生產者模式)。當目標釋出突變時,源將向緩衝區新增事件。一旦可用,目標將從緩衝區中提取事件並處理下一批突變。

Airbnb的變更資料捕獲系統,實現資料突變實時響應

目標池:對於在傳入事件速率中顯示不穩定尖峰行為的源,記憶體緩衝區偶爾會飽和,從而導致效能的間歇性降級。為了減輕系統的不規則負載模式,我們將源事件的應用程式級分割槽應用於由執行緒池管理的一組可配置的緩衝目標。事件多路複用到執行緒目標,同時保留排序模式。這使我們能夠實現高吞吐量,同時不會影響延遲或一致性。

管道


Airbnb的變更資料捕獲系統,實現資料突變實時響應

左:管道元件圖;右:管道管理者協調管道生命週期

管道協調給定源和目標之間的工作流程。它代表了並行的基本單位。它還負責定期檢查源狀態,並管理事件流的生命週期。如果出現錯誤行為,管道將執行正常關閉並啟動故障恢復過程。根據最後的狀態檢查點,採用保持活動機制來確保在發生故障時重新啟動源流。這允許在保持資料完整性的同時自動修復間歇性故障。管道管理器負責在給定的叢集節點上建立,更新和刪除管道以及管道生命週期(啟動/停止)。它還確保在執行時相應地傳播對管道配置的任何更改。

叢集管理

Airbnb的變更資料捕獲系統,實現資料突變實時響應

左圖:叢集資源管理;中圖:節點故障恢復;右:使用例項標記進行隔離

為了實現某些理想的體系結構方面-例如可擴充套件性,容錯性和隔離性-我們採用了一個叢集管理框架(Apache Helix)來協調跨計算資源的流處理分佈。這有助於我們實現確定性負載平衡,並通過叢集中源處理器的自動重新分配實現水平擴充套件。

為了通過可配置的容錯來提升高可用性,每個源都被指定為叢集節點的某個子集來處理事件流。我們使用Leader-Standby狀態模型,其中只有一個節點在任何給定點流式傳輸來自源的事件,而子群集中的其餘節點處於待命狀態。如果領導者關閉,那麼其中一個備用節點將擔任領導。

為了支援源型別處理之間的隔離,群集中的每個節點都標記有可以委派給它的源型別。流處理跨群集節點分佈,同時保持此隔離標準。

為了解決來自網路分割槽的不一致性,特別是在多個節點承擔來自特定源(分裂腦)的流式傳輸的領導的情況下,我們維持每個源的全域性領導者時期,其在領導者轉換時原子遞增。隨著每個突變傳播領導者時代,並且通過忽略具有比觀察到的最新時期更小的時期的事件,通過客戶端過濾來減輕不一致性。

保證

某些保證對於系統維護是必不可少的,以適應所有下游用例。

資料完整性:系統保持至少一次交付保證,其中對底層資料儲存的任何更改最終都會傳播到客戶端。這表明更改日誌中不存在任何事件永久丟失,並且是在SLA指定的時間視窗內傳遞。我們確保不會發生資料損壞,並且突變內容保持源事件的奇偶校驗。

事件排序:根據規定的分割槽方案強制執行排序。我們維持每個資料記錄(行)的排序,即給定資料庫表中特定行的所有更改都將按順序接收。

時間線一致性:在時間線上保持一致要求在給定時間範圍內按時間順序接收變化,給定變異集的兩個序列在傳送過程中不可交錯。裂腦情景可能會影響這種保證,但如前所述,它可以通過紀元圍欄得到緩解。

Validation

Airbnb的變更資料捕獲系統,實現資料突變實時響應SpinalTap驗證框架

證明SpinalTap在設計方面的保證沒有出現事故是不夠的,我們需要一種更實用的資料驅動方法來驗證我們的假設。為了解決這個問題,我們開發了一個連續的線上端到端驗證管道,負責驗證消費者在真實來源上收到的突變,並斷言在預生產和生產環境中都沒有檢測到錯誤的行為。

為了實現可靠的驗證工作流,消耗的突變被分割槽並儲存在本地磁碟上,同樣的分割槽方案應用於源事件。一旦接收到對應於分割槽事件的所有突變,就通過宣告前面描述的保證的測試列表來驗證分割槽檔案與原始源分割槽。特別是對於MySQL,binlog檔案被認為是一個乾淨的分割槽邊界。

我們在沙箱環境中設定了離線整合測試,以防止將回歸部署到生產環境中。驗證器也通過為每個源流消費實時事件線上生產。這有助於檢測未在我們的測試管道中捕獲的任何漏洞,並通過將源狀態回滾到先前的檢查點來自動修復。這強制了在解決任何問題之前不會繼續流式傳輸,並最終保證一致性和資料完整性。

模型突變

Airbnb的變更資料捕獲系統,實現資料突變實時響應

左圖:同步與非同步應用程式工作流程; 右圖:將模型突變傳播給下游消費者

消費者服務直接攻擊給定服務資料庫的SpinalTap事件的缺點是資料模式洩露,從而產生不必要的耦合。此外,用於處理封裝在擁有服務中的資料突變的域邏輯也需要複製到消費者服務。

為了緩解這種情況,我們在SpinalTap之上構建了一個模型流媒體庫,它允許服務從服務的資料儲存中偵聽事件,將它們轉換為域模型突變,並在訊息匯流排中重新注入它們。這有效地允許資料模型突變成為服務介面的一部分,並且請求/響應週期與非同步資料攝取和事件傳播的隔離。它還有助於解耦域依賴關係,促進事件驅動的通訊,並通過隔離同步和非同步應用程式工作流來提供服務的效能和容錯改進。

使用案例

SpinalTap用於基礎架構中的許多用例,其中最突出的是:

快取記憶體失效:CDC系統的常見應用是快取記憶體失效,其中後備資料儲存的更改由快取記憶體無效器服務或程式檢測,從而驅逐(或更新)相應的快取記憶體條目。優先採用非同步方法允許我們將快取機制與請求路徑以及為生產流量提供服務的應用程式程式碼分離。這種模式在服務中廣泛使用,以保持真實資料來源儲存和分散式快取叢集(例如Memcached,Redis)之間的一致性。

搜尋索引:Airbnb上有多個搜尋產品使用實時索引(例如,評論搜尋,收件箱搜尋,支援票搜尋)。SpinalTap被證明非常適合構建從資料儲存到搜尋後端(例如ElasticSearch)的索引管道,特別是它的有序和至少一次傳遞語義。服務可以輕鬆地使用相應主題的事件並轉換突變以更新索引,這有助於確保搜尋新鮮度和低延遲。

離線處理:SpinalTap還用於以流方式將線上資料儲存匯出到離線大資料處理系統(例如Hive,Airstream),這需要高吞吐量,低延遲和適當的可擴充套件性。該系統在歷史上也用於資料庫快照管道,連續構建線上資料庫的備份並將它們儲存在HBase中。這大大減少了每日備份的時間,並允許以更精細的時間粒度(例如:每小時)拍攝快照。

信令:用於在分散式體系結構中傳播資料變化的另一個經常性用例是作為信令機制,其中依賴服務可以近實時地訂閱並響應來自另一服務的資料變化。例如,可用性服務將通過訂閱預訂服務中的更改來阻止列表的日期,以便在預訂時收到通知。風險,安全,支付,搜尋和定價工作流程是我們的生態系統中採用此模式的幾個示例。

結語

在過去幾年中SpinalTap已成為我們基礎架構不可或缺的一部分,併為許多核心工作流程提供了動力。如果是尋求可以與您的基礎架構輕鬆整合的可靠通用框架,它很實用。在Airbnb,SpinalTap用於傳播來自MySQL,DynamoDB和我們內部儲存解決方案的資料突變。Kafka是首選事件匯流排,但系統的可擴充套件性也允許我們考慮其他媒介(例如:Kinesis)。

相關文章