實時數據訂閱與分發系統能夠將業務數據源變動實時分發分發到消息總線上,並維護消息的統一格式,提供通用的客戶端框架供消息生產者與下游業務接入。git
通常能用於如下場景:github
索引構建:MySQL到ES數據庫
緩存管理:MySQL到Redis或本地cache緩存
數據庫鏡像架構
實時備份併發
價格變化等重要業務信息訂閱框架
實時數據訂閱與分發系統通常都有以下幾個核心模塊構成:ide
本文以Databus(
https://github.com/linkedin/databus)爲例,來講明一個實時數據訂閱與分發系統的基本構成與原理。性能
Databus 是一個實時的低延遲數據抓取系統, 它抓取業務數據源的實時變動, 併發送到中繼(Databus Relay), 下游業務從中繼得到變動數據進行業務處理:spa
根據Linkdin的介紹, Databus有如下特性:
來源獨立:Databus支持多種數據來源的變動抓取,包括Oracle和MySQL。
可擴展、高可用:Databus能擴展到支持數千消費者和事務數據來源,同時保持高度可用性。
事務按序提交:Databus能保持來源數據庫中的事務完整性,並按照事務分組和來源的提交順序交付變動事件。
低延遲:數據源變動完成後,Databus能在微秒級內將事務提交給消費者。
無限回溯:Databus對消費者支持無限回溯能力。當消費者須要產生數據的完整拷貝時(好比新的搜索索引), 直接進行一次全量回溯便可。
Databus的結構與工做流以下圖:
經過CDC訂閱數據庫變動
將變動消息放入Relay的緩存隊列
各個client對隊列中的消息進行消費
咱們能夠看到,核心組件爲五個部分:
1)DatabusEventProducer
負責實時數據抓取CDC, 針對MySQL數據源, 開源方案提供了基於OpenReplicator(一個Binlog解析框架)的方案。
2)SchemaRegistry
註冊DatabusEvent對應的Schema, 全部DatabusEvent須要按Schema進行序列化, 並在消息中保持Schema信息。
3)DatabusRelay
基於Netty實現的一個Server, 內部維護高性能的緩存消息隊列RingBuffer,做爲訂閱消息的內存消息中間件,保證了消息的有序性。
4)BootstrapService
BootStrapService是特殊的DatabusClient, 它未來自DatabusRelay中的全部數據寫入MySQL, 當客戶端須要無限回溯時, 便請求BootstrapService拉取歷史數據。
有不少系統是將消息直接投遞到kafka或者rocketMQ,就能同時實現了DatabusRelays和BootstrapService的功能。
5)ClientLib:
ClientLib就是消費客戶端Client,用來實時接收變動消息。其中封裝了一些數據抓取細節, 好比當回溯的SCN(System Change Number)在中繼上不存在時自動請求BootstrapService, 回溯完成後切回中繼。
DatabusRelay
DatabusRelay模塊可類比爲基於內存實現的消息隊列, 下面是DatabusRelay的結構圖:
咱們能夠看到,DatabusRelay運行於Netty容器中。
同時,它會啓動一系列EventProducer, 從數據源或其餘Relays拉取實時增量數據並寫入EventBuffers。
EventBuffers由多RingBuffer組成, RingBuffer經過mmap進行寫盤持久化。這種設計下,使得EventProducer與DatabusRelay在同一個Netty容器中, 避免了rpc調用,效率更高。
全部的增量數據, 都有一個System Change Number(SCN), 這個SCN由EventProducer產生, 保證全局遞增, DatabusRelay須要記錄每一個RingBuffer目前的MaxSCN(相似Kafka的offset), 並使用MaxSCN Reader/Writer進行持久化。持久化方式是本地文件存儲。
DatabusClient
DatabusClient用於消費來自DatabusRelay的數據, 它做爲一個lib提供給須要接入的服務。下面是官方給出的DatabusClient架構圖:
客戶端代碼以回調形式註冊到DatabusClient上, 並聲明本身關心的資源。
啓動後, Client經過讀取當前checkpoint, 假如checkpoint在Relay中不存在, 那麼啓動Relay Puller 和 Bootstrap Puller分別從Relay和Bootstrap Service拉取數據, 並寫入本地EventBuffer, Dispatcher不斷poll EventBuffer中的數據, 分發到Callback Driver上, 並通知Checkpoint Persistence Provider記錄當前讀取的checkpoint(即SCN)。
這樣就能實現對訂閱消息的全量回溯, 向客戶端代碼屏蔽Relay與Boostrap Service的差別。
在上面的DataBus Relay的架構圖能夠看到
Event Producer除了能夠訂閱數據源以外,還能訂閱其餘Relays,能夠經過Relay Chaining進行擴展。在Follower Relay中使用RelayEventProducer, 從Master Relay拉取數據, 這兩個Relay就組成了Master和Follower的鏈式結構。固然,這種設計會使得變動數據在多個Relay中冗餘,有些浪費空間。
都看到最後了,原創不易,點個關注,點個贊吧~
知識碎片從新梳理,構建Java知識圖譜: github.com/saigu/JavaK…(歷史文章查閱很是方便)