本文導(dǎo)讀:
當(dāng)前,電商運(yùn)營(yíng)的主要痛點(diǎn)不僅來(lái)自多變的市場(chǎng)和客戶需求,也受困于碎片化用戶觸達(dá)等帶來(lái)的競(jìng)爭(zhēng)與挑戰(zhàn)。為了深度挖掘用戶價(jià)值、培養(yǎng)用戶忠誠(chéng)度、實(shí)現(xiàn)業(yè)績(jī)?cè)鲩L(zhǎng),有贊為商家搭建了全方位 OLAP 分析系統(tǒng),提供實(shí)時(shí)與離線分析報(bào)表、智能營(yíng)銷與人群圈選等 SaaS 服務(wù)。本文將詳細(xì)介紹有贊從 Clickhouse 至 Apache Doris 的遷移規(guī)劃和性能對(duì)比測(cè)試實(shí)踐,分享如何基于 Apache Doris 統(tǒng)一 OLAP 技術(shù)棧,并滿足龐大數(shù)據(jù)體量下的實(shí)時(shí)分析與極速查詢,最終有贊在多個(gè)場(chǎng)景下實(shí)現(xiàn)查詢平均提速 200% 。
作者:李闖 有贊 基礎(chǔ)平臺(tái)數(shù)據(jù)研發(fā)工程師
有贊是國(guó)內(nèi)領(lǐng)先的電商 SaaS 服務(wù)商,目前擁有社交電商、新零售、美業(yè)、教育及有贊國(guó)際化五大業(yè)務(wù)體系,通過(guò)旗下的社交電商、門店管理、解決方案以及其他新零售 SaaS 軟件產(chǎn)品,全面幫助商家解決在移動(dòng)互聯(lián)網(wǎng)時(shí)代遇到的推廣獲客、成交轉(zhuǎn)化、客戶留存、復(fù)購(gòu)增長(zhǎng)、分享裂變等問(wèn)題,幫助每一位重視產(chǎn)品和服務(wù)的商家實(shí)現(xiàn)顧客資產(chǎn)私有化、互聯(lián)網(wǎng)客群拓展、經(jīng)營(yíng)效率提升,最終助力商家成功。
在面對(duì)商家與開發(fā)者的定制化服務(wù)需求的同時(shí),為了能夠更好地支持商家有效解決引流獲客、分銷體系等難題,有贊為商家搭建了 OLAP 分析系統(tǒng),提供以下 SaaS 服務(wù)場(chǎng)景:
- 商家離線后臺(tái)報(bào)表: 面向 B 端為商家提供 T+1 報(bào)表查詢,對(duì)計(jì)算精度、查詢性能及穩(wěn)定性要求較高,同時(shí)會(huì)面臨復(fù)雜查詢場(chǎng)景。
- 人群圈選與智能營(yíng)銷: 從私域觸點(diǎn)、線下觸點(diǎn)獲取用戶數(shù)據(jù),結(jié)合常用社交平臺(tái)中接入的用戶數(shù)據(jù),根據(jù)業(yè)務(wù)需求在客戶數(shù)據(jù)平臺(tái)(Customer Data Platform - 以下簡(jiǎn)稱 CDP)、數(shù)據(jù)管理平臺(tái)( Data Management Platform -以下簡(jiǎn)稱 DMP)、客戶關(guān)系管理系統(tǒng)(Customer Relationship Management- 以下簡(jiǎn)稱 CRM) 進(jìn)行不同消費(fèi)者的全方位畫像分析。該場(chǎng)景會(huì)面臨大量高頻的數(shù)據(jù)實(shí)時(shí)更新,同時(shí)查詢體量較大、QPS 較高,時(shí)常出現(xiàn)復(fù)雜 SQL 查詢場(chǎng)景。
- 商家實(shí)時(shí)分析報(bào)表: 面向 B 端為商家提供相關(guān)實(shí)時(shí)報(bào)表分析查詢,該場(chǎng)景特點(diǎn)是 QPS 比較高,商家可以選擇不同的維度組合進(jìn)行查詢,對(duì)實(shí)時(shí)性和穩(wěn)定性要求高。
- 天網(wǎng)日志分析系統(tǒng): 為所有業(yè)務(wù)系統(tǒng)提供日志采集、消費(fèi)、分析、存儲(chǔ)、索引和查詢的一站式日志服務(wù)。該場(chǎng)景寫入吞吐高,需要達(dá)到每秒百萬(wàn)級(jí)別的數(shù)據(jù)寫入;且查詢頻率低,涉及天網(wǎng) TopN 日志查詢,因此系統(tǒng)要求具備實(shí)時(shí)聚合以及模糊搜索能力。
隨著業(yè)務(wù)數(shù)據(jù)體量逐漸龐大,業(yè)務(wù)對(duì)于時(shí)效性、聯(lián)邦查詢分析的需求也愈加迫切,現(xiàn)有組件在使用過(guò)程中對(duì)業(yè)務(wù)人員開發(fā)、運(yùn)維人員維護(hù)都存在一定痛點(diǎn),因此決定升級(jí)數(shù)據(jù)架構(gòu)并基于 Apache Doris 來(lái)統(tǒng)一 OLAP 技術(shù)棧。本文將詳細(xì)介紹早期架構(gòu)的組成、 OLAP 系統(tǒng)運(yùn)轉(zhuǎn)流程、以及實(shí)際應(yīng)用痛點(diǎn),分享系統(tǒng)架構(gòu)在遷移過(guò)程中的技術(shù)與調(diào)優(yōu)經(jīng)驗(yàn)。
早期架構(gòu)痛點(diǎn)
早期架構(gòu)如圖所示,數(shù)據(jù)主要來(lái)源于業(yè)務(wù)數(shù)據(jù)庫(kù) Binlog 與用戶日志等原始數(shù)據(jù),通過(guò)實(shí)時(shí)與離線兩條鏈路分別對(duì)數(shù)據(jù)進(jìn)行處理。其中原始數(shù)據(jù)首先導(dǎo)入至 Apache Kafka 與 NSQ 消息中間件,一部分會(huì)通過(guò) Apache Flink 進(jìn)行流處理計(jì)算并與存儲(chǔ)在 HBase 中的維度明細(xì)表進(jìn)行關(guān)聯(lián),另一部分?jǐn)?shù)據(jù)會(huì)存儲(chǔ)于 Apache Hive 與 HDFS 中作為離線數(shù)據(jù),通過(guò) Apache Spark 計(jì)算寫入至 OLAP 引擎中。
有贊數(shù)據(jù)架構(gòu)主要使用了以下三種 OLAP 引擎,各個(gè)組件根據(jù)業(yè)務(wù)場(chǎng)景的特點(diǎn)與需求為上游應(yīng)用提供不同場(chǎng)景的查詢與分析:
- Apache Kylin: 基于 Apache Kylin 搭建商家離線報(bào)表后臺(tái),為商家提供 T+1 報(bào)表查詢。目前后臺(tái)已經(jīng)具有超 500 萬(wàn)家的商家數(shù)量,對(duì)于部分體量較大的商家,其單點(diǎn)會(huì)員數(shù)能夠達(dá)到千萬(wàn)級(jí)別、商品 SKU 達(dá)到數(shù)十萬(wàn)、平臺(tái)構(gòu)建 Cube 數(shù)量達(dá) 400+。
- Clickhouse: 基于 Clickhouse 進(jìn)行人群圈選與 TopN 日志查詢業(yè)務(wù),其中人群圈選主要通過(guò)實(shí)時(shí)的明細(xì)查詢來(lái)輔助用戶行為數(shù)據(jù)分析。
- Apache Druid: 針對(duì) B 端商家實(shí)時(shí)分析報(bào)表場(chǎng)景,基于 Druid 構(gòu)建維度查詢系統(tǒng),為商家提供實(shí)時(shí)指標(biāo)查詢服務(wù)。
然而由于該架構(gòu)組件過(guò)多、架構(gòu)冗余等問(wèn)題導(dǎo)致維養(yǎng)、開發(fā)、業(yè)務(wù)應(yīng)用等方面帶來(lái)了一系列的挑戰(zhàn),具體如下:
01 Clickhouse :查詢性能不足
針對(duì)部份 SaaS 場(chǎng)景的高并發(fā)高 QPS 查詢場(chǎng)景,Clickhouse 的查詢能力表現(xiàn)不夠理想。由于 Clickhouse 組件本身設(shè)計(jì)的問(wèn)題,無(wú)法支持多表或大表 Join 的查詢場(chǎng)景,這就導(dǎo)致一旦出現(xiàn)關(guān)聯(lián)查詢場(chǎng)景,業(yè)務(wù)方需要重新尋找解決方案,使整體查詢效率低下。
02 Apache Druid :數(shù)據(jù)修復(fù)處理難度大
- 數(shù)據(jù)修復(fù)難度大: 當(dāng)出現(xiàn) Apache Flink 自身容錯(cuò)導(dǎo)致數(shù)據(jù)重復(fù)的情況,Druid 完全依賴寫入側(cè)進(jìn)行冪等操作,由于自身不支持?jǐn)?shù)據(jù)更新或刪除,只能對(duì)數(shù)據(jù)進(jìn)行全量替換,導(dǎo)致數(shù)據(jù)準(zhǔn)確性低、修復(fù)難度大。
- 數(shù)據(jù)一致性問(wèn)題: 對(duì)于 Druid 而言,導(dǎo)入數(shù)據(jù)后需要構(gòu)建完 Segment 才能響應(yīng)查詢結(jié)果。一旦上游 Flink 寫入 Kafka 的過(guò)程中出現(xiàn)數(shù)據(jù)延遲,則無(wú)法按照預(yù)期時(shí)間寫入 Druid 中,指標(biāo)數(shù)據(jù)就會(huì)出現(xiàn)較大波動(dòng),數(shù)據(jù)一致性無(wú)法得到保障。
- 數(shù)據(jù)修復(fù)鏈路過(guò)長(zhǎng)、成本過(guò)高:為了解決部份臨時(shí)數(shù)據(jù)修復(fù)問(wèn)題,我們首先需要花費(fèi)小時(shí)級(jí)時(shí)間將 Apache Kafka 數(shù)據(jù)備份至 HDFS上,在備份完成后還需要將數(shù)據(jù)重新導(dǎo)入 Druid 之后進(jìn)行修復(fù),整體修復(fù)的鏈路過(guò)長(zhǎng),投入的時(shí)間與研發(fā)成本會(huì)隨之升高。
03 Apache Kylin : T+1 時(shí)效性低
Apache Kylin 在數(shù)據(jù)處理過(guò)程中采用了預(yù)計(jì)算的方式,通過(guò)在多維 Cube 構(gòu)建過(guò)程中完成聚合計(jì)算,并生成 T+1 數(shù)據(jù)報(bào)表。對(duì)部分在夜間經(jīng)營(yíng)的商家而言,他們需要等待一天時(shí)間才能查看前一天的報(bào)表數(shù)據(jù),這無(wú)法滿足用戶對(duì)于時(shí)效性的需求。
04 整體架構(gòu):運(yùn)維成本高、研發(fā)效能低、架構(gòu)靈活度差
- 研發(fā)成本高: 業(yè)務(wù)方需要學(xué)習(xí)每種組件(Clickhouse、Druid、Apache Kylin)的使用方式、并且查詢 SQL 標(biāo)準(zhǔn)各異,這會(huì)使學(xué)習(xí)成本加大,并且在后期進(jìn)行研發(fā)、監(jiān)控、運(yùn)維、周邊生態(tài)工具等開發(fā)工作過(guò)程中,需要投入大量的人力與開發(fā)接入成本,降低開發(fā)效率。
- 運(yùn)維瓶頸: 在擴(kuò)縮容期間業(yè)務(wù)方需要停寫進(jìn)行集群調(diào)整,且單次擴(kuò)容需要將所有的庫(kù)表都進(jìn)行遷移,不僅無(wú)法保證運(yùn)維時(shí)間成本,還會(huì)增加過(guò)高的人力成本。而目前有贊存在大量的擴(kuò)容需求,現(xiàn)有架構(gòu)的運(yùn)維成本則成為系統(tǒng)的一大痛點(diǎn)。
- 架構(gòu)靈活度差: Apache Kylin 僅在維度和指標(biāo)提前設(shè)定、表結(jié)構(gòu)固定的場(chǎng)景下能夠正常運(yùn)行,一旦增加維度和指標(biāo)則需要新建 Cube 并重刷歷史數(shù)據(jù);Clickhouse 在寬表補(bǔ)數(shù)時(shí)會(huì)出現(xiàn)需要重新全量導(dǎo)入數(shù)據(jù),這些架構(gòu)缺陷在業(yè)務(wù)運(yùn)行過(guò)程中都會(huì)引發(fā)資源使用增加、運(yùn)維成本增加、研發(fā)效能較低的問(wèn)題。
技術(shù)調(diào)研與收益成本評(píng)估
基于上述架構(gòu)痛點(diǎn),我們對(duì)市面上的架構(gòu)進(jìn)行了調(diào)研與選型,希望選擇一款能夠簡(jiǎn)化當(dāng)前復(fù)雜架構(gòu)、統(tǒng)一 OLAP 技術(shù)棧的引擎。我們除了分析 OLAP 性能本身對(duì)于業(yè)務(wù)的幫助,還需要評(píng)估架構(gòu)改造所帶來(lái)的收益成本比,思考架構(gòu)進(jìn)行遷移和重構(gòu)之后所帶來(lái)的 ROI 是否符合預(yù)期。
對(duì)于收益而言,我們需要評(píng)估新架構(gòu)引入后的性能是否如預(yù)期提升,將 Apache Doris 分別與 Clickhouse、Druid、Kylin 進(jìn)行對(duì)比評(píng)估。
對(duì)于成本而言,我們首先會(huì)考慮在替換過(guò)程中,周邊工具開發(fā)的成本,其中涉及監(jiān)控、告警、上下游依賴平臺(tái)等一系列工具的構(gòu)建與研發(fā);其次業(yè)務(wù)的遷移會(huì)涉及大量業(yè)務(wù)改造與協(xié)調(diào),如何催動(dòng)業(yè)務(wù)方進(jìn)行改造、提供更豐富的改造工具、盡可能降低投入成本也是我們主要考慮的問(wèn)題。
經(jīng)過(guò)一系列評(píng)估后,我們發(fā)現(xiàn)基于 Apache Doris 進(jìn)行架構(gòu)迭代,其不論是在業(yè)務(wù)賦能還是成本方面,都能夠有效解決當(dāng)前架構(gòu)的痛點(diǎn),極大程度地實(shí)現(xiàn)降本增效的目標(biāo),整體迭代的預(yù)期收益明顯高于改造代價(jià),因此我們決定基于 Apache Doris 構(gòu)建統(tǒng)一實(shí)時(shí)數(shù)倉(cāng),具體評(píng)估分析如下:
- 查詢性能優(yōu)異: 解決了 Clickhouse 在高 QPS 查詢與大表關(guān)聯(lián)查詢場(chǎng)景下的弊端,提供了優(yōu)秀的并發(fā)查詢能力。此外,在 Apache Doris 2.0 發(fā)布后,倒排索引功能支持任意維度快速檢索、文本分詞全文檢索,在日志場(chǎng)景下的查詢性能提升尤為明顯。
- 高效的數(shù)據(jù)更新: Apache Doris 的 Unique Key 支持大批量數(shù)據(jù)更新、小批量數(shù)據(jù)實(shí)時(shí)寫入,覆蓋我們 90 % 業(yè)務(wù)場(chǎng)景,其 Duplicate Key 與 Aggregate Key 模型還能夠支持部分列更新,整體數(shù)據(jù)模型豐富,幫助提升寫入與查詢效率。
- 保證數(shù)據(jù)正確性: Apache Doris 支持事務(wù)導(dǎo)入,Bitmap 功能支持精準(zhǔn)去重,保證數(shù)據(jù)不丟不重;同時(shí)支持精準(zhǔn)寫入,保證數(shù)據(jù)基表與物化視圖強(qiáng)一致性、副本數(shù)據(jù)強(qiáng)一致性。
- 簡(jiǎn)單易用、開發(fā)成本低: Apache Doris 高度兼容 MySQL,使開發(fā)簡(jiǎn)單使用門檻降低,且 Doris 的遷移與擴(kuò)縮容成本較低,在橫向擴(kuò)容等運(yùn)維操作方面特別簡(jiǎn)單。其周邊組件的接入與監(jiān)控的接入皆相對(duì)簡(jiǎn)單,Doris 社區(qū)提供 Flink & Doris Connector、Spark & Doris Connector 等接入工具,并且監(jiān)控模版能夠直接取用,無(wú)需再開發(fā)。
- 社區(qū)活躍度高: 在過(guò)往加入的開源社區(qū)中,Apache Doris 社區(qū)活躍度非常高,社區(qū)開發(fā)者多、迭代更新快,對(duì)于社區(qū)內(nèi)的問(wèn)題解答也十分積極,在開發(fā)過(guò)程給予了非常多的幫助。
基于 Apache Doris 構(gòu)建統(tǒng)一實(shí)時(shí)數(shù)倉(cāng)
如上圖所示,新架構(gòu)將基于 Apache Doris 搭建統(tǒng)一實(shí)時(shí)數(shù)倉(cāng),替換原架構(gòu)中的三個(gè) OLAP 組件,解決由組件過(guò)多引起的接入成本高、資源使用增加、數(shù)據(jù)鏈路過(guò)長(zhǎng)等問(wèn)題,最終能夠減輕業(yè)務(wù)方的負(fù)擔(dān)、減少整體框架的硬件成本、實(shí)現(xiàn)引擎與技術(shù)棧統(tǒng)一等目標(biāo)。
在有贊絕大多數(shù)應(yīng)用場(chǎng)景中,原架構(gòu)都存在數(shù)據(jù)重復(fù)、數(shù)據(jù)延遲需要修復(fù)的情況,引入 Apache Doris 之后,我們將利用其 Unique Key、Duplicate Key、Aggregate Key 模型功能實(shí)現(xiàn)高效的數(shù)據(jù)更新,保證寫入效率,并且 Doris 架構(gòu)具備彈性伸縮的能力,引入后能夠極大程度地降低故障發(fā)生的概率以及出現(xiàn)故障時(shí)數(shù)據(jù)恢復(fù)的效率。
此外我們還將引入 Apache Doris 以下功能:
- 倒排索引: Apache Doris 2.0 版本的倒排索引功能優(yōu)化天網(wǎng)日志分析系統(tǒng),實(shí)現(xiàn)多維度快速檢索,加速日志場(chǎng)景的查詢分析性能。
- 主鍵模型寫時(shí)合并(Merge-on-Write): Apache Doris 提供豐富的導(dǎo)入方式,可以將小批量數(shù)據(jù)實(shí)時(shí)導(dǎo)入 Doris 中,為后續(xù)上架門店業(yè)務(wù)提供實(shí)時(shí)報(bào)表查詢,與原價(jià)構(gòu)使用對(duì)比,Doris 能夠極大程度提升導(dǎo)入時(shí)效性。
從 Clickhouse 到 Apache Doris 的遷移經(jīng)驗(yàn)
在確定架構(gòu)遷移之后,我們首先選擇用 Apache Doris 來(lái)替換 Clickhouse 組件,主要由于在業(yè)務(wù)增長(zhǎng)時(shí) Clickhouse 查詢性能瓶頸較大、集群擴(kuò)縮容操作過(guò)于復(fù)雜等痛點(diǎn)使運(yùn)維團(tuán)隊(duì)的工作量大幅增加,加之大表 Join 能力差、高 QPS 查詢性能差等一系列問(wèn)題無(wú)法滿足業(yè)務(wù)方訴求,且 Clickhouse 功能與 Apache Doris 相似,業(yè)務(wù)方更便于遷移, 因此我們優(yōu)先替換 Clickhouse 組件。
接下來(lái),我們將分享 Doris 替換 Clickhouse 的遷移方案,架構(gòu)迭代的整體節(jié)奏分為 SQL 語(yǔ)句改寫實(shí)現(xiàn)自動(dòng)導(dǎo)入(包含建表語(yǔ)句與查詢語(yǔ)句的改寫)、查詢性能測(cè)試、穩(wěn)定性測(cè)試、導(dǎo)入性能測(cè)試與優(yōu)化,在結(jié)束一系列測(cè)試后最終進(jìn)行整體業(yè)務(wù)數(shù)據(jù)的遷移。
01 SQL 建表語(yǔ)句與查詢語(yǔ)句改寫
目前,我們針對(duì) Unique Key 模型與 Duplicate Key 模型制作了 SQL 建表語(yǔ)句改寫工具,如上圖所示,支持通過(guò)配置參數(shù)自動(dòng)將 Clickhouse 建表語(yǔ)句轉(zhuǎn)為 Doris 建表語(yǔ)句,該工具的主要功能具體如下:
- 字段類型映射: 由于 Doris 與 Clickhouse 字段不一致,存在一些特殊要求的轉(zhuǎn)換,例如 Key 值類型 String 需要轉(zhuǎn)為 Varchar 以及設(shè)置對(duì)應(yīng)長(zhǎng)度、分區(qū)字段 String 需要轉(zhuǎn)為 Date V2 等;
- 動(dòng)態(tài)分區(qū)表的歷史分區(qū)數(shù)確定: 因?yàn)椴糠荼泶嬖跉v史分區(qū),需要在建表時(shí)指定分區(qū)數(shù)量,否則插入數(shù)據(jù)會(huì)出現(xiàn) No Partition 異常;
- Buckets 數(shù)量確定: 雖然歷史分區(qū)表可以進(jìn)行統(tǒng)一配置,但是往往歷史分區(qū)數(shù)據(jù)量不完全一致,因此我們根據(jù)歷史分區(qū)的實(shí)際數(shù)據(jù)量推算出歷史分區(qū)的分桶數(shù),同時(shí)對(duì)于非分區(qū)表可以根據(jù)歷史數(shù)據(jù)量設(shè)置 Properties 進(jìn)行自動(dòng)分桶配置;
- TTL 周期確定: 可以設(shè)定動(dòng)態(tài)分區(qū)表的轉(zhuǎn)換周期,設(shè)定保留時(shí)間后再轉(zhuǎn)換;
- Unique 模型的 Sequence 設(shè)置: 在導(dǎo)入時(shí)可以指定 Sequence 列導(dǎo)入順序,解決了導(dǎo)入順序無(wú)法確定的問(wèn)題,有效保證數(shù)據(jù)導(dǎo)入過(guò)程中的有序性。
與建表語(yǔ)句改寫工具類似,SQL 查詢語(yǔ)句改寫能夠自動(dòng)將 Clickhouse 查詢語(yǔ)句轉(zhuǎn)成 Doris 查詢語(yǔ)句,主要為了雙跑進(jìn)行數(shù)據(jù)準(zhǔn)確性和穩(wěn)定性驗(yàn)證。在改寫過(guò)程中,我們梳理了以下注意事項(xiàng):
- 查詢表名轉(zhuǎn)換: 在 Clickhouse 與 Doris 建表過(guò)程中存在一定的映射規(guī)則,在進(jìn)行雙跑測(cè)試的過(guò)程中,我們可以直接根據(jù)映射規(guī)則直接進(jìn)行轉(zhuǎn)換。
-
函數(shù)轉(zhuǎn)換: 由于 Clickhouse 與 Doris 使用函數(shù)差異較大,需要根據(jù) Doris 和 Clickhouse 的函數(shù)映射關(guān)系進(jìn)行函數(shù)映射轉(zhuǎn)換。其中我們遇到一些比較特殊的函數(shù)轉(zhuǎn)換需要進(jìn)行特別處理,例如 Clickhouse 中的
COUNTIF()
需要轉(zhuǎn)換為SUM(CASE WHEN _ THEN 1 ELSE 0)
以達(dá)到相同的效果,ORDER BY
與GROUP BY
需要利用 Doris 開窗函數(shù)進(jìn)行轉(zhuǎn)化,此外 Clickhouse 利用Array Join
進(jìn)行列傳行,對(duì)應(yīng) Doris 則需要利用Explode
、Lateral View
來(lái)展開; -
語(yǔ)法層面的不兼容: 由于 Clickhouse 不兼容 MySQL 協(xié)議而 Doris 高度兼容,因此在子查詢中需要進(jìn)行別名設(shè)置。特別是在人群圈選的業(yè)務(wù)場(chǎng)景中存在多個(gè)子查詢,因此在售后轉(zhuǎn)換的時(shí)候需要把對(duì)應(yīng)子查詢利用
sqlparse
進(jìn)行遞歸,檢查出所有的子查詢進(jìn)行設(shè)置。
02 Apache Doris 與 Clickhouse 性能壓測(cè)
查詢性能測(cè)試主要通過(guò) Apache Doris 與原架構(gòu) Clickhouse 組件在三個(gè)核心業(yè)務(wù)場(chǎng)景(CDP、DMP、CRM)下的對(duì)比表現(xiàn)。我們選用了線上等比的集群規(guī)模,通過(guò)查詢 SQL 性能對(duì)比、大表 Join 性能兩方面進(jìn)行對(duì)比壓測(cè),同時(shí)檢測(cè) Doris 在查詢期間的 CPU 以及 內(nèi)存損耗。接下來(lái)我們將詳細(xì)介紹壓測(cè)過(guò)程與具體性能數(shù)據(jù)對(duì)比。測(cè)試集群規(guī)模3 FE + 16 BE,BE單節(jié)點(diǎn)配置為( 32C 128 G 7T SSD)。
核心場(chǎng)景下查詢 SQL 性能對(duì)比
在進(jìn)行查詢 SQL 性能測(cè)試中,我們主要基于當(dāng)前實(shí)際應(yīng)用場(chǎng)景最多的三大系統(tǒng)進(jìn)行查詢,分別是 CDP、DMP、CRM 場(chǎng)景的對(duì)比。最終有效查詢 SQL 16 條,線上場(chǎng)景下查詢 SQL 的具體特點(diǎn)如下:
如表格所示,我們將 Doris 與 Clickhouse 16 條 SQL 查詢時(shí)間對(duì)比,其中有 10 條 SQL Doris 查詢性能優(yōu)于 Clickhouse。 此外我們將 Doris 與 Clickhouse 查詢時(shí)間總和進(jìn)一步對(duì)比,在對(duì) Doris 表結(jié)構(gòu)設(shè)計(jì)優(yōu)化后,Doris 整體查詢速度相比 Clickhouse 快 2-3 倍。
大表 Join 查詢性能測(cè)試
在關(guān)聯(lián)查詢測(cè)試中,以 CDP 場(chǎng)景下的相關(guān)數(shù)據(jù)表為基礎(chǔ),我們選用了不同數(shù)據(jù)量級(jí)的主表與維表數(shù)據(jù),主表測(cè)試數(shù)據(jù)量分別為 40 億的用戶行為表、250 億的用戶額外屬性表、960 億的用戶額外屬性表;維表以 kdt_id + user_id 為基礎(chǔ),測(cè)試量級(jí)分別為 100 萬(wàn)、1000 萬(wàn)、5000 萬(wàn)、1 億、5 億、10 億及 25 億維表數(shù)據(jù)量。為了測(cè)試更加全面,關(guān)聯(lián)查詢測(cè)試分為完全關(guān)聯(lián)與過(guò)濾關(guān)聯(lián)兩種測(cè)試,完全關(guān)聯(lián)是將主表與維度表直接進(jìn)行 Join,過(guò)濾關(guān)聯(lián)是在相同主表量級(jí)關(guān)聯(lián)中,增加了 WHERE
條件對(duì)指定的兩個(gè)店鋪 ID 進(jìn)行過(guò)濾。
具體的查詢測(cè)試表現(xiàn)如下:
- 全關(guān)聯(lián) 40 億: 在 40 億主表完全關(guān)聯(lián)查詢中,Doris 查詢性能均優(yōu)于 Clickhouse,且隨著維表數(shù)據(jù)量級(jí)增大,Doris 與 Clickhouse 查詢耗時(shí)差距越大,其中 Doris 最高能夠達(dá)到 5 倍性能提升;
-
過(guò)濾指定店鋪關(guān)聯(lián) 40 億: 在過(guò)濾條件關(guān)聯(lián)查詢中,主表按照
WHERE
條件過(guò)濾后的數(shù)據(jù)為 4100 萬(wàn),相較于 Clickhouse,Doris 在維表數(shù)據(jù)量小的情況下能夠達(dá)到 2-3 倍的性能提升,在維表數(shù)據(jù)量大的情況達(dá)到 10 倍以上的性能提升,其中當(dāng)維度數(shù)據(jù)表超過(guò) 1 億后,Doris 依舊可以穩(wěn)定查詢,而 Clickhouse 由于 OOM 情況導(dǎo)致查詢失敗。 - 全關(guān)聯(lián) 250 億: 在 250 億 50 字段寬表作為主表完全關(guān)聯(lián)時(shí),Doris 查詢性能依舊優(yōu)于 Clickhouse,Doris 在所有維表量級(jí)中均能跑出,而 Clickhouse 在超過(guò) 5000 萬(wàn)后出現(xiàn) OOM 情況;
- 與過(guò)濾指定店鋪關(guān)聯(lián) 250 億: 在條件關(guān)聯(lián)查詢中,主表按照店鋪 ID 過(guò)濾數(shù)據(jù)為 5.7 億,Doris 的查詢響應(yīng)時(shí)間均達(dá)到了秒級(jí),而 Clickhouse 最快響應(yīng)時(shí)間也需要分鐘級(jí)耗時(shí),在數(shù)據(jù)量大的情況下更是無(wú)法跑出。
- 全關(guān)聯(lián)與過(guò)濾指定店鋪關(guān)聯(lián) 960 億: 不論是主表關(guān)聯(lián)查詢還是條件關(guān)聯(lián)查詢,Doris 均可跑出且響應(yīng)速度較快,Clickhouse 則在所有維表量級(jí)中無(wú)法跑出。
除響應(yīng)性能外,我們還對(duì)于 Doris 的 CPU 與內(nèi)存損耗進(jìn)行檢測(cè),發(fā)現(xiàn) Doris 在數(shù)百億計(jì)大表關(guān)聯(lián)查詢的情況下集群負(fù)載依舊穩(wěn)定。綜上,Apache Doris 在絕大部份場(chǎng)景查詢響應(yīng)速度快于 Clickhosue ,特別是在大表 Join 場(chǎng)景下,Apache Doris 性能表現(xiàn)完全優(yōu)于 Clickhouse。
03 Clickhouse 線上流量回放穩(wěn)定性測(cè)試
在查詢壓測(cè)完成后,我們開始將 Doris 與 Clickhouse 線上雙跑以進(jìn)一步驗(yàn)證 Doris 的穩(wěn)定性。具體步驟如下:
- 通過(guò)定時(shí)采集 Clickhouse 最近 1 分鐘的查詢狀態(tài)為 QueryFinish 的有效查詢信息。
- 將查詢信息上報(bào)至 Kafka,接著通過(guò) Flink 消費(fèi) Kafka Topic 獲取 Clickhouse 查詢 SQL 并統(tǒng)計(jì)結(jié)果。
- 在 Flink 中實(shí)現(xiàn) UDF 將 Clickhouse 查詢 SQL 轉(zhuǎn)化為 Doris 查詢 SQL,并由 JDBC 執(zhí)行。
- 獲取執(zhí)行結(jié)果與統(tǒng)計(jì)結(jié)果,與 Clcikhouse 執(zhí)行信息進(jìn)行對(duì)比最終存放至 RDS。
- 最終通過(guò)對(duì)線上 Clickhouse 查詢流量回放的統(tǒng)計(jì),分析 Doris 查詢性能與查詢數(shù)據(jù)準(zhǔn)確性。
04 Apache Doris 數(shù)據(jù)導(dǎo)入性能測(cè)試與優(yōu)化
數(shù)據(jù)導(dǎo)入性能測(cè)試是我們重要關(guān)注的環(huán)節(jié)之一,Apache Doris 本身對(duì)于實(shí)時(shí)數(shù)據(jù)和離線數(shù)據(jù)的導(dǎo)入提供了比較豐富的導(dǎo)入方式,實(shí)時(shí)數(shù)據(jù)的導(dǎo)入方式主要是通過(guò) Apache Flink 將 NSQ 和 Apache Kafka 的數(shù)據(jù)實(shí)時(shí)通過(guò) Stream Load 方式寫入 Apache Doris 中。在離線數(shù)據(jù)中,Doris 提供了多種導(dǎo)入方式:
- 支持通過(guò) Spark SQL 讀取外部數(shù)據(jù),通過(guò) Stream Load 方式寫入 Apache Doris;
- 支持通過(guò) Spark Load 方式,利用 Spark 集群資源將數(shù)據(jù)排序操作在 HDFS 中完成,再通過(guò) Broker Load 將數(shù)據(jù)寫入 Doris;
- 支持 Doris Multi-Catalog 功能直接讀取 外部數(shù)據(jù)源并通過(guò) Insert Into 方式寫入 Doris。
由于離線數(shù)據(jù)量較大,針對(duì)這類數(shù)據(jù)我們將幾種數(shù)據(jù)導(dǎo)入方式進(jìn)行了性能測(cè)試對(duì)比,通過(guò)明細(xì)數(shù)據(jù)的各個(gè)數(shù)據(jù)量級(jí)對(duì)比測(cè)試導(dǎo)入時(shí)間。 測(cè)試集群規(guī)模 3 FE + 16 BE,BE 單節(jié)點(diǎn)配置為( 32C 128 G 7T SSD)測(cè)試結(jié)果:
Spark Doris Connector 格式導(dǎo)入的并行度為 80,單批為 100 萬(wàn),集群的負(fù)載情況如下:
根據(jù)上方測(cè)試結(jié)果,我們進(jìn)一步分析各種導(dǎo)入方式的優(yōu)勢(shì)與后續(xù)調(diào)優(yōu)方案,希望以下的調(diào)優(yōu)實(shí)踐能夠幫助到有類似需求的開發(fā)者們:
Doris Insert Into
Insert Into 方式能夠提供快速導(dǎo)數(shù)性能,在用法上也相對(duì)簡(jiǎn)單,目前該方式的導(dǎo)入性能已經(jīng)足夠支持我們的業(yè)務(wù)需求。
Spark Doris Connector 支持阻塞寫入
Spark Doris Connector 導(dǎo)入方式更具有通用性,能夠解決大量數(shù)據(jù)導(dǎo)入的問(wèn)題,導(dǎo)入性能相對(duì)穩(wěn)定,在導(dǎo)入過(guò)程我們需要合理控制導(dǎo)入速率與導(dǎo)入并行度。考慮到我們的業(yè)務(wù)場(chǎng)景每天會(huì)涉及千億級(jí)別的數(shù)據(jù)量并花費(fèi) 5-6 個(gè)小時(shí)進(jìn)行導(dǎo)入,對(duì)于這類大表數(shù)據(jù)的導(dǎo)入如果因?yàn)?BE 寫入被拒絕導(dǎo)致失敗,會(huì)造成下游數(shù)據(jù)產(chǎn)出延遲等問(wèn)題。此外,在 2.0 版本中,類似 -235,-238 錯(cuò)誤已經(jīng)在 Apache Doris 內(nèi)核層面解決,無(wú)需用戶再手動(dòng)處理此類問(wèn)題。
我們主要從控制寫入速度入手,整體改造原理是通過(guò)指數(shù)退避寫入的方式延遲阻塞,利用配置參數(shù)使大數(shù)據(jù)量出現(xiàn)導(dǎo)入異常時(shí)可以等待重試,不讓任務(wù)失敗。通過(guò)最大阻塞次數(shù)、單次最大阻塞時(shí)間、需要阻塞異常捕獲關(guān)鍵詞這三個(gè)參數(shù)來(lái)捕獲阻塞異常情況,實(shí)現(xiàn)阻塞退避功能。最終在該設(shè)置下,我們的大表導(dǎo)入數(shù)據(jù)成功率達(dá) 95%以上。
[1] 相關(guān) PR: https://github.com/apache/doris-spark-connector/pull/117
Spark Doris Connector 支持 Bitmap 數(shù)據(jù)導(dǎo)入
在閱讀 Apache Doris 官方文檔時(shí),我們發(fā)現(xiàn) Spark Load 的方式可以對(duì) Bitmap 數(shù)據(jù)進(jìn)行導(dǎo)入,同時(shí)能夠?qū)?Bitmap 數(shù)據(jù)計(jì)算放在 Spark 集群中進(jìn)行計(jì)算。在業(yè)務(wù)實(shí)踐中,我們使用 Spark Doris Connector 更為常用,于是開始探索通過(guò) Spark Doris Connector 的方式實(shí)現(xiàn) Bitmap 數(shù)據(jù)導(dǎo)入。
如上圖所示,Bitmap 建表語(yǔ)句主要分為三個(gè)字段,其中最后一個(gè)字段是將 CASE_ID 進(jìn)行 Bitmap 計(jì)算。在與社區(qū)成員溝通之后,提供一種設(shè)置 Doris Read Field 選項(xiàng),寫除 Bitmap 列外的其他列,同時(shí)在 Doris Write Field 中做映射處理。最終實(shí)現(xiàn)如上圖所示方式通過(guò) Spark Doris Connect 直接將 Apache Hive 明細(xì)數(shù)據(jù)導(dǎo)入 Apache Doris 的 Bitmap 數(shù)據(jù)中。
Spark Doris Connector CSV 格式導(dǎo)入優(yōu)化
在我們的導(dǎo)入流程中,無(wú)論是 Spark Doris Connector 還是 Flink Doris Connector,最終都是利用 Stream Load 的方式進(jìn)行導(dǎo)入,其導(dǎo)入文件 CSV 與 JSON 有兩種導(dǎo)入格式且對(duì)于不同格式的選擇,導(dǎo)入性能的損耗與速率也是不同的。
在優(yōu)化前,我們進(jìn)行了測(cè)試,以數(shù)十億數(shù)據(jù)規(guī)模、26 個(gè)字段的業(yè)務(wù)表進(jìn)行導(dǎo)入性能測(cè)試,發(fā)現(xiàn) CSV 格式比 JSON 的導(dǎo)入速度快近 40% 且其內(nèi)存消耗是更低的,這也是為什么 Apache Doris 官方推薦使用 CSV 格式。
其中值得注意的是使用 CSV 格式進(jìn)行導(dǎo)入時(shí),設(shè)置合理的字段分隔符和換行符對(duì)于 CSV Reader 識(shí)別效率是至關(guān)重要的,如果 BE 的 CSV Reader 對(duì)于字段中最后一個(gè)字符和分隔符的首字符相同時(shí),則無(wú)法識(shí)別分隔符。
通過(guò)官方文檔的提示,我們發(fā)現(xiàn) Stream Load 中能夠支持參數(shù)配置去除字段最外層的雙引號(hào),基于此我們決定在 Spark Doris Connector 寫入階段添加用戶設(shè)置配置,在字段外層拼接雙引號(hào),保證不用選定特殊字符依然能夠有效分隔,同時(shí)在 Stream Load 寫入階段添加去除最外層雙引號(hào)的配置。通過(guò)兩端配置,能夠保證即使業(yè)務(wù)數(shù)據(jù)很復(fù)雜的情況下,也無(wú)需為字段符號(hào)的識(shí)別而煩惱,有效保證字段能夠正常分割。
[2] 相關(guān) PR: https://github.com/apache/doris-spark-connector/pull/119
Spark Load
Spark Load 導(dǎo)入方式的特點(diǎn)是基于 Spark 資源進(jìn)行 Shuffle、排序等工作將文件輸出在 HDFS 中,之后 BE 節(jié)點(diǎn)能夠直接讀取 HDFS 上的文件并按照 Doris 格式寫入?;谶@種方式,在測(cè)試過(guò)程中我們發(fā)現(xiàn)當(dāng)數(shù)據(jù)量越大時(shí)導(dǎo)入速度越快、越能夠節(jié)省 Doris 的集群資源,不會(huì)帶來(lái)較大性能損耗。
由于 Spark Load 在臨時(shí)修復(fù)數(shù)據(jù)場(chǎng)景中使用頻繁,我們也基于測(cè)試進(jìn)一步優(yōu)化。通過(guò)官網(wǎng)文檔與社區(qū)幫助下我們發(fā)現(xiàn),Spark Load 階段的導(dǎo)入速率主要由單次導(dǎo)入并發(fā)度和單次 BE 導(dǎo)入數(shù)據(jù)處理量?jī)煞矫鎱?shù)影響,且兩個(gè)參數(shù)都與源文件大小、BE 節(jié)點(diǎn)密切相關(guān)。當(dāng)控制其他變量的情況下,源文件越小,導(dǎo)入速度越慢,因此我們認(rèn)為在 ETL 階段充分利用 Spark 經(jīng)營(yíng)資源并且合理設(shè)置 Bucket 數(shù)量能夠有效加速導(dǎo)入速率。
未來(lái)規(guī)劃與展望
在整體測(cè)試環(huán)節(jié)中,基于 Apache Doris 2.0 正式版本的性能測(cè)試已經(jīng)完成,我們對(duì)于 Doris 的查詢性能表現(xiàn)是十分滿意的。此外,對(duì)于導(dǎo)入性能,我們?cè)跍y(cè)試時(shí)首先采用的是 Doris 2.0-Alpha 版本,發(fā)現(xiàn)在導(dǎo)入過(guò)程中存在偶發(fā)性 CPU 瓶頸的問(wèn)題,例如當(dāng)通過(guò) Spark Doris Connector 的方式,Spark 使用資源和 Doris 導(dǎo)入數(shù)據(jù) CPU 存在一定的瓶頸。同時(shí),我們也將問(wèn)題反饋給社區(qū),在經(jīng)過(guò)社區(qū)優(yōu)化與 2.0-Beta 版本發(fā)布后,穩(wěn)定性得到了改善。
目前,我們正在與 Clickhouse 線上雙跑對(duì) Doris 的穩(wěn)定性進(jìn)一步驗(yàn)證,同時(shí)我們正在對(duì) Spark Doris Connector 導(dǎo)入方式的的進(jìn)行性能優(yōu)化、開發(fā)導(dǎo)入周邊工具以完成組件替換等落地工作。后續(xù)在逐步完成 Clickhouse 的業(yè)務(wù)遷移后,基于 Clickhouse 的遷移經(jīng)驗(yàn),對(duì)未遷移的存量業(yè)務(wù)逐步完成 Druid、Kylin 兩個(gè)組件的遷移,最終基于 Apache Doris 構(gòu)建極速分析、實(shí)時(shí)統(tǒng)一的數(shù)據(jù)倉(cāng)庫(kù)。
在此非常感謝 SelectDB 技術(shù)團(tuán)隊(duì)的積極響應(yīng)與專業(yè)解答,加速有贊業(yè)務(wù)的遷移進(jìn)程,也希望通過(guò)這篇文章為準(zhǔn)備進(jìn)行架構(gòu)遷移的企業(yè)提供相關(guān)實(shí)踐經(jīng)驗(yàn)和 OLAP 選型參考。最后,我們也會(huì)持續(xù)參與社區(qū)活動(dòng),將相關(guān)成果貢獻(xiàn)回饋社區(qū),希望 Apache Doris 飛速發(fā)展,越來(lái)越好!
參考 GitHub PR:
[1] Spark Doris Connector 支持阻塞寫入
https://github.com/apache/doris-spark-connector/pull/117
[2] Spark Doris Connector CSV 格式導(dǎo)入優(yōu)化
https://github.com/apache/doris-spark-connector/pull/119
[3] Spark Load 創(chuàng)建 Hive 外表支持 Hive 版本設(shè)置
https://github.com/apache/doris/pull/20622
[4] Spark Load 系統(tǒng)環(huán)境變量獲取優(yōu)化
https://github.com/apache/doris/pull/21837
[5] HIve 外表屬性在 Spark Load 不生效優(yōu)化文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-707290.html
https://github.com/apache/doris/pull/21881文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-707290.html
到了這里,關(guān)于從 Clickhouse 到 Apache Doris:有贊業(yè)務(wù)場(chǎng)景下性能測(cè)試與遷移驗(yàn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!