<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          干貨 | 實(shí)時數(shù)據(jù)聚合怎么破

          共 3209字,需瀏覽 7分鐘

           ·

          2021-03-31 19:58

          作者簡介

           

          數(shù)據(jù)猩猩,攜程數(shù)據(jù)分析總監(jiān),關(guān)注分布式數(shù)據(jù)存儲和實(shí)時數(shù)據(jù)分析。


          實(shí)時數(shù)據(jù)分析一直是個熱門話題,需要實(shí)時數(shù)據(jù)分析的場景也越來越多,如金融支付中的風(fēng)控,基礎(chǔ)運(yùn)維中的監(jiān)控告警,實(shí)時大盤之外,AI模型也需要消費(fèi)更為實(shí)時的聚合結(jié)果來達(dá)到很好的預(yù)測效果。

          實(shí)時數(shù)據(jù)分析如果講的更加具體些,基本上會牽涉到數(shù)據(jù)聚合分析。

          數(shù)據(jù)聚合分析在實(shí)時場景下,面臨的新問題是什么,要解決的很好,大致有哪些方面的思路和框架可供使用,本文嘗試做一下分析和厘清。

          在實(shí)時數(shù)據(jù)分析場景下,最大的制約因素是時間,時間一變動,所要處理的源頭數(shù)據(jù)會發(fā)生改變,處理的結(jié)果自然也會因此而不同。在此背景下,引申出來的三大子問題就是:

          • 通過何種機(jī)制觀察到變化的數(shù)據(jù) 

          • 通過何種方式能最有效的處理變化數(shù)據(jù),將結(jié)果并入到原先的聚合分析結(jié)果中

          • 分析后的數(shù)據(jù)如何讓使用方及時感知并獲取


          可以說,數(shù)據(jù)新鮮性和處理及時性是實(shí)時數(shù)據(jù)處理中的一對基本矛盾。


          另外實(shí)時是一個相對的概念,在不同場景下對應(yīng)的時延也差異很大,借用Uber給出的定義,大體來區(qū)分一下實(shí)時處理所能接受的時延范圍。


          一、數(shù)據(jù)新鮮性




          為簡單起見,把數(shù)據(jù)分成兩大類,一類是關(guān)鍵的交易性數(shù)據(jù),以存儲在關(guān)系型數(shù)據(jù)庫為主,另一類是日志型數(shù)據(jù),以存儲在日志型消息隊(duì)列(如kafka)為主。

          第二類數(shù)據(jù),消費(fèi)端到感知到最新的變化數(shù)據(jù),采用內(nèi)嵌的pull機(jī)制,比較容易實(shí)現(xiàn),同時日志類數(shù)據(jù),絕大部分是append-only,不涉及到刪改,無論是采用ClickHouse還是使用TimeScaleDB都可以達(dá)到很好的實(shí)時聚合效果,這里就不再贅述。

          針對第一類存儲在數(shù)據(jù)庫中的數(shù)據(jù),要想實(shí)時感知到變化的數(shù)據(jù)(這里的變化包含有增/刪/改三種操作類型),有兩種打法。

          打法一:基于時間戳方式的數(shù)據(jù)同步,假設(shè)在表設(shè)計(jì)時,每張表中都有datachange_lasttime字段表示最近一次操作發(fā)生的時間,同步程序會定期掃描目標(biāo)表,把datachange_lasttime不小于上次同步時間的數(shù)據(jù)拉出進(jìn)行同步。

          這種處理方式的主要缺點(diǎn)是無法感知到數(shù)據(jù)刪除操作,為了規(guī)避這個不足,可以采用邏輯刪除的表設(shè)計(jì)方式。數(shù)據(jù)刪除并不是采取物理刪除,只是修改表示數(shù)據(jù)已經(jīng)刪除的列中的值標(biāo)記為刪除或無效。使用這種方法雖然讓同步程序可以感知到刪除操作,但額外的成本是讓應(yīng)用程序在刪除和查詢時,操作語句和邏輯都變得復(fù)雜,降低了數(shù)據(jù)庫的可維護(hù)性。

          打法一的變種是基于觸發(fā)器方式,把變化過的數(shù)據(jù)推送給同步程序。這種方式的成本,一方面是需要設(shè)計(jì)實(shí)現(xiàn)觸發(fā)器,另一方面是了降低了insert/update/delete操作的性能, 提升了時延,降低了吞吐量。

          打法二:基于CDC(Change Data Capture)的方式進(jìn)行增量數(shù)據(jù)同步,這種方式對數(shù)據(jù)庫設(shè)計(jì)的侵入性最小,性能影響也最低,同時可以獲得豐富的開源組件支持,如Cannal對MySQL有很好支持,Debezium對PostgreSQL有支持。利用這些同步組件,把變化數(shù)據(jù)寫入到Kafka,然后供后續(xù)實(shí)時數(shù)據(jù)分析進(jìn)一步處理。

          二、數(shù)據(jù)關(guān)聯(lián)




          新鮮數(shù)據(jù)在獲取到之后,第一步常見操作是進(jìn)行數(shù)據(jù)補(bǔ)全(Data Enrichment), 數(shù)據(jù)補(bǔ)全自然涉及到多表之間的關(guān)聯(lián)。這里有一個痛點(diǎn),要關(guān)聯(lián)的數(shù)據(jù)并不一定也會在增量數(shù)據(jù)中,如機(jī)票訂單數(shù)據(jù)狀態(tài)發(fā)生變化,要找到變化過訂單涉及到的航段信息。由于訂單信息和航段信息是兩張不同的表維護(hù),如果只是拿增量數(shù)據(jù)進(jìn)行關(guān)聯(lián),那么有可能找不到航段信息。這是一個典型的實(shí)時數(shù)據(jù)和歷史數(shù)據(jù)關(guān)聯(lián)的例子。

          解決實(shí)時數(shù)據(jù)和歷史數(shù)據(jù)關(guān)聯(lián)一種非常容易想到的思路就是當(dāng)實(shí)時數(shù)據(jù)到達(dá)的時候,去和數(shù)據(jù)庫中的歷史數(shù)據(jù)進(jìn)行關(guān)聯(lián),這種做法一是加大了數(shù)據(jù)庫的訪問,導(dǎo)致數(shù)據(jù)庫負(fù)擔(dān)增加,另一方面是關(guān)聯(lián)的時延會大大加長。為了讓歷史數(shù)據(jù)迅速可達(dá),自然想到添加緩存,緩存的引入固然可以減少關(guān)聯(lián)處理時延,但容易引起緩存數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)不一致問題,另外緩存容量不易估算,成本增加。

          有沒有別的套路可以嘗試?這個必須要有。

          可以在數(shù)據(jù)庫側(cè)先把數(shù)據(jù)進(jìn)行補(bǔ)全,利用行轉(zhuǎn)列的方式,形成一張寬表,實(shí)現(xiàn)數(shù)據(jù)自完備,寬表的變化內(nèi)容,利用CDC機(jī)制,讓外界實(shí)時感知。

          三、計(jì)算及時性



          在解決好數(shù)據(jù)變化實(shí)時感知和數(shù)據(jù)完備兩個問題之后,進(jìn)入最關(guān)鍵一環(huán),數(shù)據(jù)聚合分析。為了達(dá)到結(jié)果準(zhǔn)確和處理及時之間的平衡,有兩大解決方法:一為全量,一為增量。

          3.1 全量計(jì)算(1m<時延<5m)


          全量計(jì)算以時間代價,對變化過的數(shù)據(jù)進(jìn)行全量分析,分析結(jié)果有最高的準(zhǔn)確性和可靠性。成本是花費(fèi)較長的計(jì)算時間和消耗較多的計(jì)算資源。可以使用的分析引擎或計(jì)算框架有 Apache Spark 和 Apache Flink。

          全量數(shù)據(jù)容量一般會比較大,為了節(jié)約存儲,同時為了方便數(shù)據(jù)過濾和減少不必要的網(wǎng)絡(luò)傳輸,大多會使用列式存儲, 列式存儲使用較多的當(dāng)屬Parquet和ORC。

          列式存儲最大的不足是無法進(jìn)行刪/改操作,為了支持刪改,一般會把列式存儲和行式存儲相結(jié)合。最近時間內(nèi)變化的數(shù)據(jù)采用行式存儲如avro格式,然后定期合并成列式存儲。非常成功和紅火的Apache Hudi和Delta IO就是基于這種思路。

          3.2 增量計(jì)算


          假設(shè)當(dāng)前處理的時間窗口中有10萬條記錄,因?yàn)槠渲胁坏?00條的記錄發(fā)生變化,而對所有記錄的聚合指標(biāo)進(jìn)行計(jì)算重演,顯然不是非常合理,那么有沒有可能只對增量數(shù)據(jù)導(dǎo)致的變化聚合指標(biāo)進(jìn)行重算。答案是肯定的,或者說在部分場景下,是可以實(shí)現(xiàn)的。

          讓我們把增量計(jì)算分成幾種不同情況:

          1)增量數(shù)據(jù)會添加新的聚合記錄,對原有計(jì)算結(jié)果無影響 
          2)增量數(shù)據(jù)會添加新的聚合記錄,并導(dǎo)致原有計(jì)算結(jié)果部分失效 
          3)增量數(shù)據(jù)不添加新的聚合記錄,但導(dǎo)致原有計(jì)算結(jié)果全部失效

          第1、2兩種情況下,增量計(jì)算會帶來實(shí)時性上的收益,第三種不會,因?yàn)樗兄笜?biāo)均被破壞,都需要重演,已經(jīng)褪化成全量計(jì)算。

          增量處理模型除了Apache Flink之外,非常著名的還有Microsoft提出的Naiad模型,后者更為高效。由于后者只提供了非常底層的調(diào)用API,在生態(tài)建設(shè)方面遠(yuǎn)不如Apache Flink,但其思想深刻影響了TensorFlow等框架的設(shè)計(jì)和實(shí)現(xiàn),等有時間再詳細(xì)介紹一下Naiad。

          上面討論的全量也好,增量也罷,都是把數(shù)據(jù)從數(shù)據(jù)庫拉出來再進(jìn)行計(jì)算,那么有沒有可能在數(shù)據(jù)庫內(nèi)部實(shí)現(xiàn)增量計(jì)算的可能?

          Oracle在12.x版本中提供物理視圖(materialized view)的自動刷新機(jī)制,這意味著用戶可以把實(shí)時聚合邏輯定義在物理視圖中,然后每當(dāng)有數(shù)據(jù)更新,視圖會被自動更新。既然Oracle有,那么在開源的世界里一定會有對應(yīng)的東西出現(xiàn),最起碼會有相應(yīng)的影子在浮現(xiàn),這個影子就是PostgreSQL IVM。

          PostgreSQL IVM使用到Transition Table這個概念,在觸發(fā)器中,用戶可以看到變化前和變化后的數(shù)據(jù),從而計(jì)算出變更的內(nèi)容,利用這些Delta數(shù)據(jù),進(jìn)行刷新預(yù)先定義好的物理視圖。

          四、計(jì)算觸發(fā)機(jī)制




          • 定時觸發(fā)

          • trigger for every new element


          計(jì)算成本比較


          五、聚合結(jié)果實(shí)時可見




          聚合結(jié)果的存儲要支持upsert語義,聚合結(jié)果的消費(fèi)者實(shí)時感知到,同時聚合結(jié)果的存儲要有水平可擴(kuò)性。結(jié)合這三個要求,比較推薦使用NoSQL來進(jìn)行指標(biāo)的存儲,具體可以使用MongoDB。

          六、小結(jié)




          本文嘗試對實(shí)時數(shù)據(jù)聚合分析中涉及到的問題和常見思路進(jìn)行梳理,文中定有不少疏漏,不足之處希望讀者批評指正。

          瀏覽 79
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文无码在线视频 | 一级特黄录像免费播放下载软件 | 爆操老司机| 天天日天天干天天日 | 欧美午夜激情视频 |