您的位置:首頁 > 宏觀 >

如何在萬億數(shù)據(jù)下的多維實時分析系統(tǒng)做到亞秒級響應

2020-10-23 08:42:33 來源: 51cto

導語當業(yè)務發(fā)展到一定規(guī)模,實時數(shù)據(jù)倉庫是一個必要的基礎(chǔ)服務。從數(shù)據(jù)驅(qū)動方面考慮,多維實時數(shù)據(jù)分析系統(tǒng)的重要性也不言而喻。但是當數(shù)據(jù)

導語

當業(yè)務發(fā)展到一定規(guī)模,實時數(shù)據(jù)倉庫是一個必要的基礎(chǔ)服務。從數(shù)據(jù)驅(qū)動方面考慮,多維實時數(shù)據(jù)分析系統(tǒng)的重要性也不言而喻。但是當數(shù)據(jù)量巨大的情況下,拿騰訊看點來說,一天上報的數(shù)據(jù)量達到萬億級的規(guī)模,要實現(xiàn)極低延遲的實時計算和亞秒級的多維實時查詢是有技術(shù)挑戰(zhàn)的。本文將介紹一下信息流場景下,騰訊看點的實時數(shù)據(jù)倉庫和多維實時數(shù)據(jù)分析系統(tǒng)的技術(shù)架構(gòu)。

一、可解決的痛點

可以先看一下,多維實時數(shù)據(jù)分析系統(tǒng)可以解決哪些痛點。比如:

推薦同學10分鐘前上了一個推薦策略,想知道在不同人群的推薦效果怎么樣?

運營同學想知道,在廣東省的用戶中,最火的廣東地域內(nèi)容是哪些,方便做地域Push。

審核同學想知道,過去5分鐘,游戲類被舉報最多的內(nèi)容和賬號是哪些?

老板可能想了解,過去10分鐘有多少用戶在看點消費了內(nèi)容,對消費人群有一個宏觀了解。

二、調(diào)研

在進行開發(fā)之前,我們做了這些調(diào)研。

1.離線數(shù)據(jù)分析平臺能否滿足這些需求,結(jié)論是不能滿足。離線數(shù)據(jù)分析平臺不行的原因如下:

C側(cè)數(shù)據(jù)上報過來,需要經(jīng)過Spark的多層離線計算,最終結(jié)果出庫到Mysql或者ES提供給離線分析平臺查詢。這個過程的延時最少3-6個小時,目前比較常見的都是提供隔天的查詢,所以很多實時性要求高的業(yè)務場景都是不能滿足的; 另一個問題是,騰訊看點的數(shù)據(jù)量太大,帶來的不穩(wěn)定性也比較大,經(jīng)常會有預料不到的延遲。所以,離線分析平臺是無法滿足很多需求的。

2.實時數(shù)據(jù)分析平臺的話,事業(yè)群內(nèi)部提供了準實時數(shù)據(jù)查詢的功能,底層技術(shù)用的是Kudu+Impala,Impala雖然是MPP架構(gòu)的大數(shù)據(jù)計算引擎,并且訪問以列式存儲數(shù)據(jù)的Kudu。但是對于實時數(shù)據(jù)分析場景來說,查詢響應的速度和數(shù)據(jù)的延遲都還是比較高,查詢一次實時DAU,返回結(jié)果耗時至少幾分鐘,無法提供良好的交互式用戶體驗。

所以(Kudu+Impala)這種通用大數(shù)據(jù)處理框架的速度優(yōu)勢更多的是相比(Spark+Hdfs)這種離線分析框架來說的,對于我們這個實時性要求更高的場景,是無法滿足的。

三、項目背景

經(jīng)過剛才的介紹,再來看下我們這個項目的背景。

作者發(fā)文的內(nèi)容被內(nèi)容中心引入,經(jīng)過內(nèi)容審核鏈路,啟用或者下架。啟用的內(nèi)容給到推薦系統(tǒng)和運營系統(tǒng),然后推薦系統(tǒng)和運營系統(tǒng)將內(nèi)容進行C側(cè)分發(fā)。內(nèi)容分發(fā)給C側(cè)用戶之后,用戶會產(chǎn)生各種行為,曝光、點擊、舉報等,通過埋點上報實時接入到消息隊列中。

接下來我們做了兩部分工作,就是圖中有顏色的這兩部分。

第一部分構(gòu)建了一個騰訊看點的實時數(shù)據(jù)倉庫;第二部分就是基于OLAP存儲引擎,開發(fā)了多維實時數(shù)據(jù)分析系統(tǒng)。

我們?yōu)槭裁匆獦?gòu)建實時數(shù)倉,因為原始的上報數(shù)據(jù)量非常大,一天上報峰值就有上萬億條。而且上報格式混亂。缺乏內(nèi)容維度信息、用戶畫像信息,下游沒辦法直接使用。而我們提供的實時數(shù)倉,是根據(jù)騰訊看點信息流的業(yè)務場景,進行了內(nèi)容維度的關(guān)聯(lián),用戶畫像的關(guān)聯(lián),各種粒度的聚合,下游可以非常方便的使用實時數(shù)據(jù)。

四、方案選型

那就看下我們多維實時數(shù)據(jù)分析系統(tǒng)的方案選型,選型我們對比了行業(yè)內(nèi)的領(lǐng)先方案,選擇了最符合我們業(yè)務場景的方案。

第一塊是實時數(shù)倉的選型,我們選擇的是業(yè)界比較成熟的Lambda架構(gòu),他的優(yōu)點是靈活性高、容錯性高、成熟度高和遷移成本低;缺點是實時、離線數(shù)據(jù)用兩套代碼,可能會存在一個口徑修改了,另一個沒改的問題,我們每天都有做數(shù)據(jù)對賬的工作,如果有異常會進行告警。

第二塊是實時計算引擎選型,因為Flink設(shè)計之初就是為了流處理,SparkStreaming嚴格來說還是微批處理,Strom用的已經(jīng)不多了。再看Flink具有Exactly-once的準確性、輕量級Checkpoint容錯機制、低延時高吞吐和易用性高的特點,我們選擇了Flink作為實時計算引擎。

第三塊是實時存儲引擎,我們的要求就是需要有維度索引、支持高并發(fā)、預聚合、高性能實時多維OLAP查詢??梢钥吹?,Hbase、Tdsql和ES都不能滿足要求,Druid有一個缺陷,它是按照時序劃分Segment,無法將同一個內(nèi)容,存放在同一個Segment上,計算全局TopN只能是近似值,所以我們選擇了最近兩年大火的MPP數(shù)據(jù)庫引擎ClickHouse。

五、設(shè)計目標與設(shè)計難點

我們多維實時數(shù)據(jù)分析系統(tǒng)分為三大模塊:

實時計算引擎; 實時存儲引擎; App層。

難點主要在前兩個模塊:實時計算引擎和實時存儲引擎。

千萬級/s的海量數(shù)據(jù)如何實時接入,并且進行極低延遲維表關(guān)聯(lián); 實時存儲引擎如何支持高并發(fā)寫入、高可用分布式和高性能索引查詢,是比較難的。

這幾個模塊的具體實現(xiàn),看一下我們系統(tǒng)的架構(gòu)設(shè)計。

六、架構(gòu)設(shè)計

前端采用的是開源組件Ant Design,利用了Nginx服務器,部署靜態(tài)頁面,并反向代理了瀏覽器的請求到后臺服務器上。

后臺服務是基于騰訊自研的RPC后臺服務框架寫的,并且會進行一些二級緩存。

實時數(shù)倉部分,分為了接入層、實時計算層和實時數(shù)倉存儲層。

接入層主要是從千萬級/s的原始消息隊列中,拆分出不同行為數(shù)據(jù)的微隊列,拿看點的視頻來說,拆分過后,數(shù)據(jù)就只有百萬級/s了; 實時計算層主要負責,多行行為流水數(shù)據(jù)進行行轉(zhuǎn)列,實時關(guān)聯(lián)用戶畫像數(shù)據(jù)和內(nèi)容維度數(shù)據(jù); 實時數(shù)倉存儲層主要是設(shè)計出符合看點業(yè)務的,下游好用的實時消息隊列。我們暫時提供了兩個消息隊列,作為實時數(shù)倉的兩層。一層DWM層是內(nèi)容ID-用戶ID粒度聚合的,就是一條數(shù)據(jù)包含內(nèi)容ID-用戶ID還有B側(cè)內(nèi)容數(shù)據(jù)、C側(cè)用戶數(shù)據(jù)和用戶畫像數(shù)據(jù);另一層是DWS層,是內(nèi)容ID粒度聚合的,一條數(shù)據(jù)包含內(nèi)容ID,B側(cè)數(shù)據(jù)和C側(cè)數(shù)據(jù)??梢钥吹絻?nèi)容ID-用戶ID粒度的消息隊列流量進一步減小到十萬級/s,內(nèi)容ID粒度的更是萬級/s,并且格式更加清晰,維度信息更加豐富。

實時存儲部分分為實時寫入層、OLAP存儲層和后臺接口層。

實時寫入層主要是負責Hash路由將數(shù)據(jù)寫入; OLAP存儲層利用MPP存儲引擎,設(shè)計符合業(yè)務的索引和物化視圖,高效存儲海量數(shù)據(jù); 后臺接口層提供高效的多維實時查詢接口。

七、實時計算

這個系統(tǒng)最復雜的兩塊,實時計算和實時存儲。先介紹實時計算部分:分為實時關(guān)聯(lián)和實時數(shù)倉。

1、實時高性能維表關(guān)聯(lián)

實時維表關(guān)聯(lián)這一塊難度在于。百萬級/s的實時數(shù)據(jù)流,如果直接去關(guān)聯(lián)HBase,1分鐘的數(shù)據(jù),關(guān)聯(lián)完HBase耗時是小時級的,會導致數(shù)據(jù)延遲嚴重。

我們提出了幾個解決方案:

第一個是,在Flink實時計算環(huán)節(jié),先按照1分鐘進行了窗口聚合,將窗口內(nèi)多行行為數(shù)據(jù)轉(zhuǎn)一行多列的數(shù)據(jù)格式,經(jīng)過這一步操作,原本小時級的關(guān)聯(lián)耗時下降到了十幾分鐘,但是還是不夠的。

第二個是,在訪問HBase內(nèi)容之前設(shè)置一層Redis緩存,因為1000條數(shù)據(jù)訪問HBase是秒級的,而訪問Redis是毫秒級的,訪問Redis的速度基本是訪問HBase的1000倍。為了防止過期的數(shù)據(jù)浪費緩存,緩存過期時間設(shè)置成24小時,同時通過監(jiān)聽寫HBase Proxy來保證緩存的一致性。這樣將訪問時間從十幾分鐘變成了秒級。

第三個是,上報過程中會上報不少非常規(guī)內(nèi)容ID,這些內(nèi)容ID在內(nèi)容HBase中是不存儲的,會造成緩存穿透的問題。所以在實時計算的時候,我們直接過濾掉這些內(nèi)容ID,防止緩存穿透,又減少一些時間。

第四個是,因為設(shè)置了定時緩存,會引入一個緩存雪崩的問題。為了防止雪崩,我們在實時計算中,進行了削峰填谷的操作,錯開設(shè)置緩存的時間。

可以看到,優(yōu)化前后,數(shù)據(jù)量從百億級減少到了十億級,耗時從小時級減少到了數(shù)十秒,減少99%。

2、下游提供服務

實時數(shù)倉的難度在于:它處于比較新的領(lǐng)域,并且各個公司各個業(yè)務差距比較大,怎么能設(shè)計出方便,好用,符合看點業(yè)務場景的實時數(shù)倉是有難度的。

先看一下實時數(shù)倉做了什么,實時數(shù)倉對外就是幾個消息隊列,不同的消息隊列里面存放的就是不同聚合粒度的實時數(shù)據(jù),包括內(nèi)容ID、用戶ID、C側(cè)行為數(shù)據(jù)、B側(cè)內(nèi)容維度數(shù)據(jù)和用戶畫像數(shù)據(jù)等。

我們是怎么搭建實時數(shù)倉的,就是上面介紹的實時計算引擎的輸出,放到消息隊列中保存,可以提供給下游多用戶復用。

我們可以看下,在我們建設(shè)實時數(shù)據(jù)倉庫前后,開發(fā)一個實時應用的區(qū)別。沒有數(shù)倉的時候,我們需要消費千萬級/s的原始隊列,進行復雜的數(shù)據(jù)清洗,然后再進行用戶畫像關(guān)聯(lián)、內(nèi)容維度關(guān)聯(lián),才能拿到符合要求格式的實時數(shù)據(jù),開發(fā)和擴展的成本都會比較高,如果想開發(fā)一個新的應用,又要走一遍這個流程。有了數(shù)倉之后,如果想開發(fā)內(nèi)容ID粒度的實時應用,就直接申請TPS萬級/s的DWS層的消息隊列。開發(fā)成本變低很多,資源消耗小很多,可擴展性也強很多。

看個實際例子,開發(fā)我們系統(tǒng)的實時數(shù)據(jù)大屏,原本需要進行如上所有操作,才能拿到數(shù)據(jù)?,F(xiàn)在只需要消費DWS層消息隊列,寫一條Flink SQL即可,僅消耗2個cpu核心,1G內(nèi)存。

可以看到,以50個消費者為例,建立實時數(shù)倉前后,下游開發(fā)一個實時應用,可以減少98%的資源消耗。包括計算資源,存儲資源,人力成本和開發(fā)人員學習接入成本等等。并且消費者越多,節(jié)省越多。就拿Redis存儲這一部分來說,一個月就能省下上百萬人民幣。

八、實時存儲

介紹完實時計算,再來介紹實時存儲。這塊分為三個部分來介紹:

分布式-高可用; 海量數(shù)據(jù)-寫入; 高性能-查詢。

1、分布式-高可用

我們這里聽取的是Clickhouse官方的建議,借助ZK實現(xiàn)高可用的方案。數(shù)據(jù)寫入一個分片,僅寫入一個副本,然后再寫ZK,通過ZK告訴同一個分片的其他副本,其他副本再過來拉取數(shù)據(jù),保證數(shù)據(jù)一致性。

這里沒有選用消息隊列進行數(shù)據(jù)同步,是因為ZK更加輕量級。而且寫的時候,任意寫一個副本,其它副本都能夠通過ZK獲得一致的數(shù)據(jù)。而且就算其它節(jié)點第一次來獲取數(shù)據(jù)失敗了,后面只要發(fā)現(xiàn)它跟ZK上記錄的數(shù)據(jù)不一致,就會再次嘗試獲取數(shù)據(jù),保證一致性。

2、海量數(shù)據(jù)-寫入

數(shù)據(jù)寫入遇到的第一個問題是,海量數(shù)據(jù)直接寫入Clickhouse的話,會導致ZK的QPS太高,解決方案是改用Batch方式寫入。Batch設(shè)置多大呢,Batch太小的話緩解不了ZK的壓力,Batch也不能太大,不然上游內(nèi)存壓力太大,通過實驗,最終我們選用了大小幾十萬的Batch。

第二個問題是,隨著數(shù)據(jù)量的增長,單QQ看點的視頻內(nèi)容每天可能寫入百億級的數(shù)據(jù),默認方案是寫一張分布式表,這就會造成單臺機器出現(xiàn)磁盤的瓶頸,尤其是Clickhouse底層運用的是Mergetree,原理類似于HBase、RocketsDb的底層LSM-Tree。在合并的過程中會存在寫放大的問題,加重磁盤壓力。峰值每分鐘幾千萬條數(shù)據(jù),寫完耗時幾十秒,如果正在做Merge,就會阻塞寫入請求,查詢也會非常慢。我們做的兩個優(yōu)化方案:一是對磁盤做Raid,提升磁盤的IO;二是在寫入之前進行分表,直接分開寫入到不同的分片上,磁盤壓力直接變?yōu)?/N。

第三個問題是,雖然我們寫入按照分片進行了劃分,但是這里引入了一個分布式系統(tǒng)常見的問題,就是局部的Top并非全局Top的問題。比如同一個內(nèi)容ID的數(shù)據(jù)落在了不同的分片上,計算全局Top100閱讀的內(nèi)容ID,有一個內(nèi)容ID在分片1上是Top100,但是在其它分片上不是Top100,導致匯總的時候,會丟失一部分數(shù)據(jù),影響最終結(jié)果。我們做的優(yōu)化是在寫入之前加上一層路由,將同一個內(nèi)容ID的記錄,全部路由到同一個分片上,解決了該問題。

介紹完寫入,下一步介紹Clickhouse的高性能存儲和查詢。

3、高性能-存儲-查詢

Clickhouse高性能查詢的一個關(guān)鍵點是稀疏索引。稀疏索引這個設(shè)計就很有講究,設(shè)計得好可以加速查詢,設(shè)計不好反而會影響查詢效率。我根據(jù)我們的業(yè)務場景,因為我們的查詢大部分都是時間和內(nèi)容ID相關(guān)的,比如說,某個內(nèi)容,過去N分鐘在各個人群表現(xiàn)如何?我按照日期,分鐘粒度時間和內(nèi)容ID建立了稀疏索引。針對某個內(nèi)容的查詢,建立稀疏索引之后,可以減少99%的文件掃描。

還有一個問題就是,我們現(xiàn)在數(shù)據(jù)量太大,維度太多。拿QQ看點的視頻內(nèi)容來說,一天流水有上百億條,有些維度有幾百個類別。如果一次性把所有維度進行預聚合,數(shù)據(jù)量會指數(shù)膨脹,查詢反而變慢,并且會占用大量內(nèi)存空間。我們的優(yōu)化,針對不同的維度,建立對應的預聚合物化視圖,用空間換時間,這樣可以縮短查詢的時間。

分布式表查詢還會有一個問題,查詢單個內(nèi)容ID的信息,分布式表會將查詢下發(fā)到所有的分片上,然后再返回查詢結(jié)果進行匯總。實際上,因為做過路由,一個內(nèi)容ID只存在于一個分片上,剩下的分片都在空跑。針對這類查詢,我們的優(yōu)化是后臺按照同樣的規(guī)則先進行路由,直接查詢目標分片,這樣減少了N-1/N的負載,可以大量縮短查詢時間。而且由于我們是提供的OLAP查詢,數(shù)據(jù)滿足最終一致性即可,通過主從副本讀寫分離,可以進一步提升性能。

我們在后臺還做了一個1分鐘的數(shù)據(jù)緩存,針對相同條件查詢,后臺就直接返回了。

4、擴容

這里再介紹一下我們的擴容的方案,調(diào)研了業(yè)內(nèi)的一些常見方案。

比如HBase,原始數(shù)據(jù)都存放在HDFS上,擴容只是Region Server擴容,不涉及原始數(shù)據(jù)的遷移。但是Clickhouse的每個分片數(shù)據(jù)都是在本地,是一個比較底層存儲引擎,不能像HBase那樣方便擴容。

Redis是哈希槽這種類似一致性哈希的方式,是比較經(jīng)典分布式緩存的方案。Redis slot在Rehash的過程中雖然存在短暫的ask讀不可用,但是總體來說遷移是比較方便的,從原h(huán)[0]遷移到h[1],最后再刪除h[0]。但是Clickhouse大部分都是OLAP批量查詢,不是點查,而且由于列式存儲,不支持刪除的特性,一致性哈希的方案不是很適合。

目前擴容的方案是,另外消費一份數(shù)據(jù),寫入新Clickhouse集群,兩個集群一起跑一段時間,因為實時數(shù)據(jù)就保存3天,等3天之后,后臺服務直接訪問新集群。

九、成果

騰訊看點實時數(shù)據(jù)倉庫:DWM層和DWS層,數(shù)據(jù)延遲1分鐘。

遠見多維實時數(shù)據(jù)分析系統(tǒng):亞秒級響應多維條件查詢請求,在未命中緩存情況下,過去30分鐘的查詢,99%的請求耗時在1秒內(nèi);過去24小時的查詢,90%的請求耗時在5秒內(nèi),99%的請求耗時在10秒內(nèi)。

關(guān)鍵詞:

精選 導讀

募資55億港元萬物云啟動招股 預計9月29日登陸港交所主板

萬科9月19日早間公告,萬物云當日啟動招股,預計發(fā)行價介乎每股47 1港元至52 7港元,預計9月29日登陸港交所主板。按發(fā)行1 167億股計算,萬

發(fā)布時間: 2022-09-20 10:39
管理   2022-09-20

公募基金二季度持股情況曝光 隱形重倉股多為高端制造業(yè)

隨著半年報披露收官,公募基金二季度持股情況曝光。截至今年二季度末,公募基金全市場基金總數(shù)為9794只,資產(chǎn)凈值為269454 75億元,同比上

發(fā)布時間: 2022-09-02 10:45
資訊   2022-09-02

又有上市公司宣布變賣房產(chǎn) 上市公司粉飾財報動作不斷

再有上市公司宣布變賣房產(chǎn)。四川長虹25日稱,擬以1 66億元的轉(zhuǎn)讓底價掛牌出售31套房產(chǎn)。今年以來,A股公司出售房產(chǎn)不斷。根據(jù)記者不完全統(tǒng)

發(fā)布時間: 2022-08-26 09:44
資訊   2022-08-26

16天12連板大港股份回復深交所關(guān)注函 股份繼續(xù)沖高

回復交易所關(guān)注函后,大港股份繼續(xù)沖高。8月11日大港股份高開,隨后震蕩走高,接近收盤時觸及漲停,報20 2元 股。值得一提的是,在7月21日

發(fā)布時間: 2022-08-12 09:56
資訊   2022-08-12

萬家基金再添第二大股東 中泰證券擬受讓11%基金股權(quán)

7月13日,中泰證券發(fā)布公告,擬受讓齊河眾鑫投資有限公司(以下簡稱齊河眾鑫)所持有的萬家基金11%的股權(quán),交易雙方共同確定本次交易的標的資

發(fā)布時間: 2022-07-14 09:39
管理   2022-07-14

央行連續(xù)7日每天30億元逆回購 對債市影響如何?

央行12日再次開展了30億元逆回購操作,中標利率2 10%。這已是央行連續(xù)7日每天僅進行30億元的逆回購縮量投放,創(chuàng)下去年1月以來的最低操作規(guī)

發(fā)布時間: 2022-07-13 09:38
資訊   2022-07-13

美元指數(shù)創(chuàng)近20年新高 黃金期貨創(chuàng)出逾9個月新低

由于對美聯(lián)儲激進加息的擔憂,美元指數(shù)11日大漲近1%創(chuàng)出近20年新高。受此影響,歐美股市、大宗商品均走弱,而黃金期貨創(chuàng)出逾9個月新低。美

發(fā)布時間: 2022-07-13 09:36
資訊   2022-07-13

美股三大股指全線下跌 納斯達克跌幅創(chuàng)下記錄以來最大跌幅

今年上半年,美股持續(xù)回落。數(shù)據(jù)顯示,道瓊斯指數(shù)上半年下跌15 3%,納斯達克綜合指數(shù)下跌29 5%,標普500指數(shù)下跌20 6%。其中,納斯達克連續(xù)

發(fā)布時間: 2022-07-04 09:51
推薦   2022-07-04

融資客熱情回升 兩市融資余額月內(nèi)增加超344億元

近期A股走強,滬指6月以來上漲4%,融資客熱情明顯回升。數(shù)據(jù)顯示,截至6月16日,兩市融資余額1 479萬億元,月內(nèi)增加344 67億元,最近一個半

發(fā)布時間: 2022-06-20 09:41
資訊   2022-06-20

4個交易日凈買入超百億元 北向資金持續(xù)流入A股市場

北向資金凈流入態(tài)勢延續(xù)。繼6月15日凈買入133 59億元后,北向資金6月16日凈買入44 52億元。自5月27日至今,除6月13日以外,北向資金累計凈

發(fā)布時間: 2022-06-17 09:37
推薦   2022-06-17