ByteHouse案例實(shí)踐:某銷(xiāo)售數(shù)據(jù)平臺(tái)如何基于OLAP大幅提升復(fù)雜查詢效率?
在現(xiàn)如今激烈的市場(chǎng)競(jìng)爭(zhēng)中,銷(xiāo)售數(shù)據(jù)是企業(yè)下一步市場(chǎng)決策的重要依據(jù)。銷(xiāo)售數(shù)據(jù)提供了關(guān)于市場(chǎng)需求、客戶行為、產(chǎn)品表現(xiàn)等方面的詳細(xì)信息。通過(guò)深入分析這些數(shù)據(jù),企業(yè)銷(xiāo)售人員、決策者等可以獲取有關(guān)市場(chǎng)趨勢(shì)和消費(fèi)者偏好的寶貴洞察,從而做出更加明智和精準(zhǔn)的決策。
某公司的市場(chǎng)份額一直處于快速增長(zhǎng)的態(tài)勢(shì),為了更好的統(tǒng)一數(shù)據(jù)口徑、保障數(shù)據(jù)質(zhì)量、控制數(shù)據(jù)權(quán)限,企業(yè)內(nèi)部已將分散的銷(xiāo)售數(shù)據(jù)統(tǒng)一到一套可視化分析平臺(tái)中。該平臺(tái)之前由開(kāi)源ClickHouse作為數(shù)據(jù)分析引擎,但在引入鑒權(quán)ACL用于管理數(shù)據(jù)權(quán)限、保障數(shù)據(jù)安全之后,該平臺(tái)出現(xiàn)性能不足、影響用戶體驗(yàn)的情況。
ByteHouse是火山引擎推出的一款定位為OLAP的分析型數(shù)據(jù)庫(kù),基于ClickHouse進(jìn)行架構(gòu)升級(jí)和優(yōu)化,在復(fù)雜查詢層面擁有顯著優(yōu)勢(shì)。該公司引入ByteHouse之后,結(jié)合相關(guān)銷(xiāo)售場(chǎng)景,對(duì)ByteHouse優(yōu)化器能力點(diǎn)對(duì)點(diǎn)優(yōu)化,實(shí)現(xiàn)查詢效率顯著提升,在某些場(chǎng)景下效率提升達(dá)到16倍。
本文將從業(yè)務(wù)痛點(diǎn)、解決方案、優(yōu)化結(jié)果三個(gè)方面,詳細(xì)拆解該公司銷(xiāo)售數(shù)據(jù)平臺(tái)如何基于ByteHouse復(fù)雜查詢能力實(shí)現(xiàn)效率提升。
業(yè)務(wù)背景:銷(xiāo)售數(shù)據(jù)平臺(tái)采用鑒權(quán)ACL模式管理數(shù)據(jù)權(quán)限
在該公司內(nèi)部,銷(xiāo)售人員(數(shù)據(jù)使用者)、數(shù)據(jù)分析師、數(shù)據(jù)工程師(數(shù)據(jù)維護(hù)和提供方)以及公司管理,一直以來(lái)都存在以下痛點(diǎn)問(wèn)題:
- 對(duì)于銷(xiāo)售來(lái)說(shuō),數(shù)據(jù)范圍難以全平臺(tái)對(duì)齊,即便是同一個(gè)數(shù)據(jù)集也會(huì)存在可見(jiàn)范圍不同的問(wèn)題;組織變動(dòng)、負(fù)責(zé)的客戶頻繁,調(diào)整過(guò)后則會(huì)存在看數(shù)問(wèn)題。
- 對(duì)于數(shù)據(jù)產(chǎn)品經(jīng)理、數(shù)據(jù)工程師、數(shù)據(jù)分析師等數(shù)據(jù)維護(hù)和提供方來(lái)說(shuō),數(shù)據(jù)集行權(quán)限維護(hù)成本高,了解銷(xiāo)售場(chǎng)景中復(fù)雜的鑒權(quán)邏輯,導(dǎo)致學(xué)習(xí)成本高。
- 對(duì)于公司合規(guī)管理來(lái)說(shuō),數(shù)據(jù)權(quán)限應(yīng)該得到合理控制,各個(gè)銷(xiāo)售能看到的客戶信息應(yīng)控制在最小范圍內(nèi)。
為了解決以上問(wèn)題,該公司的研發(fā)團(tuán)隊(duì)單獨(dú)把銷(xiāo)售數(shù)據(jù)的鑒權(quán)內(nèi)聚成新服務(wù),并且引入新的一種查詢鑒權(quán)模式 ACL來(lái)解決以上問(wèn)題。
“鑒權(quán) ACL(Access Control List)”通常指用于進(jìn)行身份鑒別和權(quán)限控制的訪問(wèn)控制列表。鑒權(quán)是指驗(yàn)證用戶或?qū)嶓w的身份和權(quán)限,以確定其是否有權(quán)訪問(wèn)特定的資源或執(zhí)行特定的操作。引入鑒權(quán) ACL之后,能?chē)?yán)格控制數(shù)據(jù)訪問(wèn)權(quán)限,確保只有授權(quán)人員可查看和操作敏感的銷(xiāo)售數(shù)據(jù),還可以根據(jù)員工職責(zé)精細(xì)劃分權(quán)限,比如銷(xiāo)售團(tuán)隊(duì)只能訪問(wèn)自身業(yè)務(wù)數(shù)據(jù),管理層能獲取更全面數(shù)據(jù),提升數(shù)據(jù)使用的合理性和安全性。
- 引入鑒權(quán)ACL之前的查詢情況:
- 引入鑒權(quán)ACL后:
綠色部分為SQL改動(dòng),通過(guò)引入子查詢的方式,使用戶無(wú)權(quán)限數(shù)據(jù)過(guò)濾,保證用戶鑒權(quán)最新?tīng)顟B(tài)。
業(yè)務(wù)痛點(diǎn):基于ClickHouse難以滿足鑒權(quán)ACL下的數(shù)據(jù)查詢需求
在引入ACL之前,日常銷(xiāo)售分析查詢就非常復(fù)雜、查詢量級(jí)大。而在SQL加入ACL控制后,采用的是分布式表JOIN,且ACL表子查詢返回結(jié)果大,進(jìn)一步導(dǎo)致集群負(fù)載惡化,ClickHouse集群CPU使用率長(zhǎng)期打滿,影響用戶體驗(yàn)。
性能惡化核心原因?yàn)镃lickHouse社區(qū)的Scatter/Gather執(zhí)行模型缺少shuffle的能力,對(duì)于多輪join難以很好支持。
下面用一個(gè)簡(jiǎn)單的例子說(shuō)明Scatter/Gather執(zhí)行模型下join的原理:
兩張分布式表source和to_join(對(duì)應(yīng)local表分別是source_local和to_join_local)數(shù)據(jù)分布在兩個(gè)分片上,如下圖:
- 先設(shè)置
distributed_product_mode = 'allow'
,執(zhí)行join查詢:
- 每個(gè)分片節(jié)點(diǎn)獨(dú)立執(zhí)行子查詢
SELECT *FROM to_join AS tj
,然后在本地做join,最后在接收查詢的節(jié)點(diǎn)(下文用host server指代)上匯總join結(jié)果,如下圖所示
- 最終結(jié)果如下:
如果分片數(shù)目為N,右表表達(dá)式的分布式表to_join
在一次join中就會(huì)被重復(fù)查詢N次,導(dǎo)致效率低下。為了解決該問(wèn)題,我們采用Global Join
,或者設(shè)置distributed_product_mode='global'
,引擎會(huì)自動(dòng)將分布式表的join改寫(xiě)成Global Join。
Global Join的原理是host server先執(zhí)行帶分布式表的子查詢,再類(lèi)似臨時(shí)表存在內(nèi)存中,發(fā)送到其他的節(jié)點(diǎn),讓其他節(jié)點(diǎn)join的時(shí)不用重復(fù)查詢?cè)摲植际奖怼_@樣的優(yōu)化方式讓Global Join效率基本可用了,但還存在如下局限性:
- 右表的大小影響join效率,如果右表比較大,join的時(shí)候cache missing會(huì)非常嚴(yán)重,性能很差;
- 不考慮SPILL的情況下(Graceful hash join可以部分緩解這個(gè)問(wèn)題),右表的必須全部在內(nèi)存中,容易OOM。
- Broadcast右表實(shí)現(xiàn)的效率上也有提升空間,比方說(shuō)右表數(shù)據(jù)先匯總到host server,再下發(fā)到各個(gè)節(jié)點(diǎn)多了一輪額外的傳輸和序列化反序列化開(kāi)銷(xiāo)。
- 多表JOIN,不同的join順序?qū)π阅苡绊懸埠艽螅珻lickHouse并沒(méi)有join reorder的能力,依賴用戶手動(dòng)調(diào)優(yōu)join的表的順序。
解決方案:遷移到ByteHouse提升銷(xiāo)售數(shù)據(jù)平臺(tái)復(fù)雜查詢效率
ByteHouse企業(yè)版支持優(yōu)化器和MPP執(zhí)行模型,可以較好的支持復(fù)雜join的場(chǎng)景,并且優(yōu)化器能力可以進(jìn)一步提升查詢效率,成為該公司銷(xiāo)售數(shù)據(jù)平臺(tái)從ClickHouse遷移的首選。
優(yōu)化器是DBMS中一個(gè)核心組件,它負(fù)責(zé)分析查詢語(yǔ)句,并根據(jù)表的結(jié)構(gòu)、索引等信息來(lái)生成最優(yōu)的執(zhí)行計(jì)劃。通過(guò)優(yōu)化查詢執(zhí)行計(jì)劃,可以提高查詢的執(zhí)行效率,減少資源消耗,提升系統(tǒng)性能。為了提升在復(fù)雜場(chǎng)景的查詢性能,ByteHouse 的自研優(yōu)化器進(jìn)行了大量的優(yōu)化,主要包括四個(gè)大的優(yōu)化方向:RBO(基于規(guī)則的優(yōu)化能力),CBO(基于代價(jià)的優(yōu)化能力),分布式計(jì)劃優(yōu)化以及一些高階優(yōu)化能力。
優(yōu)化器和MPP執(zhí)行模型原理
開(kāi)啟優(yōu)化器后,執(zhí)行模式由原來(lái)的Scatter/Gather模型切成了完全MPP模型。整個(gè)SQL的執(zhí)行流程如下圖所示(以3節(jié)點(diǎn)的集群為例)
- PlanSegment:分布式執(zhí)行計(jì)劃邏輯單元(QueryPlan+Exchange輸入輸出)
- Optimizer: 根據(jù)Rule(RBO)和統(tǒng)計(jì)信息(CBO)進(jìn)行查詢計(jì)劃的優(yōu)化,生成最終的查詢計(jì)劃PlanSegmentTree.
- Scheduler: 發(fā)送PlanSegment到各個(gè)Worker
- Exchange:在Pipeline之間傳輸數(shù)據(jù)
- PipelineExecutor: 驅(qū)動(dòng)執(zhí)行PlanSegment
ByteHouse優(yōu)化器四大優(yōu)化方向
下面用上一節(jié)的例子簡(jiǎn)單說(shuō)明:采用之前的SQL
可以看到右表讀取完之后通過(guò)exchange進(jìn)行了廣播到左表再join(不同于原來(lái)模式需要先在host server匯總右表再下發(fā)到各個(gè)節(jié)點(diǎn))。
如果兩個(gè)表很大,開(kāi)啟統(tǒng)計(jì)信息的情況下,計(jì)劃如下:
左右表會(huì)先shuffle N份(N默認(rèn)為分片總數(shù)/10,可以通過(guò)distributed_max_parallel_size參數(shù)控制)再進(jìn)行join,這樣單個(gè)節(jié)點(diǎn)join的時(shí)候右表的大小平均是總右表的1/N,內(nèi)存占用和性能都有很大提升。
開(kāi)啟ByteHouse優(yōu)化器后,查詢計(jì)劃會(huì)有這四類(lèi)優(yōu)化:
優(yōu)化一:RBO:
基于規(guī)則的優(yōu)化能力。支持列裁剪,分區(qū)裁剪,表達(dá)式簡(jiǎn)化,子查詢解關(guān)聯(lián),謂詞下推,冗余算子消除,外部連接轉(zhuǎn)內(nèi)部連接,算子下推存儲(chǔ),分布式算子拆分等常見(jiàn)的啟發(fā)式優(yōu)化能力。
- 解關(guān)聯(lián)
很多OLAP引擎不支持相關(guān)子查詢,在語(yǔ)法分析階段就會(huì)報(bào)錯(cuò)。優(yōu)化器實(shí)現(xiàn)了完整的解關(guān)聯(lián)能力,對(duì)于關(guān)聯(lián)查詢可以轉(zhuǎn)換為常見(jiàn)的 join agg filter 等算子執(zhí)行,下圖就是一個(gè)簡(jiǎn)單的解關(guān)聯(lián)例子。對(duì)于一些特殊類(lèi)型的關(guān)聯(lián)查詢也可以利用 window 算子執(zhí)行,更加快速簡(jiǎn)潔。
- 非等值Join優(yōu)化
在很多引擎中,帶有非等值條件的 join 需要通過(guò)多個(gè)算子來(lái)組合執(zhí)行(inner join + filter + group-by
),而在 ByteHouse 中,支持非等值 join 之后可以直接在 join 算子中完成非等值條件的執(zhí)行。
優(yōu)化器會(huì)對(duì)一些關(guān)聯(lián)子查詢轉(zhuǎn)成非等值 join 來(lái)執(zhí)行,相較于轉(zhuǎn)成其他常見(jiàn)的算子(inner join, filter, agg)性能有一倍以上的提升。
優(yōu)化二:CBO
基于代價(jià)的優(yōu)化能力。基于級(jí)聯(lián)搜索框架,利用Graph分區(qū)技術(shù)實(shí)現(xiàn)了高效的Join枚舉算法,以及基于直方圖的代價(jià)估算,對(duì)10表級(jí)別規(guī)模的Join Reorder問(wèn)題,能夠全量枚舉并尋求最優(yōu)解,同時(shí)針對(duì)于10表規(guī)模的Join Reorder支持啟發(fā)式枚舉并尋求最優(yōu)解。CBO支持基于規(guī)程擴(kuò)展搜索空間,除了常見(jiàn)的Join Reorder問(wèn)題以外,還支持外部Join/Join Reorder、Aggregate/Join Reorder、Magic Set Placement等相關(guān)優(yōu)化能力。
優(yōu)化三:分布式計(jì)劃優(yōu)化
業(yè)界主流實(shí)現(xiàn)分為兩個(gè)階段,首先尋求最優(yōu)的單機(jī)版計(jì)劃,然后將其分布式化。但是這樣的設(shè)計(jì)流程,不能提前考慮分布式系統(tǒng)的特點(diǎn),可能會(huì)導(dǎo)致網(wǎng)絡(luò)延遲、數(shù)據(jù)分布不均衡,并導(dǎo)致可擴(kuò)展性限制等問(wèn)題。我們的方案則是將這兩個(gè)階段融合在一起,在整個(gè) CBO 尋求最優(yōu)解的過(guò)程中,會(huì)結(jié)合分布式計(jì)劃的訴求,從代價(jià)的角度選擇最優(yōu)的分布式計(jì)劃,同時(shí)在 Join/Aggregate 過(guò)程中,也支持 Partition 屬性展開(kāi)。
另外,我們也在 CBO 中實(shí)現(xiàn)了對(duì)于 Aggregate/Join Reorder,Magic Set Placement 等相關(guān)能力。對(duì)于 CTE 的實(shí)現(xiàn)方式也基于 Cost 進(jìn)行選擇,在 inline,shared 和 partial inline 之間做權(quán)衡,選出最優(yōu)的計(jì)劃。在 tpcds 等 benchmark 中都有一定的應(yīng)用。
優(yōu)化四:高階優(yōu)化能力
ByteHouse實(shí)現(xiàn)了動(dòng)態(tài)Filter下推、物化視圖改寫(xiě)、基于代價(jià)的CTE(公共表達(dá)式共享)、計(jì)劃復(fù)用、結(jié)果復(fù)用等高階優(yōu)化能力。
最佳實(shí)踐之“聚合計(jì)算加速”
在數(shù)據(jù)庫(kù)中,優(yōu)化器對(duì)于聚合計(jì)算加速起著關(guān)鍵作用。優(yōu)化器能夠分析查詢語(yǔ)句的結(jié)構(gòu)和涉及的數(shù)據(jù),評(píng)估不同的執(zhí)行計(jì)劃。對(duì)于聚合計(jì)算,它會(huì)考慮數(shù)據(jù)的分布、索引的可用性以及表之間的關(guān)系等因素。除了JOIN場(chǎng)景,ByteHouse在聚合計(jì)算場(chǎng)景也產(chǎn)生了積極的影響。
- 多節(jié)點(diǎn)并行merge聚合結(jié)果
分散/聚集模式在聚集階段會(huì)聚合各個(gè)節(jié)點(diǎn)局部聚合的中間結(jié)果,這時(shí)容易遇到單節(jié)點(diǎn)的性能和內(nèi)存瓶頸,其典型的場(chǎng)景是大數(shù)據(jù)的count distinct
。開(kāi)啟ByteHouse優(yōu)化器后,我們可以使用10%的分片(通過(guò)distributed_max_parallel_size參數(shù)調(diào)整,最大值為集群分片數(shù)目)來(lái)做最終的聚合操作,實(shí)現(xiàn)較好的并行聚合。
- 優(yōu)化器會(huì)對(duì)聚合進(jìn)行改寫(xiě)優(yōu)化,提升聚合性能
如果缺少group by key的聚合操作,在沒(méi)開(kāi)優(yōu)化器的情況下,Gather階段在單機(jī)內(nèi)為單線程聚合(由于缺少group by key無(wú)法并行)。ByteHouse優(yōu)化器能實(shí)現(xiàn)進(jìn)行自動(dòng)改寫(xiě),除了多節(jié)點(diǎn)并行合并聚合結(jié)果,單節(jié)點(diǎn)內(nèi)部也能并行。
下面為tpch
的數(shù)據(jù)(6億數(shù)據(jù)的lineitem表)在一個(gè)兩節(jié)點(diǎn)集群測(cè)試(最后merge的節(jié)點(diǎn)為同一個(gè)),SQL如下:
開(kāi)啟優(yōu)化器耗時(shí)從5.913秒下降到了2.263秒。
優(yōu)化結(jié)果:最高16倍,相關(guān)場(chǎng)景查詢效率提升
通過(guò)非ACL查詢和ACL查詢兩個(gè)方向,我們可以看到查詢時(shí)間在優(yōu)化前后有顯著提升。其中,在ACL查詢中的60M廣告客戶DI場(chǎng)景中,引入ByteHouse之后將查詢效率從16s縮短為秒級(jí),提升了16倍。
- 非ACL查詢
?
抽取該公司銷(xiāo)售平臺(tái)某數(shù)據(jù)集測(cè)試
?
- ACL查詢
?
抽取該公司銷(xiāo)售平臺(tái)某數(shù)據(jù)集測(cè)試
?
總結(jié)來(lái)看,但隨著用戶使用場(chǎng)景愈加復(fù)雜,ByteHouse針對(duì)復(fù)雜的查詢場(chǎng)景,在RBO、CBO、分布式計(jì)劃等層面進(jìn)行大量?jī)?yōu)化,進(jìn)一步提升了OLAP在各個(gè)場(chǎng)景下的查詢性能。未來(lái),ByteHouse也將持續(xù)為更多企業(yè)的數(shù)據(jù)分析能力提供支持,助推數(shù)智化轉(zhuǎn)型升級(jí)。