導(dǎo)讀:數(shù)據(jù)總線(DBus)專注于數(shù)據(jù)的實時采集與實時分發(fā),可以對IT系統(tǒng)在業(yè)務(wù)流程中產(chǎn)生的數(shù)據(jù)進(jìn)行匯聚,經(jīng)過轉(zhuǎn)換處理后成為統(tǒng)一JSON的數(shù)據(jù)格式(UMS),提供給不同數(shù)據(jù)使用方訂閱和消費,充當(dāng)數(shù)倉平臺、大數(shù)據(jù)分析平臺、實時報表和實時營銷等業(yè)務(wù)的數(shù)據(jù)源。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了四平免費建站歡迎大家使用!
本文從數(shù)據(jù)分片的角度出發(fā),具體介紹DBus在數(shù)據(jù)采集的過程中,運用了什么樣的分片策略和分片原理,以及過程中遇到的問題及解決方案。
對于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,DBus通過提供全量數(shù)據(jù)拉取和增量數(shù)據(jù)采集兩種途徑滿足用戶數(shù)據(jù)采集需求。DBus數(shù)據(jù)抽取流程如下圖所示(以MySQL為例):
全量數(shù)據(jù)采集的主要原理是:根據(jù)主鍵、唯一索引、索引等信息,確定分片列。之所以分片列要根據(jù)主鍵、唯一索引、索引等選擇,是因為這些列的數(shù)據(jù)在庫里建立了良好索引,能提升數(shù)據(jù)掃描的效率。
根據(jù)選定的分片列,對數(shù)據(jù)進(jìn)行拆片,確定每片數(shù)據(jù)的上下界,然后根據(jù)每片上下界,以6~8左右的并發(fā)度,進(jìn)行數(shù)據(jù)拉取。(6~8左右的并發(fā)度是經(jīng)大量測試獲得的經(jīng)驗值。實驗顯示,6~8左右的并發(fā)度既不會對源庫形成過高壓力,又能最大限度提升全量數(shù)據(jù)拉取的效率。)
DBus分片策略示意圖:
DBus拉取策略示意圖:
那么,DBus支持什么類型的列作為分片列?不同類型的分片列,分片策略如何呢?
分片策略這塊,DBus借鑒了Sqoop的分片設(shè)計,支持以下類型的列作為分片列:
拆片原理大體一致,都是根據(jù)分片列的最大最小值,以及設(shè)定的每片大小,進(jìn)行每一分片上下界的計算和確定。但具體實現(xiàn)細(xì)節(jié)差異很大。尤其是Text/NText類型,借鑒、應(yīng)用的過程中發(fā)現(xiàn)一些問題,我們進(jìn)行了一些調(diào)整和優(yōu)化。
本文主要和大家分享一下遇到的坑和我們的解決辦法。
讓我們先以最簡單、明了的數(shù)字類型分片列為例介紹分片原理。
如前所述,我們會按照主鍵->唯一索引->索引的優(yōu)先級確定分片列。如果表有主鍵,我們以主鍵列為分片列;如果沒有主鍵,有唯一索引,我們以唯一索引列為分片列……以此類推。如果找到的鍵或索引是聯(lián)合主鍵或聯(lián)合索引,我取其中的第一列作為分片列。如果沒有找到任何合適的列作為分片列,則不分片,所有數(shù)據(jù)作一片進(jìn)行拉?。o法享受并發(fā)拉取帶來的效率提升)。
首先要根據(jù)一定的規(guī)則選取某一列作為分片列,然后根據(jù)分片列的最大最小值,以及設(shè)定的每片大小,進(jìn)行每一分片上下界的計算和確定:
1)獲取切分字段的MIN()和MAX()
2)根據(jù)MIN和MAX不同的類型采用不同的切分方式
實現(xiàn)代碼片段如下:
對于分片列類型為數(shù)字類型的情況,很好理解。
如果分片列類型為char/varchar等字符串類型呢?每一片的上下界該如何計算?
原理還是一樣的:查出該列的最小、最大值,根據(jù)每片大小,計算每片分界點,生成每一片的上下界。
技術(shù)細(xì)節(jié)上不一樣的地方是:每片分界點/上下界的計算。
分片列類型為int,min 為2 ,max為10, shard size為3,分片很好理解:
Split[2,5)
Split[5,8)
Split[8,10]
如果分片列類型為varchar(128), min 為abc,max為 xyz,怎么計算拆片點呢?
Sqoop的分片機制是通過將“字符串”映射為“數(shù)字”,根據(jù)數(shù)字計算出分片上下界,然后將以數(shù)字表達(dá)的分片上下界映射回字符串,以此字符串作為分片的上/下界。如下所示:
然而,在實際應(yīng)用中,上述分片機制碰到各種問題,下面將我們碰到和解決這一系列問題的經(jīng)驗分享如下。
1)現(xiàn)象
2)分析
3)解決辦法
1)現(xiàn)象
2)分析
3)檢查發(fā)現(xiàn)
4)Unicode
5)UTF16
第二個WORD的取值范圍(二進(jìn)制)是11011100 00000000到11011111 11111111,即0xDC00-0xDFFF。
根據(jù)上述字符集只是,我們找到了問題癥結(jié)所在:
6)解決方案
↓↓↓
解決字符集亂碼問題后,能正常拉取數(shù)據(jù),但總數(shù)不對。
1)現(xiàn)象
2)分析
3)解決方案
類似: SELECT * FROM tableName WHERE binary columnName = 'a';
至此,對char、varchar類型字符串分片列的分片,也有了很好的支持。