一種多數(shù)據(jù)源索引同步設(shè)計

大數(shù)據(jù)

背景

在我接觸的很多應(yīng)用開發(fā)中,搜索引擎(ElasticSearch)是充當業(yè)務(wù)寬表使用,也就是聚合多張業(yè)務(wù)表,免去線上查詢的join操作。

初始方案通過canal來同步多表數(shù)據(jù)源,因為canal同步binlog消息是單線程運行的,所以不存在順序問題,另外多表之間也沒有重疊的業(yè)務(wù)字段,所以多表更新也不要求順序性。

在基礎(chǔ)服務(wù)平臺化之后,如果多個業(yè)務(wù)(索引同步算是業(yè)務(wù)方之一)各自根據(jù)業(yè)務(wù)需求使用canal訂閱binlog變更消息,會對db造成一定的壓力,而且其實canal訂閱這部分工作是重復(fù)的,也就是可以從業(yè)務(wù)中拆分出數(shù)據(jù)同步的生命周期(數(shù)據(jù)變更->binlog->獲取變更),作為數(shù)據(jù)總線的一部分,數(shù)據(jù)交互通過消息隊列解耦。

這樣拆分之后,因為mq這個環(huán)節(jié)的加入,使得消息到達同步程序時可能發(fā)生亂序現(xiàn)象(原本狀態(tài)是“支付”->“發(fā)貨”,實際可能是“發(fā)貨”->“支付”),導(dǎo)致了一條臟數(shù)據(jù);如果要保證消息順序,可以使用mq的局部有序特性(服務(wù)端分為若干partition,每個partition單線程生產(chǎn)、單線程消費,指定字段的消息只路由到某一個partition),但這樣會嚴重影響消息吞吐量。

所以初始方案加入mq之后就只有兩個選擇,要么容忍一定程度的臟數(shù)據(jù),通過數(shù)據(jù)補償實現(xiàn)最終一致性,要么降低吞吐量使用局部順序消息數(shù)據(jù)。

目標

消息亂序問題是使用mq過程中經(jīng)常遇到的,多線程生產(chǎn)/多線程消費/ack處理不當都可能引起消息亂序,另外mq的特性就是最多一次或者最少一次,為了保證數(shù)據(jù)不丟失,一般我們的選擇都是最少一次(保證每條消息至少會被consumer消費一次)。

這里我們的目標就是在保持現(xiàn)有同步程序吞吐量的情況下解決消息亂序問題,簡單歸納就是:

使用mq同步消息不依賴局部有序特性保證數(shù)據(jù)一致性

方案

上面說到通過mq來同步數(shù)據(jù),其實binlog消息是可以有順序標記的(filename+offset),如果將其轉(zhuǎn)化為一個long類型數(shù)值就可以作為版本號使用,既然有版本號,那么只要保證新數(shù)據(jù)的版本號高于舊數(shù)據(jù)即可(按上面的轉(zhuǎn)換方式天然保證),然而Es并不支持列級別版本號,只能設(shè)置行級別,多數(shù)據(jù)源有多個版本號,所以使用原生的Es版本號并不可行。

作為NoSql屆的一哥,HBase是可以支持列版本號的,row+column+version才可以唯一確定某個cell中的值,默認保留3個version的數(shù)值,get操作如果不指定version則返回cell中version最大的數(shù)值。

大數(shù)據(jù)

寫到這里熟悉的同學應(yīng)該已經(jīng)猜到我們的方案了:

在HBase中建立HTable,作為鏡像索引通過mq消費多個數(shù)據(jù)源的binlog消息,消息中包含binlog序號轉(zhuǎn)換而來的version將帶version消息寫入HBase,即使舊數(shù)據(jù)后于新數(shù)據(jù)到達,只要保證version按更新順序遞增就可以保證get到最新數(shù)據(jù)通過get操作從HBase中獲取單條記錄(不用指定version),建議是保持rowkey和索引唯一鍵一致,方便兩側(cè)的讀寫判斷記錄是否完整(是否所有非空字段都有值,涉及業(yè)務(wù)操作,此步驟可選)通過index操作回寫到索引(因為是完整數(shù)據(jù),所以直接覆蓋更方便,還可以省去update的取/合并操作)正常返回結(jié)束,否則重試即可

大數(shù)據(jù)

具體需要實現(xiàn)一個消費多個數(shù)據(jù)源消息的consumer,需要同時訪問HBase和Es:

大數(shù)據(jù)

補充說明幾點:

HTable字段配置和索引配置一樣,也可以根據(jù)需要加上其它的字段,只要保證索引字段是HTable字段的子集就可以了cf可以配置為一個表一個cf或者全部合并為一個cf因為HBase中有全量數(shù)據(jù),如果索引需要重建,在維持增量同步程序運行狀態(tài)下,只需要單獨啟動程序遍歷HTable寫入Es。這樣就可以做到不暫停線上任務(wù)的情況下,在任意時間點全量重刷索引數(shù)據(jù)了從HBase取數(shù)據(jù)寫索引是個冪等操作,重試簡單可行

結(jié)語

這個方案論證了挺久,理論上是實際可行的,然而因為各種原因沒有真正實現(xiàn),所以可能有些坑并沒有踩到,比如性能/cf設(shè)計等。

拋磚引玉,希望對大家有所幫助。

作者:跳跳爸的科普

極客網(wǎng)企業(yè)會員

免責聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準確性及可靠性,但不保證有關(guān)資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負任何法律責任。任何單位或個人認為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實情況說明,并提供身份證明、權(quán)屬證明及詳細侵權(quán)或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實,溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

2017-11-16
一種多數(shù)據(jù)源索引同步設(shè)計
背景 在我接觸的很多應(yīng)用開發(fā)中,搜索引擎(ElasticSearch)是充當業(yè)務(wù)寬表使用,也就是聚合多張業(yè)務(wù)表,免去線上查詢的join操作。 初始方案通過ca

長按掃碼 閱讀全文