關於 Apache Pulsar
Apache Pulsar 是 Apache 軟體基金會頂級專案,是下一代雲原生分散式訊息流平臺,集訊息、儲存、輕量化函式式計算為一體,採用計算與儲存分離架構設計,支援多租戶、持久化儲存、多機房跨區域資料複製,具有強一致性、高吞吐、低延時及高可擴充套件性等流資料儲存特性。
GitHub 地址:http://github.com/apache/pulsar/
本文作者為江謀晶,誼品生鮮高階研發工程師。主導資料管道系統的設計與研發,藉助 Apache Pulsar 作為資料同步工具,並落地實現增量資料同步的各種應用場景需求。他計劃進一步實現資料管道的平臺化及視覺化,並接入更豐富的資料庫型別支援。
背景
資料管道,就是讓資料通過一定的傳輸介質,從一個地點到達另一個地點,從而實現資料的同步或複製,來滿足應用需求。隨著業務量及資料量的的大幅增長,我們現有的微服務需要再度細化(拆分)。
系統拆分如何做到讓使用者無感知呢?上線時,通過分流策略將部分使用者引流到新的服務中,要求新老系統並行執行一段時間來支撐新服務的試執行到完全落地,從而最大程度上減少生產故障。為了讓新服務資料能夠與舊系統服務中的資料實時一致,就需要同步資料。隨著資料量大幅增長,要加快查詢速度,可以將資料複製到 ElasticSearch 中,提高查詢速率。
市場上有相關的開源資料同步產品和商業版資料通道工具,不需要人工介入即可實現雙邊的資料同步複製。但系統重構可能會發生一些表結構或表物件的變動,無法相容商業的資料同步,需要開發人員介入進行相關處理。我們採用了 Maxwell + Pulsar 的自研解決方案:使用 Maxwell 讀取 binlog,Pulsar 進行資料傳輸。Maxwell + Pulsar 實現上層的資料讀取,下游業務方實現對應的資料同步邏輯。比如,針對系統重構拆分的資料同步業務場景以及讀寫分離,將資料複製同步到類似 ElasticSearch 搜尋引擎中的業務場景。
為何選擇 Pulsar?
在資料管道的系統重構中,我們選擇 Apache Pulsar 的原因如下:
- 無狀態。微服務架構體系中,中介軟體最好是無狀態的。這樣啟動快,可以隨時替換並且可以實現無縫伸縮,彈性擴充套件。Kafka 不是無狀態的,每個 Broker 都包含了分割槽所有的日誌,如果一個 Broker 當機,並非任意一個 Broker 可以來接管,也不能隨意新增 Broker 來分擔負載,Broker 之間必須進行狀態同步。在 Pulsar 架構中,資料從 Broker 剝離,儲存在共享儲存內部;上層是上層是無狀態的計算層(Broker),複製訊息分發和服務(計算),下層則是持久化的儲存層( Bookie )。所以資料計算和儲存相互獨立,可以實現資料的獨立擴充套件和快速恢復。
- Pulsar 支援流處理和傳統的訊息佇列,大大提升了訂閱靈活度。
- Pulsar 雲原生的架構方便水平彈性擴充套件,且支援跨地域複製。
- Pulsar 支援分割槽,吞吐高,延遲低。
- 開源社群活躍,技術支援響應快、服務好。
Pulsar 如何保證分散式消費過程中的順序
首先,我們瞭解一下 Pulsar 的訂閱模式。Pulsar 有四種訂閱模式:exclusive 模式(獨佔模式)、failover 模式 (故障轉移模式)、Shared 模式 (共享模式)以及 Key_Shared 模式。Exclusive 模式只有一個消費者(consumer),接收一個 Topic 所有的訊息。
Failover 模式中,同一時刻只有一個有效的消費者,其餘的消費者作為備用節點,在主消費者(master consumer)不可用後進行替代(該模式適用於資料量小、解決單點故障的場景)。
Shared 模式中,多個消費者可以連線到同一訂閱主題。訊息以輪詢的方式分佈在各個消費者之間,任何給定的訊息僅傳遞給一個消費者。起初我們採用 Shared 模式,因為 Shared 模式具備分散式消費能力,消費速度快。但在生產過程中發現源資料庫資料與同步的目標庫(ElasticSearch、MySQL)頻繁出現資料偏差和資料不一致的問題。經排查發現,是消費順序錯亂導致的,當使用者頻繁操作某條資料產生了多條 MQ 訊息時,Shared 模式下,多個消費者並行消費訊息了。
Pulsar 在 2.4.0 版本基於 Shared 模式推出了 Key_Shared 模式。在 Key_Shared 模式下,多個消費者可以附加到同一訂閱。訊息在各個使用者之間進行分發,具有相同 key 或相同訂購 key 的訊息僅投遞給一位消費者,不管訊息重新傳送多少次,它都會被髮送到同一使用者。當消費者連線或斷開連線時,服務的消費者會更改某些訊息 Key(密匙)。Key_Shared 模式保證在 Shared 模式下同一個 Key 的訊息會傳送到同一個消費者,在併發的同時保證順序性。
資料同步場景對訊息的順序要求非常高。當使用者不斷更新某條資料時,資料庫表中對應的記錄也在不斷更新。資料量大高併發時,需要保證使用者變更資料產生的訊息順序與其操作順序一致,否則會出現同步的該條資料與源資料不一致,產生系統故障。
順序問題是分散式消費過程中常見的問題。為了保證客戶端的有序消費,我們採用 Key_Shared 訂閱模式。Key_Shared 模式是 Shared 訂閱模式擴充,一個分割槽可以有幾個消費者並行消費訊息,但具有相同 key 的訊息只路由給一個消費者。其原理是通過雜湊來確定目標使用者,每個消費端提供固定範圍的雜湊值;雜湊值的整個範圍可以覆蓋所有的消費端。然後生產訊息時指定 key(如下所示),形成閉環,就可以實現有序的存放至指定的分割槽以及訊息有序的消費。具體原理及用法可以參考 Pulsar 官網 。
key :{"database":"you_db_name","table":"you_table_name","pk.id":"you_table_Primary key"}
如何過濾重複訊息?
訊息的傳輸保障一般有三種:At least once、At most once 和 Exactly once。
- At least once:每條訊息會進行多次傳輸嘗試,至少成功一次,即訊息可能重複但不會丟失;
- At most once:每條訊息最多傳輸一次,訊息可能會丟失;
- Exactly once:每條訊息只傳輸一次,訊息傳輸既不會丟失也不會重複。
在資料同步場景下,要最大化保證訊息的可達性,我們運用 Maxwell 的 At least once 模式,儘可能保證訊息傳輸。在網路不理想時,訊息可能已經投遞至目標,但接收到超時響應或者未接收成功,Pulsar 會再次投遞,從而產生了“重複訊息”。
為了解決重複訊息的問題,我們在資料管道資料鏈路模型中增加了過濾器,過濾一些重複、無效、重試的訊息。
總結
在需要同步大量增量資料的場景下,我們採用了 Maxwell + Pulsar 的自研解決方案,Pulsar Key_Shared 訂閱模式能否很好解決分散式訊息消費過程中的順序問題,在資料管道資料鏈路中增設過濾器,能保證訊息不重不漏。
後續我們計劃基於現有的解決方案,充分利用 Pulsar 的特性,將資料管道做成視覺化的資料同步中臺,接入更多的資料庫擴充套件、完善的監控和日誌體系。
相關閱讀
點選 連結 ,獲取 Apache Pulsar 硬核乾貨資料!