近幾年,數(shù)字驅(qū)動(dòng)的口號(hào)越喊越響,在這樣一個(gè)用數(shù)據(jù)說話的時(shí)代,數(shù)據(jù)在一定程度上決定企業(yè)的業(yè)務(wù)和決策。而從數(shù)據(jù)驅(qū)動(dòng)的方面考慮,多維實(shí)時(shí)數(shù)據(jù)分析系統(tǒng)的重要性也不言而喻。但是當(dāng)數(shù)據(jù)量巨大的情況下,企業(yè)對(duì)數(shù)據(jù)技術(shù)也提出了更高的要求,但是要實(shí)現(xiàn)極低延遲的實(shí)時(shí)計(jì)算和亞秒級(jí)的多維實(shí)時(shí)查詢還是有難度的。
以騰訊看點(diǎn)來說,一天上報(bào)的數(shù)據(jù)量達(dá)到萬億級(jí)的規(guī)模,企業(yè)要如何知道在不同人群的推薦效果怎么樣?在不同地域中最火的內(nèi)容分別是什么?被舉報(bào)最多的內(nèi)容和賬號(hào)是哪些?在某個(gè)時(shí)間段內(nèi)有多少用戶消費(fèi)了內(nèi)容??
在分享一開始,王展雄首先總結(jié)了多維實(shí)時(shí)數(shù)據(jù)分析系統(tǒng)可以解決的主要痛點(diǎn)問題,比如:- 推薦同學(xué)10分鐘前上了一個(gè)推薦策略,想知道在不同人群的推薦效果怎么樣?
- 運(yùn)營(yíng)同學(xué)想知道,在廣東省的用戶中,最火的廣東地域內(nèi)容是哪些?
- 審核同學(xué)想知道,過去5分鐘,游戲類被舉報(bào)最多的內(nèi)容和賬號(hào)是哪些?
- 老板可能想了解,過去10分鐘有多少用戶在看點(diǎn)消費(fèi)了內(nèi)容?
騰訊看點(diǎn)在實(shí)時(shí)數(shù)倉(cāng)與多維實(shí)時(shí)分析系統(tǒng)搭建之前,首先做的就是進(jìn)行調(diào)研,即離線數(shù)據(jù)分析平臺(tái)能否解決以上這些需求?結(jié)論是不能。首先,C端的行為數(shù)據(jù)上報(bào)過來需要經(jīng)過Spark多層離線計(jì)算,把最終結(jié)果初步過ES,初步之后再提供離線數(shù)據(jù)平臺(tái)進(jìn)行查詢。這個(gè)過程延時(shí)最少在3-6小時(shí),目前最常見的就是隔天的查詢。加之騰訊看點(diǎn)的數(shù)據(jù)量大,穩(wěn)定性較弱,離線分析平臺(tái)難以滿足多樣化的需求。此外,企業(yè)內(nèi)部現(xiàn)有的準(zhǔn)實(shí)時(shí)數(shù)據(jù)查詢平臺(tái)的底層技術(shù)用的是Kudu+Impala,Impala雖然是MPP架構(gòu)的大數(shù)據(jù)計(jì)算引擎,并且訪問以列式存儲(chǔ)數(shù)據(jù)的Kudu。但是Kudu+Impala這種通用大數(shù)據(jù)處理框架只是相比Spark+Hdfs這種離線分析框架而言具有速度優(yōu)勢(shì),對(duì)于實(shí)時(shí)數(shù)據(jù)分析場(chǎng)景來說,查詢響應(yīng)的速度和數(shù)據(jù)的延遲仍然比較高,無法滿足實(shí)時(shí)性要求更高的場(chǎng)景,無法提供良好的交互式用戶體驗(yàn)。?
技術(shù)研發(fā)是要根據(jù)企業(yè)的業(yè)務(wù)需求進(jìn)行的,騰訊看點(diǎn)內(nèi)容業(yè)務(wù)的運(yùn)行模式是作者發(fā)布的內(nèi)容被內(nèi)容中心引入,經(jīng)過內(nèi)容審核鏈路,審核結(jié)果啟用或者下架。啟用的內(nèi)容給到推薦系統(tǒng)和運(yùn)營(yíng)系統(tǒng),然后推薦系統(tǒng)和運(yùn)營(yíng)系統(tǒng)將內(nèi)容通過手機(jī)QQ、微信、QQ瀏覽器,還有一些獨(dú)立端的APP進(jìn)行C側(cè)分發(fā)。內(nèi)容分發(fā)給C側(cè)用戶之后,用戶會(huì)產(chǎn)生各種行為,曝光、點(diǎn)擊、舉報(bào)等,通過埋點(diǎn)上報(bào)實(shí)時(shí)接入到消息隊(duì)列中。?
而工程技術(shù)人員接下來要做兩件事,一個(gè)是構(gòu)建騰訊看點(diǎn)的實(shí)時(shí)數(shù)據(jù)倉(cāng)庫(kù),另一個(gè)則是基于OLAP存儲(chǔ)引擎,開發(fā)多維實(shí)時(shí)數(shù)據(jù)分析系統(tǒng)。?? ??
? ? ? ?實(shí)時(shí)數(shù)據(jù)倉(cāng)庫(kù)能夠按照信息流的業(yè)務(wù)場(chǎng)景進(jìn)行內(nèi)部維度關(guān)聯(lián)、用戶畫像關(guān)聯(lián),聚合各種內(nèi)容,提高下游使用實(shí)時(shí)數(shù)據(jù)的便捷性。多維實(shí)時(shí)數(shù)據(jù)分析系統(tǒng)可以實(shí)時(shí)分析系統(tǒng)消費(fèi)了上一輪數(shù)據(jù)實(shí)時(shí)數(shù)據(jù)倉(cāng)庫(kù),然后利用了OLAP存儲(chǔ)計(jì)算引擎,讓海量的數(shù)據(jù)進(jìn)行了高效的存儲(chǔ),提供高性能的查詢。每種方案都有不足,騰訊看點(diǎn)對(duì)比行業(yè)內(nèi)的領(lǐng)先方案,最終選擇最符合企業(yè)業(yè)務(wù)場(chǎng)景的方案。
- 實(shí)時(shí)數(shù)倉(cāng)的選型:騰訊看點(diǎn)選擇了業(yè)界比較成熟的Lambda架構(gòu),Lambda架構(gòu)具有靈活性高、容錯(cuò)性高、成熟度高和遷移成本低眾多有點(diǎn);缺點(diǎn)是實(shí)時(shí)、離線數(shù)據(jù)需要使用兩套代碼,可能業(yè)務(wù)邏輯修改了,但是批次沒有跟上。騰訊看點(diǎn)對(duì)這個(gè)問題的處理方法是每天都進(jìn)行數(shù)據(jù)對(duì)賬工作,如果有異常則進(jìn)行告警。
- 實(shí)時(shí)計(jì)算引擎選型:選擇了Flink作為實(shí)時(shí)計(jì)算引擎。因?yàn)镕link設(shè)計(jì)之初就是為了流處理,此外,F(xiàn)link還具有Exactly-once的準(zhǔn)確性、輕量級(jí)Checkpoint容錯(cuò)機(jī)制、低延時(shí)高吞吐和易用性高的特點(diǎn),是最佳選擇。
- 實(shí)時(shí)存儲(chǔ)引擎選型:騰訊看點(diǎn)的業(yè)務(wù)對(duì)維度索引、支持高并發(fā)、預(yù)聚合、高性能實(shí)時(shí)多維OLAP查詢有要求,而Hbase、Tdsql和ES都不能滿足。Druid存在按照時(shí)序劃分Segment的缺陷,無法將同一個(gè)內(nèi)容,存放在同一個(gè)Segment上,計(jì)算全局TopN只能是近似值。綜合對(duì)比,最終選擇了MPP數(shù)據(jù)庫(kù)引擎ClickHouse。
04設(shè)計(jì)目標(biāo)與設(shè)計(jì)難點(diǎn)分析
騰訊看點(diǎn)的多維實(shí)時(shí)數(shù)據(jù)分析系統(tǒng)分為三大模塊:實(shí)時(shí)計(jì)算引擎、實(shí)時(shí)存儲(chǔ)引擎、App層。
難點(diǎn)主要在實(shí)時(shí)計(jì)算引擎和實(shí)時(shí)存儲(chǔ)引擎兩個(gè)模塊:要實(shí)現(xiàn)千萬級(jí)/s的海量數(shù)據(jù)實(shí)時(shí)接入,并且進(jìn)行極低延遲的實(shí)時(shí)維表關(guān)聯(lián);實(shí)現(xiàn)高并發(fā)寫入、高可用分布式和高性能索引查詢。
? ? ? ?
? ? ? ?
王展雄指出,騰訊看點(diǎn)的前端采用的是開源組件Ant Design,利用了Nginx服務(wù)器,部署靜態(tài)頁(yè)面,并反向代理了瀏覽器的請(qǐng)求到后臺(tái)服務(wù)器上。?
后臺(tái)服務(wù)是基于騰訊自研的RPC后臺(tái)服務(wù)框架寫的,并且會(huì)進(jìn)行一些二級(jí)緩存。
? ? ? ?
? ? ? ?
實(shí)時(shí)數(shù)倉(cāng)部分,分為了接入層、實(shí)時(shí)計(jì)算層和實(shí)時(shí)數(shù)倉(cāng)存儲(chǔ)層。?
實(shí)時(shí)存儲(chǔ)部分分為實(shí)時(shí)寫入層、OLAP存儲(chǔ)層和后臺(tái)接口層。
實(shí)時(shí)寫入層主要是負(fù)責(zé)Hash路由將數(shù)據(jù)寫入;
OLAP存儲(chǔ)層利用MPP存儲(chǔ)引擎,設(shè)計(jì)符合業(yè)務(wù)的索引和物化視圖,高效存儲(chǔ)海量數(shù)據(jù);
后臺(tái)接口層提供高效的多維實(shí)時(shí)查詢接口。
實(shí)時(shí)計(jì)算分為實(shí)時(shí)關(guān)聯(lián)和實(shí)時(shí)數(shù)倉(cāng)。?
1 、實(shí)時(shí)高性能維表關(guān)聯(lián)?
在實(shí)時(shí)高性能維表關(guān)聯(lián)上,王展雄指出,百萬級(jí)/s的實(shí)時(shí)數(shù)據(jù)流,如果直接去關(guān)聯(lián)HBase,1分鐘的數(shù)據(jù),關(guān)聯(lián)完HBase耗時(shí)是小時(shí)級(jí)的,會(huì)導(dǎo)致數(shù)據(jù)延遲嚴(yán)重。為此,騰訊看點(diǎn)提出了以下幾個(gè)解決方案:- 第一個(gè)是,在Flink實(shí)時(shí)計(jì)算環(huán)節(jié),先按照1分鐘進(jìn)行了窗口聚合,將窗口內(nèi)多行行為數(shù)據(jù)轉(zhuǎn)一行多列的數(shù)據(jù)格式,經(jīng)過這一步操作,原本小時(shí)級(jí)的關(guān)聯(lián)耗時(shí)下降到了十幾分鐘,但是還是不夠的。
?? ? ?
? ? ? ?
- 第二個(gè)是,在訪問HBase內(nèi)容之前設(shè)置一層Redis緩存,因?yàn)?000條數(shù)據(jù)訪問HBase是秒級(jí)的,而訪問Redis是毫秒級(jí)的,訪問Redis的速度基本是訪問HBase的1000倍。為了防止過期的數(shù)據(jù)浪費(fèi)緩存,緩存過期時(shí)間設(shè)置成24小時(shí),同時(shí)通過監(jiān)聽寫HBase Proxy來保證緩存的一致性,并將訪問時(shí)間從十幾分鐘變成了秒級(jí)。
- 第三個(gè)是,上報(bào)過程中會(huì)上報(bào)不少非常規(guī)內(nèi)容ID,這些內(nèi)容ID在內(nèi)容HBase中是不存儲(chǔ)的,會(huì)造成緩存穿透的問題。所以在實(shí)時(shí)計(jì)算的時(shí)候,系統(tǒng)直接過濾掉這些內(nèi)容ID,防止緩存穿透,又減少一些時(shí)間。
- 第四個(gè)是,因?yàn)樵O(shè)置了定時(shí)緩存,會(huì)引入一個(gè)緩存雪崩的問題。為了防止雪崩,我們在實(shí)時(shí)計(jì)算中,進(jìn)行了削峰填谷的操作,錯(cuò)開設(shè)置緩存的時(shí)間。
?
優(yōu)化后,數(shù)據(jù)量從百億級(jí)減少到了十億級(jí),耗時(shí)從小時(shí)級(jí)減少到了數(shù)十秒,減少99%。?
而實(shí)時(shí)數(shù)倉(cāng)的難度在于,它處于比較新的領(lǐng)域,并且各個(gè)公司各個(gè)業(yè)務(wù)差距比較大,要設(shè)計(jì)出方便,好用,符合看點(diǎn)業(yè)務(wù)場(chǎng)景的實(shí)時(shí)數(shù)倉(cāng)是有難度的。?
實(shí)時(shí)數(shù)倉(cāng)對(duì)外就是幾個(gè)消息隊(duì)列,不同的消息隊(duì)列里面存放的就是不同聚合粒度的實(shí)時(shí)數(shù)據(jù),包括內(nèi)容ID、用戶ID、C側(cè)行為數(shù)據(jù)、B側(cè)內(nèi)容維度數(shù)據(jù)和用戶畫像數(shù)據(jù)等。騰訊看點(diǎn)搭建數(shù)倉(cāng)通過上面介紹的實(shí)時(shí)計(jì)算引擎的輸出,放到消息隊(duì)列中保存,可以提供給下游多用戶復(fù)用。在沒有數(shù)倉(cāng)的時(shí)候,需要消費(fèi)千萬級(jí)/s的原始隊(duì)列,進(jìn)行復(fù)雜的數(shù)據(jù)清洗,然后再進(jìn)行用戶畫像關(guān)聯(lián)、內(nèi)容維度關(guān)聯(lián),才能拿到符合要求格式的實(shí)時(shí)數(shù)據(jù),開發(fā)和擴(kuò)展的成本都會(huì)比較高,如果想開發(fā)一個(gè)新的應(yīng)用,又要走一遍這個(gè)流程。有了數(shù)倉(cāng)之后,如果想開發(fā)內(nèi)容ID粒度的實(shí)時(shí)應(yīng)用,就直接申請(qǐng)TPS萬級(jí)/s的DWS層的消息隊(duì)列。開發(fā)成本變低很多,資源消耗小很多,可擴(kuò)展性也強(qiáng)很多。開發(fā)騰訊看點(diǎn)系統(tǒng)的實(shí)時(shí)數(shù)據(jù)大屏,原本需要進(jìn)行如上所有操作,才能拿到數(shù)據(jù)。現(xiàn)在只需要消費(fèi)DWS層消息隊(duì)列,寫一條Flink SQL即可,僅消耗2個(gè)cpu核心,1G內(nèi)存??梢钥吹?,以50個(gè)消費(fèi)者為例,建立實(shí)時(shí)數(shù)倉(cāng)前后,下游開發(fā)一個(gè)實(shí)時(shí)應(yīng)用,可以減少98%的資源消耗。包括計(jì)算資源,存儲(chǔ)資源,人力成本和開發(fā)人員學(xué)習(xí)接入成本等等。并且消費(fèi)者越多,節(jié)省越多。就拿Redis存儲(chǔ)這一部分來說,一個(gè)月就能省下上百萬人民幣。
表引擎以什么方式存儲(chǔ)?以什么方式加載?以及數(shù)據(jù)表又有什么特性?這些問題都與實(shí)時(shí)儲(chǔ)存技術(shù)相關(guān)。?
騰訊看點(diǎn)聽取了Clickhouse官方的建議,借助ZK實(shí)現(xiàn)高可用的方案。數(shù)據(jù)寫入一個(gè)分片,僅寫入一個(gè)副本,然后再寫ZK,通過ZK告訴同一個(gè)分片的其他副本,其他副本再過來拉取數(shù)據(jù)。ZK更加輕量級(jí),寫的時(shí)候,任意寫一個(gè)副本,其它副本都能夠通過ZK獲得一致的數(shù)據(jù)。此外,即便其它節(jié)點(diǎn)第一次來獲取數(shù)據(jù)失敗了,后面只要發(fā)現(xiàn)它跟ZK上記錄的數(shù)據(jù)不一致,就會(huì)再次嘗試獲取數(shù)據(jù),保證數(shù)據(jù)一致性。?
王展雄先生指出,數(shù)據(jù)寫入遇到的第一個(gè)問題是,海量數(shù)據(jù)直接寫入Clickhouse的話,會(huì)導(dǎo)致ZK的QPS太高,解決方案是改用Batch方式寫入。Batch設(shè)置多大呢,Batch太小的話緩解不了ZK的壓力,Batch也不能太大,不然上游內(nèi)存壓力太大,通過實(shí)驗(yàn),最終選用了大小幾十萬的Batch。?
第二個(gè)問題是,如果采取默認(rèn)方案,隨著數(shù)據(jù)量的增長(zhǎng),會(huì)造成單臺(tái)機(jī)器出現(xiàn)磁盤的瓶頸,在合并的過程中會(huì)存在寫放大的問題,加重磁盤壓力。峰值每分鐘幾千萬條數(shù)據(jù),寫完耗時(shí)幾十秒,如果正在做Merge,就會(huì)阻塞寫入請(qǐng)求,查詢也會(huì)非常慢。為此騰訊看點(diǎn)做了兩個(gè)優(yōu)化方案:一是對(duì)磁盤做Raid,提升磁盤的IO;二是在寫入之前進(jìn)行分表,直接分開寫入到不同的分片上,磁盤壓力直接變?yōu)?/N。?
第三個(gè)問題是,雖然寫入按照分片進(jìn)行了劃分,但是存在一個(gè)分布式系統(tǒng)常見的問題,就是局部的Top并非全局Top的問題,導(dǎo)致匯總的時(shí)候,會(huì)丟失一部分?jǐn)?shù)據(jù),影響最終結(jié)果。騰訊看點(diǎn)內(nèi)部在寫入之前加上一層路由,將同一個(gè)內(nèi)容ID的記錄,全部路由到同一個(gè)分片上,解決了該問題。?
Clickhouse高性能查詢的一個(gè)關(guān)鍵點(diǎn)是稀疏索引。稀疏索引這個(gè)設(shè)計(jì)就很有講究,設(shè)計(jì)得好可以加速查詢,設(shè)計(jì)不好反而會(huì)影響查詢效率。騰訊看點(diǎn)根據(jù)自身的業(yè)務(wù)場(chǎng)景,針對(duì)某個(gè)內(nèi)容的查詢,建立稀疏索引之后,可以減少99%的文件掃描。但是騰訊看點(diǎn)的數(shù)據(jù)量太大,維度太多,如果一次性把所有維度進(jìn)行預(yù)聚合,數(shù)據(jù)量會(huì)指數(shù)膨脹,查詢反而變慢,并且會(huì)占用大量?jī)?nèi)存空間。針對(duì)不同的維度,騰訊看點(diǎn)建立對(duì)應(yīng)的預(yù)聚合物化視圖,用空間換時(shí)間,縮短查詢時(shí)間。?
此外,分布式表查詢還有一個(gè)問題,查詢單個(gè)內(nèi)容ID的信息,分布式表會(huì)將查詢下發(fā)到所有的分片上,然后再返回查詢結(jié)果進(jìn)行匯總。實(shí)際上,因?yàn)樽鲞^路由,一個(gè)內(nèi)容ID只存在于一個(gè)分片上,剩下的分片都在空跑。針對(duì)這類查詢,騰訊看點(diǎn)的優(yōu)化方案是后臺(tái)按照同樣的規(guī)則先進(jìn)行路由,直接查詢目標(biāo)分片,這樣減少了N-1/N的負(fù)載,可以大量縮短查詢時(shí)間。而且由于我們是提供的OLAP查詢,數(shù)據(jù)滿足最終一致性即可,通過主從副本讀寫分離,可以進(jìn)一步提升性能。在后臺(tái)再做一個(gè)1分鐘的數(shù)據(jù)緩存,針對(duì)相同條件查詢,后臺(tái)就直接返回了。?? ? ??
? ? ? ?
分享最后,王展雄指出,騰訊看點(diǎn)的實(shí)時(shí)分析系統(tǒng)力亞秒級(jí)的響應(yīng)查詢請(qǐng)求,在未命中緩存情況下,過去30分鐘的查詢,99%的請(qǐng)求耗時(shí)在1秒內(nèi);過去24小時(shí)的查詢,90%的請(qǐng)求耗時(shí)在5秒內(nèi),99%的請(qǐng)求耗時(shí)在10秒內(nèi)。點(diǎn)擊文末閱讀原文,立即了解易觀開發(fā)者生態(tài)。