實(shí)時(shí)計(jì)算 | 2021年網(wǎng)易云音樂(lè)實(shí)時(shí)計(jì)算平臺(tái)發(fā)展和挑戰(zhàn)

網(wǎng)易云音樂(lè)實(shí)時(shí)數(shù)倉(cāng)平臺(tái)上線以后,經(jīng)過(guò)一年半的發(fā)展,整體實(shí)時(shí)數(shù)倉(cāng)已經(jīng)初具規(guī)模,我們已有實(shí)時(shí)數(shù)倉(cāng)表300+,運(yùn)行中的任務(wù)數(shù)有1200+。其中1000左右的任務(wù)是SQL任務(wù), Kafka總出口流量達(dá)到到18GB/S,總用戶數(shù)達(dá)到了200+。
數(shù)據(jù)量和用戶的增長(zhǎng)也給數(shù)據(jù)平臺(tái)的易用性以及穩(wěn)定性帶來(lái)了了越來(lái)越多的挑戰(zhàn),包含Kafka的穩(wěn)定性、集群的穩(wěn)定性、運(yùn)維工作的挑戰(zhàn)以及很多早期的技術(shù)債;業(yè)務(wù)的增長(zhǎng),暴露出了基建的薄弱,也給我們積累了很多平臺(tái)建設(shè)和運(yùn)維的經(jīng)驗(yàn)。
我們平臺(tái)整體的的功能大家可以參考《云音樂(lè)實(shí)時(shí)數(shù)倉(cāng)技術(shù)改造以及未來(lái)的一些規(guī)劃》,這里將主要介紹我們最新的一些工作:
“我的任務(wù)延遲了,怎么擴(kuò)容都不行,這是為什么?”
在日常運(yùn)維工作中這是我們經(jīng)常遇到的問(wèn)題,往往也是比較耗費(fèi)時(shí)間的問(wèn)題。導(dǎo)致這種這種問(wèn)題的原因有很多,為了解決這個(gè)問(wèn)題,我們做了一些工作來(lái)增強(qiáng)我們的運(yùn)維能力。
IO指標(biāo)完善
IO問(wèn)題是導(dǎo)致以上問(wèn)題經(jīng)常出現(xiàn)的原因之一,包含消息讀取效率、維表JOIN效率、SINK效率等等,第三方存儲(chǔ)的性能以及穩(wěn)定性,直接影響實(shí)時(shí)任務(wù)的穩(wěn)定性,為了快速定位相關(guān)問(wèn)題,我們添加了很多IO相關(guān)Metric指標(biāo)。

1. Kafka消費(fèi)側(cè)的一些性能指標(biāo)

2. 讀取反序列化指標(biāo)
包含:
反序列化的RT
反序列化的錯(cuò)誤比例
在Format側(cè)我們開(kāi)發(fā)了一套Format代理,支持在不修改原有format代碼的情況下,上報(bào)相關(guān)metirc指標(biāo),忽略錯(cuò)誤數(shù)據(jù)等功能。只要添加屬性format.proxy指定代理類就可以支持不同方式的Format封裝。
比如我們指定format.proxy=magina,就可以支持上報(bào)上述的性能指標(biāo);指定format.proxy=ds 就可以支持解析ds封裝的日志格式,使用被代理的Format解析DS中的Body部分,不需要單獨(dú)為DS封裝的日志格式開(kāi)發(fā)Format,且同樣會(huì)上報(bào)性能相關(guān)指標(biāo),支持忽略錯(cuò)誤消息等功能。
3. 維表JOIN相關(guān)指標(biāo)
在維表JOIN側(cè), 我們添加了:
數(shù)據(jù)查詢的響應(yīng)時(shí)間
本地緩存的命中率
查詢發(fā)生重試的比例
成功JOIN上的數(shù)據(jù)的比例等
5. 數(shù)據(jù)寫(xiě)入的一些性能指標(biāo)
數(shù)據(jù)序列化的RT
數(shù)據(jù)寫(xiě)入外部數(shù)據(jù)源的平均響應(yīng)時(shí)間等
整套IO相關(guān)指標(biāo)的實(shí)現(xiàn),我們?nèi)渴窃贔link Connector的頂層接口做了一些公共的封裝,重構(gòu)了相關(guān)Connector的代碼,只要按照我們自己的接口實(shí)現(xiàn)Connector,無(wú)需關(guān)心細(xì)節(jié)指標(biāo)的上報(bào),這些指標(biāo)都會(huì)自動(dòng)化的上報(bào)出來(lái)。
Kafka分區(qū)問(wèn)題
Kafka分區(qū)的限制也是經(jīng)常導(dǎo)致我們程序性能無(wú)法擴(kuò)展的原因,出于Exactly Once的實(shí)現(xiàn)、讀取性能、以及讀取穩(wěn)定性的考慮,F(xiàn)link采用主動(dòng)拉取的方式讀取Kafka消息,這種方式限制了我們讀取Kafka消息的任務(wù)數(shù),大大限制我們?nèi)蝿?wù)性能的擴(kuò)張能力,以下面這個(gè)case為例:
SET 'table.exec.state.ttl' = '1h';SET 'table.exec.mini-batch.enabled' = 'true';SET 'table.exec.mini-batch.allow-latency' = '10s';SET 'table.exec.mini-batch.size' = '100000';INSERT INTO music_kudu_online.music_kudu_internal.ads_ab_rtrs_user_metric_hourSELECTfrom_unixtime(`timestamp`, 'yyyy-MM-dd') as dt,from_unixtime(`timestamp`, 'HH') as `hour`,os, sceneid, parent_exp, `exp`, exp_type, userid,count(1) pvFROM iplay_ods.ods_rtrs_ab_logINNER JOIN abtest_online.abtest.abtest_sence_metric_relationFOR SYSTEM_TIME AS OF user_metric.proctimeON ods_rtrs_ab_log.sceneid = abtest_sence_metric_relation.sceneidGROUP BY from_unixtime(`timestamp`, 'yyyy-MM-dd'),from_unixtime(`timestamp`, ‘HH’),os, sceneid, parent_exp, `exp`, exp_type, userid
這是一個(gè)實(shí)時(shí)全聚合任務(wù),在原始的FLINK中這段SQL執(zhí)行的DAG大概是這樣的:

假如我們讀取的流表ods_rtrs_ab_log有5個(gè)分區(qū),我們的SQL任務(wù)有七個(gè)并發(fā),因?yàn)槭艿?span style="font-size: 15px;">Kafka分區(qū)數(shù)的影響,加上FLINK本身作業(yè)鏈的優(yōu)化,我們的消息的讀取、維表JOIN、MINI BATCH的操作全部受到了Kafka分區(qū)的影響,無(wú)法擴(kuò)展,特別是對(duì)于維表JOIN這種IO操作來(lái)說(shuō),任務(wù)的并發(fā)度嚴(yán)重影響了整體程序的性能,這個(gè)時(shí)候我只能通過(guò)擴(kuò)容Kafka的分區(qū)數(shù)來(lái)提升性能。
但是這種操作非常重,而且很有可能會(huì)影響其它讀取這張流表的任務(wù);為了解決這個(gè)問(wèn)題,我們對(duì)Kafka的Connector做了一些改造,支持通過(guò)配置多添加一步Shuffle操作,比如在上面的配置當(dāng)中我們添加了配置:
'connector.rebalance.keys' = 'sceneid,parent_exp,userid'消息會(huì)在讀取以后按照sceneid,parent_exp,userid等字段進(jìn)行hash分片,這樣大大提高了整體程序的性能擴(kuò)展性,而且通過(guò)指定字段的keyBy操作,可以大大提高維表JOIN緩存的命中率,提高M(jìn)INI BATCH的性能和效率。

除了以上配置以外,我們還支持添加隨機(jī)的Rebalance操作、Rescale操作以及解析行為的拆解,來(lái)進(jìn)一步提升整體程序性能的擴(kuò)展,這里需要注意的是額外Shuffle操作,會(huì)帶來(lái)更多線程和網(wǎng)絡(luò)開(kāi)銷,在配置這些操作的同時(shí)需要同時(shí)關(guān)注機(jī)器的負(fù)載情況,添加額外的Shuffle操作雖然能提升程序的擴(kuò)展性,但是由于額外網(wǎng)絡(luò)和線程開(kāi)銷,如果機(jī)器本身性能不行的話,很有可能會(huì)適得其反,在相同的資源情況下性能變得更差,這點(diǎn)需要根據(jù)自己程序以及環(huán)境情況進(jìn)行配置。
Kafka使用優(yōu)化
隨著流量的飛速增長(zhǎng)Kafka的穩(wěn)定性也是我們面臨的主要難題,包括Kafka的機(jī)柜帶寬問(wèn)題、跨機(jī)房帶寬問(wèn)題、Kafka擴(kuò)縮容的抖動(dòng)問(wèn)題、還有Kafka本身配置問(wèn)題等等,基本上大家能遇到的問(wèn)題我們都遇到了,為了解決以上問(wèn)題我們做了以下工作:
1. 開(kāi)發(fā)鏡像服務(wù),解決帶寬問(wèn)題,保障高優(yōu)先級(jí)任務(wù)

我們通過(guò)FLINK自己開(kāi)發(fā)了一套鏡像服務(wù),在不同的機(jī)房模塊間分別部署了一套Kafka集群,通過(guò)鏡像服務(wù)同步兩套Kafak集群的數(shù)據(jù),主Kafka提供給比較重要P0級(jí)別的實(shí)時(shí)任務(wù),其它不是特別重要的任務(wù)讀取鏡像集群的數(shù)據(jù)。
我們通過(guò)Yarn Label技術(shù),通過(guò)不同隊(duì)列的選擇來(lái)控制任務(wù)所在的機(jī)房,來(lái)減少跨機(jī)房帶寬的消耗,為了方便用戶切換不同的Kafka集群,我們?cè)贔link流表側(cè)也做了一些改造,支持一張流表同時(shí)掛載多個(gè)Kafka集群,只要通過(guò)簡(jiǎn)單的配置就可以隨意切換Kafka集群,經(jīng)過(guò)一輪任務(wù)整理和切換,Kafka帶寬使用情況有了大大的改善:

2. Kafka監(jiān)控完善
在日常的工作中,我們發(fā)現(xiàn)很多開(kāi)發(fā)對(duì)Kafka本身并不太了解,運(yùn)維由于經(jīng)驗(yàn)的不足在初期對(duì)整體Kafka的管控也不是那么的嚴(yán)格,導(dǎo)致在使用上有很多問(wèn)題。所以我們整合了音樂(lè)內(nèi)部的Kafka監(jiān)控服務(wù)的數(shù)據(jù),結(jié)合我們平臺(tái)的任務(wù)血緣,開(kāi)發(fā)了自己的一套Kafka監(jiān)控服務(wù)。
目前這套系統(tǒng)整體還比較初級(jí),除了關(guān)聯(lián)了Kafka、流表、和任務(wù)之間的關(guān)系以外,我們還對(duì)以下這幾種情況做了主動(dòng)監(jiān)控:
Kafka Topic的分區(qū)數(shù)的合理性,主要監(jiān)控消息隊(duì)列分區(qū)數(shù)過(guò)少或者過(guò)多的情況,主要是過(guò)少的情況,防止因?yàn)榉謪^(qū)數(shù)過(guò)小,下游任務(wù)處理性能跟不上的問(wèn)題;
Kafka分區(qū)數(shù)據(jù)生產(chǎn)均衡問(wèn)題:防止因?yàn)?span style="font-size: 15px;">Kafka本身分區(qū)數(shù)據(jù)的不均衡導(dǎo)致下游任務(wù)處理性能不行的問(wèn)題;
Kafka分區(qū)數(shù)據(jù)消費(fèi)均衡問(wèn)題:防止因?yàn)?span style="font-size: 15px;">Kafka本身分區(qū)發(fā)生變化,而下游任務(wù)因?yàn)闆](méi)有開(kāi)啟分區(qū)感知,導(dǎo)致一些數(shù)據(jù)沒(méi)有消費(fèi)到等問(wèn)題;
流量激增和激降報(bào)警:關(guān)鍵隊(duì)列流量報(bào)警,保障實(shí)時(shí)數(shù)據(jù)的質(zhì)量。
Kafka版本升級(jí):為了解決本身Kafka擴(kuò)容的穩(wěn)定性問(wèn)題、資源隔離問(wèn)題,通過(guò)我們音樂(lè)公共技術(shù)團(tuán)隊(duì),在Kafka 2.X版本基礎(chǔ)上做了一些二次開(kāi)發(fā)工作,將Kafka整個(gè)服務(wù)做了平臺(tái)化的支持,支持了Topic的平滑擴(kuò)所容,支持資源隔離。
類似YARN的LAEBL技術(shù),支持針對(duì)不同的TOPIC劃分不同region的機(jī)器,完善的消息鏡像服務(wù),且支持offset的復(fù)制;統(tǒng)一的Kafka運(yùn)維監(jiān)控平臺(tái),此部分內(nèi)容后續(xù)文章會(huì)詳細(xì)介紹。
3. 分區(qū)流表技術(shù)建設(shè)
實(shí)時(shí)數(shù)倉(cāng)上線以后,我們發(fā)現(xiàn)以下幾種情況非常影響程序的穩(wěn)定性以及流表的易用性:
(1)很多時(shí)候我們只需要一張流表中1%的數(shù)據(jù),但是因?yàn)闆](méi)有辦法按需讀取,所以我們必須消耗大量的資源去解析讀取另外99%的數(shù)據(jù),導(dǎo)致了大量的資源帶寬的消耗,浪費(fèi)了大量的資源,而且本身SQL的開(kāi)發(fā)方式本身沒(méi)有辦法按需解析日志,導(dǎo)致我們必須完整的解析出每一條消息,這就導(dǎo)致進(jìn)一步的計(jì)算資源的消耗。
(2)當(dāng)我們按照經(jīng)驗(yàn)和業(yè)務(wù),將大的TOPIC拆分成很多小的TOPIC時(shí),一張表變成了很多小表,使用者又必須有很多的經(jīng)驗(yàn)知識(shí)去了解這些schema完全相同的小表中分別包含了哪些消息,易用性很差,這樣的設(shè)計(jì)也不符合數(shù)倉(cāng)的整體設(shè)計(jì)邏輯,以后如果要做批流表統(tǒng)一元數(shù)據(jù)的時(shí)候,整體也變得不太可能
在離線場(chǎng)景下我們很有很多手段來(lái)解決以上問(wèn)題,減少不必要的IO,如數(shù)據(jù)的分桶、存儲(chǔ)有序的數(shù)據(jù)利用Parquet的下推查詢的能力、做分區(qū)表等手段都可以解決以上問(wèn)題。但是實(shí)時(shí)表的Case下在現(xiàn)有的公開(kāi)的方案中好像并沒(méi)有什么好的方法;所以為了解決以上問(wèn)題,我們開(kāi)發(fā)了流表的分區(qū)方案,整體和HIVE表的分區(qū)實(shí)現(xiàn)思想差不多:

我們使用Flink Table Souce提供的SupportsFilterPushDown的接口實(shí)現(xiàn)了一套自己的實(shí)時(shí)流表分區(qū)方案,一個(gè)分區(qū)對(duì)應(yīng)一個(gè)topic,通過(guò)用戶的查詢條件下推過(guò)濾掉沒(méi)有必要的分區(qū),從而減少?zèng)]有必要的數(shù)據(jù)的讀取;目前已經(jīng)上線了第一版,初步拆分了云音樂(lè)曝光日志,順便還嘗試使用AVRO的數(shù)據(jù)格式代替以前的JSON格式,實(shí)踐下來(lái)優(yōu)化效果明顯:
(1)使用AVRO格式格式基本都能帶來(lái)至少30+%的的帶寬優(yōu)化,消息解析性能相對(duì)音樂(lè)的原始日志格式的解析性能提升一倍.
(2)使用分區(qū)流表,我們初步遷移了了4個(gè)曝光日志的消費(fèi)任務(wù),已經(jīng)節(jié)省了7臺(tái)物理機(jī),平均節(jié)省計(jì)算和帶寬資源75%以上。

雖然這些都是比較極端的Case,但是從這些例子我們可以預(yù)計(jì)分區(qū)流表技術(shù)全面鋪開(kāi)以后,使用得到的話,絕對(duì)是一個(gè)能帶來(lái)質(zhì)變的優(yōu)化。
數(shù)據(jù)實(shí)時(shí)化一直是我們?cè)埔魳?lè)數(shù)據(jù)平臺(tái)團(tuán)隊(duì)數(shù)倉(cāng)建設(shè)的一個(gè)比較大的目標(biāo),在這個(gè)目標(biāo)的背后批流一體也是我們繞不開(kāi)一個(gè)“名詞”、“概念”、“技術(shù)”、或者是個(gè)“產(chǎn)品”。在正式開(kāi)始分享我們的工作以前,首先分享下我有一次在電梯間遇到算法同學(xué),然后和算法同學(xué)發(fā)生的對(duì)話:
算法:你們的批流一體什么時(shí)候上線?我們等著用呢?
我: 你們目前的訴求是什么呢?
算法:我們現(xiàn)在很多實(shí)時(shí)指標(biāo)都是自己開(kāi)發(fā),沒(méi)法在離線以后直接使用現(xiàn)成數(shù)倉(cāng)數(shù)據(jù)。
從這段對(duì)話我們可以看出,算法同學(xué)并不是想要什么批流一體的技術(shù),他們想要的是實(shí)時(shí)的現(xiàn)成的可用的數(shù)倉(cāng)數(shù)據(jù),來(lái)提升他們的開(kāi)發(fā)效率,批流一體的背后,不同角色的業(yè)務(wù)方的訴求是什么呢?
對(duì)于運(yùn)營(yíng)、產(chǎn)品、老板、分析師們來(lái)說(shuō):
他們想要看到的是準(zhǔn)確的實(shí)時(shí)的可分析的報(bào)表數(shù)據(jù),關(guān)鍵點(diǎn)在于可分析上。當(dāng)結(jié)果數(shù)據(jù)發(fā)生異常波動(dòng)時(shí),我們得有實(shí)時(shí)的明細(xì)數(shù)據(jù)提供分析查詢,來(lái)調(diào)查發(fā)生異常波動(dòng)的原因。當(dāng)老板有一些新的想法,想對(duì)現(xiàn)成的報(bào)表做下二次分析時(shí),我們得有能力提供明細(xì)的可分析的數(shù)據(jù)來(lái)做分析給出結(jié)果。
以實(shí)時(shí)日活統(tǒng)計(jì)來(lái)說(shuō),我們常用的手段是將用戶ID存儲(chǔ)的Redis這樣KV存儲(chǔ)當(dāng)中來(lái)做去重,或者近似去重,然后計(jì)算得出實(shí)時(shí)的日活數(shù)據(jù),但是當(dāng)日活發(fā)生異常波動(dòng)時(shí),因?yàn)镽eids的數(shù)據(jù)不是可分析的。所以我們很難快速給出原因,也沒(méi)法在當(dāng)天做分析,這種方案和結(jié)果顯然是不合格的。
對(duì)于數(shù)倉(cāng)開(kāi)發(fā)來(lái)說(shuō):
統(tǒng)一實(shí)時(shí)/離線數(shù)倉(cāng)元數(shù)據(jù)管理、統(tǒng)一模型、統(tǒng)一存儲(chǔ),減少數(shù)倉(cāng)運(yùn)維建設(shè)成本,提升整體數(shù)倉(cāng)的易用性;
統(tǒng)一開(kāi)發(fā)代碼,統(tǒng)一一套SQL解決離線/實(shí)時(shí)開(kāi)發(fā)問(wèn)題,降低開(kāi)發(fā)運(yùn)維成本,徹底解決因?yàn)闃I(yè)務(wù)理解不同、邏輯不同導(dǎo)致的實(shí)時(shí)離線數(shù)據(jù)結(jié)果差異大的問(wèn)題。
對(duì)于算法同學(xué)來(lái)說(shuō):
有實(shí)時(shí)/離線統(tǒng)一的數(shù)倉(cāng)表可以可以用使用,統(tǒng)一模型,降低業(yè)務(wù)理解的門檻,提升整體數(shù)倉(cāng)數(shù)據(jù)的易用性,方便好用的數(shù)倉(cāng)元數(shù)據(jù)管理服務(wù),方便算法同學(xué)進(jìn)行二次的特征開(kāi)發(fā)工作,提升模型的開(kāi)發(fā)效率。提供準(zhǔn)確實(shí)時(shí)可分析的算法模型效果數(shù)據(jù),提升算法同學(xué)模型迭代的效率
整體總結(jié)下來(lái)批流一體的目標(biāo)主要包含三個(gè)方面:
統(tǒng)一代碼:一套SQL完成實(shí)時(shí)和離線的相關(guān)業(yè)務(wù)的開(kāi)發(fā)需求;
統(tǒng)一數(shù)倉(cāng)元數(shù)據(jù):一張表可以同時(shí)提供離線讀和實(shí)時(shí)讀,統(tǒng)一模型的批流一體的數(shù)倉(cāng);
實(shí)時(shí)的報(bào)表數(shù)據(jù):這與統(tǒng)一數(shù)倉(cāng)元數(shù)據(jù)不同,產(chǎn)品報(bào)表數(shù)據(jù)需要提供秒級(jí)的實(shí)時(shí)的結(jié)果的查詢能力,而統(tǒng)一數(shù)倉(cāng)數(shù)據(jù)往往只需要實(shí)時(shí)的存儲(chǔ)即可,對(duì)OLAP查詢的效率,并沒(méi)有報(bào)表數(shù)據(jù)并沒(méi)有那么敏感。
1. 統(tǒng)一代碼
由于實(shí)時(shí)SQL本身并沒(méi)有特別的成熟,很多在離線場(chǎng)景下很容易實(shí)現(xiàn)的邏輯,在實(shí)時(shí)場(chǎng)景下要么是不能實(shí)現(xiàn),要么是穩(wěn)定性有問(wèn)題。
目前業(yè)界都還在探索當(dāng)中,阿里目前主要的方式的是使用FLINK一套引擎解決實(shí)時(shí)離線統(tǒng)一SQL的問(wèn)題,但是目前也都是在實(shí)踐,在上層ADS層業(yè)務(wù)邏輯實(shí)現(xiàn)上通過(guò)底層數(shù)倉(cāng)的建設(shè)屏蔽掉一些實(shí)時(shí)SQL能力的問(wèn)題,做到產(chǎn)品報(bào)表開(kāi)發(fā)上統(tǒng)一一套SQL。這也是我們未來(lái)可以嘗試的方向,除了在上層報(bào)表開(kāi)發(fā)上嘗試統(tǒng)一SQL以外,我們?cè)诮y(tǒng)一代碼這一塊也做了一些工作和規(guī)劃:
(1)統(tǒng)一UDF,集成升級(jí)平臺(tái)框架到FLINK1.12新版本,統(tǒng)一離線實(shí)時(shí)統(tǒng)一套UDF;
(2)統(tǒng)一元數(shù)據(jù)管理:在FlinkSQL側(cè)我們繼承元數(shù)據(jù)中心服務(wù),提供catalog.db.table這樣的數(shù)據(jù)讀取和寫(xiě)入方式,為了統(tǒng)一元數(shù)據(jù),同樣我們對(duì)SparkSQL做了二次的封裝,同樣和元數(shù)據(jù)中心做了集成,實(shí)現(xiàn)了以catalog.db.table這樣形式的異構(gòu)數(shù)據(jù)源之間的讀取和寫(xiě)入。

場(chǎng)景化的配置式的批流一體的統(tǒng)一實(shí)現(xiàn),對(duì)于一些簡(jiǎn)單業(yè)務(wù)邏輯的場(chǎng)景,我們后續(xù)會(huì)開(kāi)發(fā)場(chǎng)景化的批流一體的實(shí)現(xiàn)。如批流一體的索引任務(wù)、批流一體的ETL清洗平臺(tái)等等,這塊由于資源問(wèn)題,目前還在規(guī)劃中。
批流一體SQL統(tǒng)一的在目前的技術(shù)下,還有一個(gè)比較大的前提是本身日志的復(fù)雜程度,這個(gè)涉及到本身日志埋點(diǎn)規(guī)范性和完整性,實(shí)時(shí)計(jì)算不像離線,可以將大量歸因邏輯, 關(guān)聯(lián)邏輯放在數(shù)據(jù)側(cè)進(jìn)行處理,拋開(kāi)合理性和成本問(wèn)題,很多工作在離線場(chǎng)景下是可以做的。
但是在實(shí)時(shí)場(chǎng)景,本身對(duì)性能和穩(wěn)定性都非常的敏感,如果將大量的邏輯都放在數(shù)據(jù)側(cè)進(jìn)行處理,本身就會(huì)帶來(lái)很多不能實(shí)現(xiàn)的問(wèn)題、實(shí)現(xiàn)起來(lái)成本高的問(wèn)題、很多穩(wěn)定性、以及數(shù)據(jù)延遲的問(wèn)題。如果打點(diǎn)做不好,整個(gè)實(shí)時(shí)數(shù)倉(cāng)建設(shè)都是問(wèn)題,所以云音樂(lè)也啟動(dòng)了曙光打點(diǎn)項(xiàng)目和有數(shù)團(tuán)隊(duì)合作,徹底重構(gòu)云音樂(lè)各個(gè)產(chǎn)品的打點(diǎn)的實(shí)現(xiàn),提升和完善打點(diǎn)的規(guī)范性和準(zhǔn)確性,降低實(shí)時(shí)數(shù)倉(cāng)的開(kāi)發(fā)成本問(wèn)題。
2. 統(tǒng)一數(shù)倉(cāng)元數(shù)據(jù)
目前業(yè)界主要有兩類方案:
第一種是建設(shè)批流映射層的方案,目前阿里公開(kāi)的方案的就是這種方案,比較適合已經(jīng)有了實(shí)時(shí)數(shù)倉(cāng)和離線數(shù)倉(cāng)的老產(chǎn)品,在不改動(dòng)原有數(shù)倉(cāng)的情況下,構(gòu)建統(tǒng)一映射層視圖,通過(guò)視圖的方式提供一體化的使用體驗(yàn),整體的原理參考下圖:

第二種方案是構(gòu)建一種新的元數(shù)據(jù)系統(tǒng),一套schema下同時(shí)掛載多種存儲(chǔ),如HDFS、Kafka等,在寫(xiě)入數(shù)據(jù)時(shí)同時(shí)寫(xiě)入,在讀取場(chǎng)景下時(shí),根據(jù)讀取方式的不同,選擇相應(yīng)的合適的存儲(chǔ),目前網(wǎng)易數(shù)帆有數(shù)產(chǎn)品團(tuán)隊(duì)開(kāi)發(fā)的Arctic采用的就是這種方案:

整體思路是封裝icberg和Kafka以及Hbase等多種存儲(chǔ),在不同場(chǎng)景下使用不同的存儲(chǔ),另外arctic還在iceberg的基礎(chǔ)上做了很多二次開(kāi)發(fā),來(lái)解決DWS數(shù)據(jù)的更新問(wèn)題,提供類似Hudi的CopyOnWrite以及MergeOnRead等功能,用來(lái)解決Flink本身用來(lái)做全聚合的穩(wěn)定性問(wèn)題。目前云音樂(lè)已經(jīng)在一些新的業(yè)務(wù)場(chǎng)景做了試用,已經(jīng)上線了幾十張的的批流一體表,大家如果想進(jìn)一步了解arctic可以找網(wǎng)易數(shù)帆有數(shù)實(shí)時(shí)計(jì)算團(tuán)隊(duì)了解,在此不過(guò)多描述。
3. 實(shí)時(shí)的報(bào)表數(shù)據(jù)
提供實(shí)時(shí)的報(bào)表數(shù)據(jù)主要依賴OLAP引擎和存儲(chǔ),存儲(chǔ)側(cè)需要有需要有在提供實(shí)時(shí)的數(shù)據(jù)更新能力的同時(shí),還需要有提供秒級(jí)別數(shù)據(jù)的查詢能力,很多時(shí)候沒(méi)有辦法把將結(jié)果直接寫(xiě)到到存儲(chǔ)中。因?yàn)閿?shù)據(jù)報(bào)表本身很多靈活性的查詢,如果直接將結(jié)果寫(xiě)到存儲(chǔ)中, 就需要類似Kylin那種實(shí)時(shí)的Cube能力,這對(duì)開(kāi)發(fā)以及Flink本身計(jì)算的壓力太大, 本身也會(huì)帶來(lái)很多資源的和存儲(chǔ)的浪費(fèi),穩(wěn)定性問(wèn)題以及開(kāi)發(fā)工作量的問(wèn)題也會(huì)很多,數(shù)據(jù)的二次分析能力也會(huì)很局限;所以在這一層我們需要OLAP引擎提供至少百億級(jí)別的數(shù)據(jù)的秒級(jí)延遲的查詢的能力,目前我們主要的方案采用的存儲(chǔ)有Kudu和Clickhouse兩種,以我們老版本的ABTest為例,我們采用的方案如下:

對(duì)于實(shí)時(shí)的最新的小時(shí)維度以及天維度的結(jié)果我們通過(guò)Impala及時(shí)讀取Kudu數(shù)據(jù)關(guān)聯(lián)出最新的結(jié)果;對(duì)于歷史的一天以前天維度數(shù)據(jù)或者兩個(gè)小時(shí)以前小時(shí)維度的數(shù)據(jù)我們采用Spark預(yù)計(jì)算好存儲(chǔ)在結(jié)果表當(dāng)中,兩份數(shù)據(jù)UNION在一起提供給用戶,保障數(shù)據(jù)結(jié)果的時(shí)效性,以及整體數(shù)據(jù)查詢的用戶體驗(yàn)。
運(yùn)維工具的完善
實(shí)時(shí)SQL的發(fā)展降低了實(shí)時(shí)數(shù)據(jù)統(tǒng)計(jì)的開(kāi)發(fā)難度,大大降低了實(shí)時(shí)數(shù)據(jù)統(tǒng)計(jì)的門檻,一方面由于本身實(shí)時(shí)SQL的不成熟而且黑盒,另一方面很多同學(xué)帶著離線SQL的開(kāi)發(fā)經(jīng)驗(yàn)或者M(jìn)YSQL類數(shù)據(jù)庫(kù)的SQL經(jīng)驗(yàn)來(lái)開(kāi)發(fā)實(shí)時(shí)任務(wù),這給平臺(tái)帶來(lái)了很大的運(yùn)維壓力,所以運(yùn)維工具相關(guān)的建設(shè),任務(wù)實(shí)時(shí)指標(biāo)的完善是我們未來(lái)主要思考的方向之一。
分區(qū)流表技術(shù)完善
分區(qū)流表技術(shù)是一個(gè)能給云音樂(lè)實(shí)時(shí)平臺(tái)資源使用,Kafka壓力以及數(shù)倉(cāng)建設(shè)帶來(lái)質(zhì)變的技術(shù),目前我們只是完成了一個(gè)初版,未來(lái)我們會(huì)在分區(qū)的動(dòng)態(tài)感知,分區(qū)的修改, schema的修改,以及運(yùn)維監(jiān)控以及推廣上繼續(xù)完善。
場(chǎng)景化批流一體建設(shè)
如批流一體索引任務(wù)建設(shè)、批流一體ETL工具等, 統(tǒng)一日志清洗規(guī)則, 為批流一體數(shù)倉(cāng)打好基礎(chǔ)。
批流一體存儲(chǔ)探索
調(diào)研業(yè)界目前的方案, 結(jié)合音樂(lè)的業(yè)務(wù)場(chǎng)景, 提供整套解決方案, 降低實(shí)時(shí)報(bào)表的開(kāi)發(fā)門檻, 提升實(shí)時(shí)報(bào)表的開(kāi)發(fā)效率;
批流一體邏輯層建設(shè)等。
最后附一張網(wǎng)易數(shù)帆有數(shù)團(tuán)隊(duì)的實(shí)時(shí)計(jì)算解決方案架構(gòu)圖,基于 Apache Flink 構(gòu)建的高性能、一站式實(shí)時(shí)大數(shù)據(jù)處理方案,廣泛適用于流式數(shù)據(jù)處理場(chǎng)景,感興趣的同學(xué)可以點(diǎn)擊文末的“閱讀原文”詳細(xì)了解。

大愚,網(wǎng)易云音樂(lè)數(shù)據(jù)平臺(tái)開(kāi)發(fā)專家,主要負(fù)責(zé)云音樂(lè)實(shí)時(shí)、離線、機(jī)器學(xué)習(xí)開(kāi)發(fā)平臺(tái)建設(shè)工作。
贈(zèng)書(shū)福利


