滴滴OLAP的技術(shù)實踐與發(fā)展方向
一、背景介紹:滴滴OLAP的發(fā)展歷程及最終為什么選擇StarRocks
滴滴的OLAP系統(tǒng),早期是基于Druid的實時監(jiān)控系統(tǒng),2017年基于Kylin的離線查詢加速應(yīng)用逐步起步,到2018年后開始全面發(fā)展,Druid、Kylin及Presto并存,用于承接實時監(jiān)控、實時看版、數(shù)據(jù)分析等場景。隨著業(yè)務(wù)的使用量和復(fù)雜度的提升,原有的引擎在性能、穩(wěn)定性、易用性、及維護(hù)成本等多方面,都無法滿足復(fù)雜的業(yè)務(wù)應(yīng)用要求。在2020年前后,滴滴引入了當(dāng)時業(yè)界廣泛使用的ClickHouse引擎,作為開源的OLAP,采用列式存儲模式,號稱比MySQL快1000倍,最大的特色在于向量化的計算引擎,單機(jī)性能很強悍。滴滴基于ClickHouse支持了當(dāng)時的網(wǎng)約車、兩輪車、順風(fēng)車、橙心優(yōu)選等多個業(yè)務(wù)線的實時運營看板、實時分析等場景。經(jīng)過1年多的發(fā)展迭代,ClickHouse和Druid成為了滴滴內(nèi)部主要的OLAP引擎,也讓OLAP在滴滴內(nèi)部逐步發(fā)展起來。
公司內(nèi)部,OLAP的使用場景越來越復(fù)雜,包括監(jiān)控報表、日志分析、離線加速、實時數(shù)倉等場景。隨著用戶需求的持續(xù)增加,對查詢的性能要求也越來越高,基于ClickHouse和Druid的OLAP引擎面臨著以下問題:
其一,維護(hù)困難。針對OLAP場景,滴滴維護(hù)的引擎超過5個,包括Druid、ClickHouse、Kylin、Presto等,每個引擎的使用方法、運維手段差異大,導(dǎo)致運維壓力巨大,后續(xù)發(fā)展遇到瓶頸。
其二,使用不便。每種OLAP引擎的特點都不一樣,如Druid是時序數(shù)據(jù)庫、ClickHouse是計算能力強、但Join關(guān)聯(lián)計算能力較差,各個引擎針對的場景都比較單一,用戶難以根據(jù)業(yè)務(wù)場景來正確選擇合適的引擎。ClickHouse從能用到好用差異巨大,運維難度大,需要投入大量的人力保障才能做到好用。
其三,用戶場景需求難以滿足。比如,很多用戶有修改、刪除數(shù)據(jù)的要求,當(dāng)時的ClickHouse、Druid都不支持;以及,對于高QPS的場景、復(fù)雜查詢、Join等,當(dāng)時的OLAP系統(tǒng)也無法滿足用戶需求。
其四,穩(wěn)定性壓力大。維護(hù)的引擎多,人員相對有限,經(jīng)常出現(xiàn)穩(wěn)定性故障;同時多業(yè)務(wù)運行在同一套集群環(huán)境中,缺少相應(yīng)集群級別的資源隔離機(jī)制,服務(wù)穩(wěn)定性難以保障。
針對實用中遇到的問題,2022年前后,滴滴引入了StarRocks引擎——StarRocks是一個全新一代的、全場景的、MPP數(shù)據(jù)庫;StarRocks使用了向量化、PipeLine引擎、CBO、智能的物化視圖等功能;StarRocks可支持實時更新的歷史數(shù)據(jù)存儲,實現(xiàn)性能強悍的主鍵模型存儲,實現(xiàn)了多維、實時、高并發(fā)的數(shù)據(jù)分析。StarRocks在開源社區(qū)里也非常活躍,增長速度不亞于ClickHouse在前期的發(fā)展。目前在各大互聯(lián)網(wǎng)公司都有廣泛的應(yīng)用。
StarRocks有幾大特點:首先,簡潔的分布式架構(gòu)。沒有外部組件的依賴,有FE、BE兩種角色,可以實現(xiàn)數(shù)據(jù)的水平擴(kuò)展,支持?jǐn)?shù)據(jù)自動均衡處理(ClickHouse需要手動同步處理),將數(shù)據(jù)分片存儲在不同的切片上,實現(xiàn)并行處理和查詢。其次,查詢性能表現(xiàn)比較強,StraRocks使用了列式存儲,支持向量化的引擎,實現(xiàn)了數(shù)據(jù)的并行處理和查詢,對于聚合或Join查詢,相較于ClickHouse也提升顯著。再次,由于架構(gòu)的原因,StarRocks引擎在QPS方面的表現(xiàn),也更優(yōu)于其他引擎。StarRocks還支持了靈活的數(shù)據(jù)模型——支持多種表結(jié)構(gòu),如明細(xì)模型、聚合模型、主鍵模型等;支持多種數(shù)據(jù)類型,如需要去重的Hyperloglog、BITMAP等等類型,可以適用于多種數(shù)據(jù)分析場景。第四,易于使用和管理。StarRocks自身提供了比較簡潔的管理頁面和命令行工具,可以基于集群的角色,對系統(tǒng)進(jìn)行上限、下限的擴(kuò)容等。所有的數(shù)據(jù)均衡、同步、容災(zāi)等,都是在內(nèi)部自動完成的,基本不需要人工的參與。第五,StarRocks支持統(tǒng)一的湖倉架構(gòu)。原生就支持的統(tǒng)一管理、數(shù)據(jù)湖、自身存儲可以支持聯(lián)邦查詢、將Hive、Iceberg、Hudi等,按照外表直接掛在StarRocks上,提供統(tǒng)一的查詢服務(wù)。可以將StarRocks中的實時數(shù)據(jù)、離線維度數(shù)據(jù)進(jìn)行實時關(guān)聯(lián),免去中間數(shù)據(jù)同步的時間開銷,通過一套技術(shù)方案,解決實時數(shù)據(jù)湖倉分析。
從引入StarRocks到現(xiàn)在(截止2023年5月),滴滴已有StarRocks集群超過30個,數(shù)據(jù)量超過300TB,每日查詢量超過400W+,數(shù)據(jù)表超過1500張。支持了滴滴幾乎所有的業(yè)務(wù)線,如網(wǎng)約車、單車、能源、貨運等等。
在平臺建設(shè)方面,主要打通的數(shù)據(jù)鏈路的上下游生態(tài),包括離線/實時的導(dǎo)入——離線導(dǎo)入采用了StarRocks的SparkLoad、實時導(dǎo)入采用Flink的StarRocks Connector導(dǎo)入。也支持基于頁面配置的自動化導(dǎo)入工具,用戶不需要編寫任務(wù),就可以完成簡單的數(shù)據(jù)同步。滴滴還建設(shè)了云原生的運維管控平臺,提供高效的運維管理工具和業(yè)務(wù)交付的能力——支持從業(yè)務(wù)申請創(chuàng)建一個新的集群,到交付給業(yè)務(wù)可用的集群,只需要1小時。
在引擎建設(shè)方面,通過容器化、資源隔離和雙鏈路等機(jī)制,對不同穩(wěn)定性要求的用戶提供針對性的保障手段——目前支持獨立的物理機(jī)群、獨立的容器集群、以及混部在一起的公共集群共存,支持通過不同的成本,來滿足用戶使用的穩(wěn)定性要求。在易用性上,將慢查詢的監(jiān)測告警功能、查詢分析細(xì)分功能開放給用戶,讓用戶有辦法感受到慢查詢,從而開展針對性的調(diào)優(yōu)。在性能方面,目前也在重點大力的推廣物化視圖能力,通過預(yù)處理的能力,為用戶提供更好的性能和更低成本的服務(wù)。
二、視圖加速實時看板:StarRocks項目物化視圖應(yīng)用分享
第二部分,詳細(xì)介紹基于StarRocks的物化視圖對業(yè)務(wù)監(jiān)控看板進(jìn)行加速優(yōu)化。
網(wǎng)約車的實時看版,是滴滴最核心的業(yè)務(wù)監(jiān)控看板,包括實時的呼叫數(shù)、冒泡數(shù)、還有實時的GMV等超過20多個業(yè)務(wù)指標(biāo),支持業(yè)務(wù)、數(shù)據(jù)和運營人員,通過看板數(shù)據(jù)變化,進(jìn)行業(yè)務(wù)趨勢及同環(huán)比的監(jiān)測,發(fā)現(xiàn)業(yè)務(wù)過程問題;支持根據(jù)實時的變化趨勢,來調(diào)整運營策略,從而影響線上行為。
舊版的實時看版基于Druid進(jìn)行配置,使用模糊去重方式進(jìn)行指標(biāo)計算,有一定的計算誤差。在大促期間,同時訪問的用戶數(shù)非常多,查詢并發(fā)過高,會導(dǎo)致集群負(fù)載過高,從而引出穩(wěn)定性問題。
在引入StarRocks之后,希望通過新的技術(shù)來對數(shù)據(jù)加工鏈路進(jìn)行重構(gòu),解決指標(biāo)的準(zhǔn)確性和穩(wěn)定性等應(yīng)用問題。
實時看板場景,有以下幾個明顯的特點:
第一,有大量精確去重的指標(biāo)計算。高精度基數(shù)的精確去重,一直是OLAP的技術(shù)難點,應(yīng)對每天上億規(guī)模明細(xì)數(shù)據(jù)的count(distinct())計算,對計算資源消耗是個大挑戰(zhàn)。
第二,篩選的維度比較靈活。在看板查詢的基礎(chǔ)上,提供多篩選條件,即表的維度字段設(shè)置過濾條件篩選,包括時間、城市、業(yè)務(wù)線等超過十個維度的字段組合,達(dá)到日均千萬級維度組合應(yīng)用場景。
第三,查詢并發(fā)高。在大促期間,所有的數(shù)據(jù)開發(fā)、業(yè)務(wù)運營用戶都會進(jìn)行盯盤,關(guān)注業(yè)務(wù)瞬時變化趨勢,高峰時期有數(shù)百上千規(guī)模的用戶并發(fā)訪問。每分鐘都會進(jìn)行指標(biāo)數(shù)據(jù)刷新,每次刷新都會觸發(fā)大幾十次的查詢計算,高峰時期有數(shù)百個查詢QPS,對集群的負(fù)載要求非常高。若直接使用原始的明細(xì)數(shù)據(jù)進(jìn)行計算,將消耗巨量的計算資源,成本是無法接受的。
課題:探索一個技術(shù)方案,在可接受的成本基礎(chǔ)上,達(dá)成業(yè)務(wù)應(yīng)用場景目標(biāo)。
結(jié)合業(yè)務(wù)特點,基于StarRocks的物化視圖能力,對整個看板場景鏈路進(jìn)行加速優(yōu)化設(shè)計。最上游數(shù)據(jù)來自數(shù)倉,對線上日志、binlog清洗和Join處理后,加入消息隊列中,通過Flink同步到StarRocks;在StarRocks內(nèi)部先做一次全局字典轉(zhuǎn)換,將需要去重的指標(biāo)列,把String映射轉(zhuǎn)化為BIGINT,為后續(xù)使用BITMAP類型進(jìn)行上卷計算。繼而在StarRocks內(nèi)部進(jìn)行數(shù)據(jù)建模,落地原始明細(xì)表,生成ODS層-StarRocks明細(xì)模型層;再加工DWD層-StarRocks中的同步物化視圖,對不同的維度組合進(jìn)行上卷,支持增量計算,時效性較高,數(shù)據(jù)滿足強一致,存儲類型使用BITMAP的中間計算結(jié)果。對單次明細(xì)查詢具有明顯的提升,但是查詢并發(fā)還是無法滿足應(yīng)用要求;繼而加工ADS層-StarRocks中的異步物化視圖進(jìn)行加速,StarRocks的異步物化視圖使用定時刷新機(jī)制,時效性相對會差一些,數(shù)據(jù)相對底表有一定的更新延遲,查詢底表和異步物化視圖可能會存在一定的差異,但因為異步視圖存儲的是最終計算結(jié)果,查詢速度極快。可以理解為查詢緩存的持久化。
經(jīng)過分析業(yè)務(wù)的歷史查詢模式,可以將最高頻的查詢定義為異步視圖;同步視圖可以降低異步視圖在定時刷新計算時的資源開銷;部分無法命中異步視圖的查詢,也可以通過同步視圖進(jìn)行加速;對于剩余的小部分低頻查詢,會使用原始的明細(xì)數(shù)據(jù)表進(jìn)行計算。
針對第一步的寫入時全局字典功能,進(jìn)行詳細(xì)介紹:
通常在需要對count(distinct())指標(biāo)做上卷計算時,StarRocks支持Hyper-loglog和BITMAP兩種類型。Hyper-loglog類型是一種模糊去重的指標(biāo)計算模式,對于精確去重的指標(biāo)需要使用BITMAP類型。
StarRocks內(nèi)部使用的是Roaring BITMAP實現(xiàn),字段類型要求是在UINT64以內(nèi),而且在數(shù)據(jù)的連續(xù)性比較好的情況下,性能表現(xiàn)更優(yōu)。若數(shù)據(jù)是連續(xù)遞增的,相比完全隨機(jī)的ID,性能差異在百倍以上。所以,滴滴在StarRocks中實現(xiàn)了高基數(shù)全局字典的功能。
第一步:全局字典表的數(shù)據(jù)使用StarRocks內(nèi)部的帶自增ID列的主鍵表進(jìn)行存儲。表的主鍵使用的是需要去重的字段,ID列就是自增ID的列,數(shù)據(jù)在寫入時生成連續(xù)遞增的數(shù)字,寫入時使用了StarRocks的一個partial_update部分列更新的功能,保證了寫入冪等。只有在初次寫入時生成自增ID列,之后相同的批重新寫入,不會對ID的結(jié)果進(jìn)行更新。確保數(shù)據(jù)可以無限次的重復(fù)寫入。
第二步:實現(xiàn)了字典映射的函數(shù)dict_mapping,入?yún)樽值浔肀砻?、主鍵值,在計算時,實時查詢字典表,并返回生成的ID列的值。使用StarRocks的主鍵索引進(jìn)行加速,相比于基于SCAN進(jìn)行掃描,性能提升非常明顯。
第三步:改造了Flink的flink-starrocks-connector函數(shù),寫入時分兩次寫入:首先,寫入字典表,抽取需要寫入字典表的列,確保數(shù)據(jù)寫入落盤,事務(wù)提交可見。之后,再寫入實時數(shù)據(jù)表,StarRocks支持寫入時設(shè)置參數(shù)、使用函數(shù)進(jìn)行預(yù)處理,對數(shù)據(jù)進(jìn)行預(yù)加工。使用第二步的字典映射函數(shù)dict_mapping,通過映射對需要去重的字段進(jìn)行重新映射,將原有的string類型,映射為字典表中ID列的值。
在數(shù)據(jù)全部落盤之后,需要設(shè)計異步視圖如何創(chuàng)建?
以簡化后的訂單表為例進(jìn)行介紹:訂單表中包括分區(qū)日期、數(shù)據(jù)時間、呼叫城市、渠道、業(yè)務(wù)線等維度字段信息,以及需要去重的字段業(yè)務(wù)訂單ID。如左下圖示視圖,利用time_slice函數(shù)將時間取整為5分鐘,按5分鐘區(qū)間粒度進(jìn)行數(shù)據(jù)聚合,聚合維度包括呼叫城市、渠道等可累加維度。當(dāng)用戶查詢5分鐘粒度,且篩選條件和視圖中聚合維度完全相同時,可以使用這張視圖表進(jìn)行查詢加速,而不需要去查詢底表明細(xì)數(shù)據(jù)。
重復(fù)上述操作,可以設(shè)置1分鐘、10分鐘、30分鐘等不同的區(qū)間聚合粒度,按照不同的維度列組合,可以創(chuàng)建出多張異步視圖,來滿足不同用戶、不同維度的組合查詢條件,完成對應(yīng)實時看版的加速效果。
在上述過程中,到底需要創(chuàng)建多少張異步視圖,才能滿足所有查詢都可以命中?
以訂單表中包含N個維度列為例,因為count(distinct())結(jié)果是不支持累加的,需要完成所有維度字段的排列組合(既2的N次方個視圖),才能滿足所有查詢命中視圖加速。即,如果有10個維度列,就需要有超過1000張視圖,這個成本是不能接受的。
我們結(jié)合表數(shù)據(jù)特點,對異步視圖的表數(shù)量進(jìn)行優(yōu)化。前面提到了可累加維度和不可累加維度概念,如一個訂單只能有一個呼叫城市,呼叫城市維度就是可累加維度。如果要進(jìn)行全國累計呼叫次數(shù)計算,就可以通過所有城市的呼叫次數(shù)進(jìn)行累加實現(xiàn)。這樣就可以復(fù)用基于城市的物化視圖,避免冗余建設(shè)全國維度的物化視圖。反向的,訂單狀態(tài)是不可累加維度,每個訂單會在多個狀態(tài)之間流轉(zhuǎn),不支持累加計算。
如果數(shù)據(jù)表中可累加的維度列有M個,那么異步物化視圖需要2的(N-M)次方個。
如何使用異步視圖的透明加速能力來簡化使用成本?
StarRocks的整條數(shù)據(jù)加工鏈路上,除了底表明細(xì)表、還有多張異步視圖、同步視圖等,使用方需要確定本次查詢需要使用哪張表,對用戶而言操作比較復(fù)雜。StarRocks提供了視圖的透明加速功能。將查詢與這張表關(guān)聯(lián)的所有視圖進(jìn)行對比,將查詢自動改寫到符合條件的視圖上,保證改寫前后的語義查詢結(jié)果相同,查詢性能一致的。從而保障在不改變查詢SQL的情況下,使用視圖對查詢進(jìn)行加速。
示例如下:查詢Demo見左下方,在SQL中,內(nèi)層的子查詢使用了按5分鐘進(jìn)行聚合,聚合維度包括所有可累加維度——日期分區(qū)、數(shù)據(jù)日期、呼叫城市、渠道等4維度字段,在外層再多數(shù)據(jù)進(jìn)行求和。
基于StarRocks的底表上,建立了3張異步視圖,視圖1包括了1分鐘聚合粒度,分區(qū)、日期、呼叫城市、渠道等可累加維度;視圖2同視圖1,將聚合粒度調(diào)整為5分鐘;視圖3集成視圖2的基礎(chǔ)上,增加業(yè)務(wù)線可累加維度。
從而產(chǎn)生了如下四種查詢條件:
- Case 1: Where 為空,命中MV1
- Case 2: Where city IN(...)命中MV2
- Case 3:Where product_line=?,命中MV3
- Case 4:Where Product_line IN(),多業(yè)務(wù)線查詢,不支持累加,不能命中MV3,如果有創(chuàng)建同步視圖的話,可以進(jìn)行上卷加速。
三、總結(jié)與規(guī)劃:進(jìn)一步提升的空間和發(fā)展方向
設(shè)計方案的核心在于做取舍,方案的成果關(guān)鍵在于綜合性能的提升。
- 單次查詢耗時降低80%,資源消耗降低95%。
- 同規(guī)模集群支持QPS提升百倍。
缺點也很明顯,如下:
- 數(shù)據(jù)鏈路相對復(fù)雜,視圖由人工配置,維護(hù)復(fù)雜度高,成本較高。
- 異步視圖是定時刷新的,在沒有看板訪問時,也保持定時刷新,浪費計算資源。
- 異步視圖由于刷新間隔問題,無法保持同底表強一致。
對于看板類查詢,并發(fā)極高,但查詢模式比較固定。大部分的查詢是類似的,甚至重復(fù)的,整體方案的思路在于犧牲一定的靈活性,保障查詢性能達(dá)到極致提升。
后續(xù)規(guī)劃方向,在性能上進(jìn)一步優(yōu)化提升:
- 首先,BITMAP的計算性能提升。嘗試修改StarRocks的BITMAP分桶策略、BITMAP的Range進(jìn)行分桶,在不需要對BITMAP的中間結(jié)果進(jìn)行shuffle情況下,就可以獲取到最終結(jié)果。使用BITMAP的fastunion函數(shù)對大量BITMAP的合并速度進(jìn)行提升。
- 其次,異步視圖在改寫計算環(huán)節(jié)資源消耗還是比較大。同底表相關(guān)的所有視圖進(jìn)行對比,包括分區(qū)數(shù)據(jù)一致性、版本是否一致等等方面,還存在較大的提升空間。例如1s的查詢,有500ms都消耗在SQL優(yōu)化器上。
- 最后,在易用性上進(jìn)行提升。由于看板查詢都是基于平臺配置,自動生成的查詢SQL,因而通過分析歷史查詢記錄,提取高頻查詢,進(jìn)行物化視圖自動創(chuàng)建,降低人工參與,才能更有利于實現(xiàn)技術(shù)的更大規(guī)模應(yīng)用和推廣。