大數(shù)據(jù)分析引擎-Doris簡要介紹

目錄:

1、背景

2、Doris的架構(gòu)

3、Doris的核心特性

4、數(shù)據(jù)的導(dǎo)入和輸出

1、背景

大數(shù)據(jù)的時代,數(shù)據(jù)的處理能力大大增強(qiáng),但在最后一個環(huán)節(jié),即數(shù)據(jù)應(yīng)用服務(wù)環(huán)節(jié)依然存在較大的瓶頸。

原來業(yè)務(wù)數(shù)據(jù)庫時代,高并發(fā)、高靈活性是一個矛盾體,如何讓一線在靈活定制分析SQL時候,雖然拖拉拽生成了不忍直視的SQL,但希望查詢引擎依舊可以保持強(qiáng)勁的性能指標(biāo),不管是并發(fā)度還是查詢時間都能讓客戶滿意,是蠻有挑戰(zhàn)的一件事情。

目前的查詢分析非常多,并且還在不斷的涌現(xiàn)出來,引擎層出不窮,各有優(yōu)勢也有其缺點(diǎn),比如ADB、Hologres、Presto、Kylin、Hbase、Doris,這些產(chǎn)品本質(zhì)上都是用資源換時間,或者空間換時間,本質(zhì)上就是計(jì)算機(jī)制重構(gòu)(比如MPP)、硬件提速(比如SSD磁盤)、索引提速(比如位圖)、空間轉(zhuǎn)換(比如預(yù)計(jì)算)等維度是提升性能。不斷涌現(xiàn)且更新的技術(shù)產(chǎn)品也從側(cè)面印證了查詢引擎的問題依然很多,痛點(diǎn)依舊沒有解決,同時也大有可為。

Doris最近也是比較火的一款產(chǎn)品,脫胎于百度的廣告業(yè)務(wù),適應(yīng)于實(shí)時分析場景,確實(shí)解決了查詢引擎的一些場景下的痛點(diǎn)問題,接下來就將個人對Doris的一些理解簡單介紹一下。

2、Doris架構(gòu)

在介紹Doris的特性之前,先讓我們了解一下Doris的整體架構(gòu)。具體包括幾個核心維度:

MPP的運(yùn)行框架,充分挖掘多核CPU的并行計(jì)算能力;

分布式架構(gòu)支持多副本支撐高可用;

接入了多個大數(shù)據(jù)的生態(tài),比如Spark, Flink, Hive, ElasticSearch,提供了豐富的數(shù)據(jù)接入和輸出的服務(wù);

采取分區(qū)分桶的機(jī)制,支持多種索引技術(shù),滿足PB級的存儲和分析能力;

支持Mysql協(xié)作,簡單、易用;

列式存儲和壓縮技術(shù),提升查詢性能;

Doris由FrontEnd DorisDB前端節(jié)點(diǎn)和BackEnd DorisDB后端節(jié)點(diǎn)核心組件組成;前端節(jié)點(diǎn)負(fù)責(zé)管理元數(shù)據(jù)、管理客戶端的連接、進(jìn)行查詢規(guī)劃和調(diào)度等工作;后端節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)存儲、計(jì)算執(zhí)行、副本管理等;另外還包括DorisManager和Broker,DorisManager管理工具,負(fù)責(zé)提供集群管理、在線查詢、故障查詢、監(jiān)控報(bào)警的可視化工具;Broker負(fù)責(zé)和外部存儲(HDFS或?qū)ο蟠鎯Γ┻M(jìn)行數(shù)據(jù)的導(dǎo)出導(dǎo)入等輔助功能;Doris可以通過MySQL客戶端直接訪問。

Doris核心組件及運(yùn)行模式如下(以下FrontEnd DorisDB簡稱FE,BackEnd DorisDB簡稱BE):

首先是FE:

管理元數(shù)據(jù), 執(zhí)行SQL DDL命令, 用Catalog記錄庫, 表, 分區(qū), tablet副本等信息。

FE高可用部署, 使用復(fù)制協(xié)議選主和主從同步元數(shù)據(jù), 所有的元數(shù)據(jù)修改操作, 由FE leader節(jié)點(diǎn)完成, FE follower節(jié)點(diǎn)可執(zhí)行讀操作。 元數(shù)據(jù)的讀寫滿足順序一致性。 ?FE的節(jié)點(diǎn)數(shù)目采用2n+1, 可容忍n個節(jié)點(diǎn)故障。 ?當(dāng)FE leader故障時, 從現(xiàn)有的follower節(jié)點(diǎn)重新選主, 完成故障切換。

FE的SQL layer對用戶提交的SQL進(jìn)行解析, 分析, 改寫, 語義分析和關(guān)系代數(shù)優(yōu)化, 生產(chǎn)邏輯執(zhí)行計(jì)劃。

FE的Planner負(fù)責(zé)把邏輯計(jì)劃轉(zhuǎn)化為可分布式執(zhí)行的物理計(jì)劃, 分發(fā)給一組BE。

FE監(jiān)督BE, 管理BE的上下線, 根據(jù)BE的存活和健康狀態(tài), 維持tablet副本的數(shù)量。

FE協(xié)調(diào)數(shù)據(jù)導(dǎo)入, 保證數(shù)據(jù)導(dǎo)入的一致性。

其次是BE:

BE管理tablet副本, tablet是table經(jīng)過分區(qū)分桶形成的子表, 采用列式存儲。

BE受FE指導(dǎo), 創(chuàng)建或刪除子表。

BE接收FE分發(fā)的物理執(zhí)行計(jì)劃并指定BE coordinator節(jié)點(diǎn), 在BE coordinator的調(diào)度下, 與其他BE worker共同協(xié)作完成執(zhí)行。

BE讀本地的列存儲引擎獲取數(shù)據(jù),并通過索引和謂詞下沉快速過濾數(shù)據(jù)。

BE后臺執(zhí)行compact任務(wù), 減少查詢時的讀放大。

數(shù)據(jù)導(dǎo)入時, 由FE指定BE coordinator, 將數(shù)據(jù)以fanout的形式寫入到tablet多副本所在的BE上。

以查詢?yōu)槔?,通過FE的組織、協(xié)調(diào)、控制,對提交的SQL進(jìn)行解析, 分析, 改寫, 優(yōu)化和規(guī)劃, 生成分布式執(zhí)行計(jì)劃,然后由若干BE執(zhí)行,并在若干BE中選定一個協(xié)作者coordinator,由協(xié)作者協(xié)調(diào)n個BE進(jìn)行本地計(jì)算,然后返回給協(xié)作者,協(xié)作者匯總后返回給FE最終結(jié)果,最后由FE將最終結(jié)果提供給最終用戶。

3、Doris的核心特性

Doris具體具備什么樣的核心特性,讓我們看看他能做什么。

1)表是如何設(shè)計(jì)?列式存儲;稀疏索引Shortkey Index;加速數(shù)據(jù)處理(預(yù)先聚合、分區(qū)分桶、RollUp表物化索引、列級別的索引技術(shù)布隆過濾器和Bitmap索引);

2)數(shù)據(jù)模型有哪些?明細(xì)模型DUPLICATE、聚合模型AGGREGATE、更新模型UNIQUE;每個模型后都需要指定排序鍵;對于不同的應(yīng)用場景,采取不同的數(shù)據(jù)模型,滿足高性能的要求;

3)數(shù)據(jù)分布有幾種?Round-Robin輪轉(zhuǎn)范圍、Round指定區(qū)分范圍、離散List、哈希Hash;同時還支持動態(tài)分區(qū)分布;分區(qū)分桶是為了MPP最大化利用資源,為防止數(shù)據(jù)傾斜,需要選擇合理的分布策略;

4)物化視圖:相較于聚合模型的匯總分析的數(shù)據(jù)不一致性,物化視圖天然的數(shù)據(jù)一致性是它最大的優(yōu)點(diǎn)。

物化視圖的組織形成與基表、RollUp表相同,創(chuàng)建后,基本的數(shù)據(jù)會自動以異步的方式填充分到物化視圖中;數(shù)據(jù)導(dǎo)入時,基表和物化視圖保持原子型保證數(shù)據(jù)的一致性。物化視圖創(chuàng)建后,不能通過命令直接查詢,還是查基表,是否用物化視圖,需要由執(zhí)行計(jì)劃自動選擇,可以查詢是否使用了物化視圖。todo基表、Rollup物化索引、物化視圖都是使用前綴索引。

可以使用bitmap_union創(chuàng)建物化視圖來處理精確去重;也可以使用hll_union創(chuàng)建物化視圖來處理近億去重;也可以匹配更豐富的前綴索引,比如用戶的基表tableA有(k1, k2, k3) 三列。其中 k1, k2 為排序鍵。這時候如果用戶查詢條件中包含 where k1=1 and k2=2 就能通過shortkey索引加速查詢。但是用戶查詢語句中使用條件k3=3, 則無法通過shortkey索引加速. 此時, 可創(chuàng)建以k3作為第一列的物化視圖。

當(dāng)然也有一些限制,分區(qū)列必須在Groupby中;不支持Key列聚合只支持Value列聚合;不支持指定物化視圖查詢;只支持單例聚合,不支持表達(dá)式(比如sum(a+b)) ;過多的物化視圖,會影響導(dǎo)入數(shù)據(jù)的效率,比如有20張物化視圖,則相當(dāng)于導(dǎo)入20張表,但不影響查詢性能,在有物化索引或物化視圖的情況下,性能會更好;相同列,不同聚合函數(shù),不能同時出現(xiàn)在一張物化視圖中;物化視圖不支持Join和where,不支持Groupby的Having子句;不能并行只能串行創(chuàng)建物化視圖;

5)Bitmap索引:Bitmap索引的原理就是將RawData進(jìn)行Dictionary的轉(zhuǎn)提煉,然后基于Dictionary(Value、ID)的ID進(jìn)行BitmapIndex(ID、Bitmap)的存儲和查詢。一般為0和1,如果是多值列,則需要轉(zhuǎn)化為某值為0,其他值為1;

當(dāng)然也有一些限制,對于聚合模型,只支持Key列Bitmap索引;適用于大量重復(fù)、較低基數(shù)的場景;不支持Float、Double、Decimal類型列建Bitmap索引;通過查詢的Profile信息查看是否使用了索引;

6)Bitmap精確去重:重有2種,一個傳統(tǒng)的是count distinct,優(yōu)點(diǎn)是保留明細(xì)數(shù)據(jù),缺點(diǎn)是消耗極大的計(jì)算和存儲資源;一個是基于預(yù)計(jì)算,在用戶不關(guān)心明細(xì)數(shù)據(jù)的情況下,采取預(yù)計(jì)算的方式去重,用空間換時間,效果不錯,MOLAP的核心思路也是如此。

Doris使用Bitmap去重,原理即給定1個數(shù)組,其取值范圍為[0,n](不包括n),對該數(shù)組去重,可采用(n+7)/8的字節(jié)長度的Bitmap,初始化為0;逐個處理數(shù)組元素,以數(shù)組中元素取值作為Bitmap的下標(biāo),將該下標(biāo)的bit置為1;最后統(tǒng)計(jì)Bitmap中1的個數(shù)即為數(shù)組的count distinct的結(jié)果。

使用Bitmap去重的優(yōu)勢:空間優(yōu)勢,對于Int32的去重,只需要1/32空間,在Doris中,使用Roaring Bitmap存儲空間會進(jìn)一步降低。時間優(yōu)勢:基于Bitmap的操作比基于Sort和基于Hash的去重效率都要高,復(fù)雜度只有O(1)~O(n),并且無條件依賴和數(shù)據(jù)依賴,可向量化執(zhí)行。

當(dāng)然以有些限制,包括只能用于聚合表,明細(xì)表和更新表不支持Bitmap列;數(shù)據(jù)類型只能是BITMAP,聚合函數(shù)為BITMAP_UNION;在Bitmap列上使用count distinct,自動轉(zhuǎn)換為BITMAP_UNION_COUNT計(jì)算。

7)Bloomfilter索引:用于判斷某個元素是否在一個集合中的數(shù)據(jù)結(jié)構(gòu),優(yōu)點(diǎn)是空間效率和時間效率都比較高,缺點(diǎn)是有一定的誤判率,但不存集合中時,一定會報(bào)不存在。布隆過濾器由Bit數(shù)組和N個哈希函數(shù)構(gòu)成,Bit數(shù)據(jù)組實(shí)始全為0,當(dāng)一個元素插入時,則通過N個哈希函數(shù)進(jìn)行計(jì)算n個Slot,然后將Bit數(shù)組中的n個Slot的Bit置1。當(dāng)判斷某一個值是否存在時,就通過N個哈希函數(shù)計(jì)算n個Slot,如果n個Slot對應(yīng)的Bit位都為1,則集合存在,只要有一個Bit為0,則不存在。由于Bit數(shù)組位數(shù)有限,所以Bit位通過不同的哈希函數(shù)計(jì)算完成后,Bit是相同或沖突的,所以全1的情形也不一定真存在;與Bitmap的適用場景相反,適用用于高基數(shù)的場景,一般用于in條件的比較多,=條件也適用;

當(dāng)然也有一些限制:不支持Tinyint、Float、Double 類型的列建Bloom Filter索引;只支持in和=過濾查詢;通過查詢的Profile信息查看是否使用了索引;

8)外部表:DorisDB支持以外部表的形式,接入其他數(shù)據(jù)源。外部表指的是保存在其他數(shù)據(jù)源中的數(shù)據(jù)表。目前DorisDB已支持的第三方數(shù)據(jù)源包括MySQL、HDFS、ElasticSearch,Hive。對這幾種種數(shù)據(jù)源,現(xiàn)階段只支持讀取,還不支持寫入。

9)Doris還支持?jǐn)?shù)組、窗口函數(shù)、HyperLogLog去重、broadcast join、?Lateral Join等一些應(yīng)用,在這里就不一一介紹了,可以看看官方資料。

4、數(shù)據(jù)的導(dǎo)入和輸出

導(dǎo)入:

根據(jù)不同的數(shù)據(jù)來源可以選擇不同的導(dǎo)入方式:

1)離線數(shù)據(jù)導(dǎo)入,如果數(shù)據(jù)源是Hive/HDFS,推薦采用Broker Load導(dǎo)入, 如果數(shù)據(jù)表很多導(dǎo)入比較麻煩可以考慮使用Hive外表直連查詢,性能會比Broker load導(dǎo)入效果差,但是可以避免數(shù)據(jù)搬遷,如果單表的數(shù)據(jù)量特別大,或者需要做全局?jǐn)?shù)據(jù)字典來精確去重可以考慮Spark Load導(dǎo)入。

2)實(shí)時數(shù)據(jù)導(dǎo)入,日志數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)庫的binlog同步到Kafka以后,優(yōu)先推薦通過Routine load導(dǎo)入DorisDB,如果導(dǎo)入過程中有復(fù)雜的多表關(guān)聯(lián)和ETL預(yù)處理可以使用Flink處理以后用stream load寫入DorisDB,我們有標(biāo)準(zhǔn)的Flink-connector?可以方便Flink任務(wù)使用

3)程序?qū)懭隓orisDB,推薦使用Stream Load,可以參考例子中有java python shell的demo,

4)文本文件導(dǎo)入推薦使用 Stream load

5)Mysql數(shù)據(jù)導(dǎo)入,推薦使用Mysql外表,insert into new_table select * from external_table 的方式導(dǎo)入

6)其他數(shù)據(jù)源導(dǎo)入,推薦使用DataX導(dǎo)入,我們提供了DataX-dorisdb-writer

7)DorisDB內(nèi)部導(dǎo)入,可以在DorisDB內(nèi)部使用insert into tablename select?的方式導(dǎo)入,可以跟外部調(diào)度器配合實(shí)現(xiàn)簡單的ETL處理。

一個導(dǎo)入作業(yè)主要分為5個階段:

1)PENDING

非必須。該階段是指用戶提交導(dǎo)入作業(yè)后,等待FE調(diào)度執(zhí)行。

Broker Load和將來的Spark Load包括該步驟。

2)ETL

非必須。該階段執(zhí)行數(shù)據(jù)的預(yù)處理,包括清洗、分區(qū)、排序、聚合等。

Spark Load包括該步驟,它使用外部計(jì)算資源Spark完成ETL。

3)LOADING

該階段先對數(shù)據(jù)進(jìn)行清洗和轉(zhuǎn)換,然后將數(shù)據(jù)發(fā)送給BE處理。當(dāng)數(shù)據(jù)全部導(dǎo)入后,進(jìn)入等待生效過程,此時導(dǎo)入作業(yè)狀態(tài)依舊是LOADING。

4)FINISHED

在導(dǎo)入作業(yè)涉及的所有數(shù)據(jù)均生效后,作業(yè)的狀態(tài)變成 FINISHED,F(xiàn)INISHED后導(dǎo)入的數(shù)據(jù)均可查詢。FINISHED是導(dǎo)入作業(yè)的最終狀態(tài)。

5)CANCELLED

在導(dǎo)入作業(yè)狀態(tài)變?yōu)镕INISHED之前,作業(yè)隨時可能被取消并進(jìn)入CANCELLED狀態(tài),如用戶手動取消或?qū)氤霈F(xiàn)錯誤等。CANCELLED也是導(dǎo)入作業(yè)的一種最終狀態(tài)。

適用場景:

1)HDFS導(dǎo)入

源數(shù)據(jù)存儲在HDFS中,數(shù)據(jù)量為幾十GB到上百GB時,可采用Broker Load方法向DorisDB導(dǎo)入數(shù)據(jù)。此時要求部署的Broker進(jìn)程可以訪問HDFS數(shù)據(jù)源。導(dǎo)入數(shù)據(jù)的作業(yè)異步執(zhí)行,用戶可通過SHOW LOAD命令查看導(dǎo)入結(jié)果。

源數(shù)據(jù)存儲在HDSF中,數(shù)據(jù)量達(dá)到TB級別時,可采用Spark Load方法向DorisDB導(dǎo)入數(shù)據(jù)。此時要求部署的Spark進(jìn)程可以訪問HDFS數(shù)據(jù)源。導(dǎo)入數(shù)據(jù)的作業(yè)異步執(zhí)行,用戶可通過SHOW LOAD命令查看導(dǎo)入結(jié)果。

對于其它外部數(shù)據(jù)源,只要Broker或Spark進(jìn)程能讀取對應(yīng)數(shù)據(jù)源,也可采用Broker Load或Spark Load方法導(dǎo)入數(shù)據(jù)。

2)本地文件導(dǎo)入

數(shù)據(jù)存儲在本地文件中,數(shù)據(jù)量小于10GB,可采用Stream Load方法將數(shù)據(jù)快速導(dǎo)入DorisDB系統(tǒng)。采用HTTP協(xié)議創(chuàng)建導(dǎo)入作業(yè),作業(yè)同步執(zhí)行,用戶可通過HTTP請求的返回值判斷導(dǎo)入是否成功。

3)Kafka導(dǎo)入

數(shù)據(jù)來自于Kafka等流式數(shù)據(jù)源,需要向DorisDB系統(tǒng)導(dǎo)入實(shí)時數(shù)據(jù)時,可采用Routine Load方法。用戶通過MySQL協(xié)議創(chuàng)建例行導(dǎo)入作業(yè),DorisDB持續(xù)不斷地從Kafka中讀取并導(dǎo)入數(shù)據(jù)。

4)Insert Into導(dǎo)入

手工測試及臨時數(shù)據(jù)處理時可以使用Insert Into方法向DorisDB表中寫入數(shù)據(jù)。其中,INSERT INTO tbl SELECT ...;語句是從 DorisDB 的表中讀取數(shù)據(jù)并導(dǎo)入到另一張表;INSERT INTO tbl VALUES(...);語句向指定表里插入單條數(shù)據(jù)。

5)同時,還有其他一些方式Json數(shù)據(jù)導(dǎo)入(對于一些半結(jié)構(gòu)化的比如Json類型的數(shù)據(jù),我們可以用stream load 或者 routine load的方式進(jìn)行導(dǎo)入。Stream Load: 對于文本文件存儲的Json數(shù)據(jù),我們可以使用 stream load進(jìn)行導(dǎo)入。Routine Load:對于Kafka中的json格式數(shù)據(jù),可以使用Routine load的方式導(dǎo)入)、flink-connector-dorisdb(內(nèi)部實(shí)現(xiàn)是通過緩存并批量由stream load導(dǎo)入)、DataX-dorisdb-writer(DorisWriter 插件實(shí)現(xiàn)了寫入數(shù)據(jù)到 DorisDB 的目的表的功能。在底層實(shí)現(xiàn)上, DorisWriter 通過Stream load以csv或 json 格式導(dǎo)入數(shù)據(jù)至DorisDB。內(nèi)部將reader讀取的數(shù)據(jù)進(jìn)行緩存后批量導(dǎo)入至DorisDB,以提高寫入性能??傮w數(shù)據(jù)流是?source -> Reader -> DataX channel -> Writer -> DorisDB。)

輸出:

數(shù)據(jù)導(dǎo)出(Export)是 DorisDB 提供的一種將數(shù)據(jù)導(dǎo)出并存儲到其他介質(zhì)上的功能。該功能可以將用戶指定的表或分區(qū)的數(shù)據(jù),以文本的格式,通過 Broker 進(jìn)程導(dǎo)出到遠(yuǎn)端存儲上,如 HDFS/阿里云OSS/AWS S3(或者兼容S3協(xié)議的對象存儲) 等。

用戶提交一個導(dǎo)出作業(yè)后,DorisDB 會統(tǒng)計(jì)這個作業(yè)涉及的所有 Tablet,然后對這些 Tablet 進(jìn)行分組,每組生成一個特殊的查詢計(jì)劃。該查詢計(jì)劃會讀取所包含的 Tablet 上的數(shù)據(jù),然后通過 Broker 將數(shù)據(jù)寫到遠(yuǎn)端存儲指定的路徑中。

處理流程主要包括:

1)用戶提交一個 Export 作業(yè)到 FE。

2)FE 的導(dǎo)出調(diào)度器會通過兩階段來執(zhí)行一個導(dǎo)出作業(yè):

3)PENDING:FE 生成一個?ExportPendingTask,向 BE 發(fā)送 snapshot 命令,對所有涉及到的 Tablet 做一個快照,并生成多個查詢計(jì)劃。

4) EXPORTING:FE 生成一個?ExportExportingTask,開始執(zhí)行一個個的查詢計(jì)劃。

Spark DorisDB Connector 可以支持通過 Spark 讀取 DorisDB 中存儲的數(shù)據(jù)。

1)當(dāng)前版本只支持從DorisDB中讀取數(shù)據(jù)。

2)可以將DorisDB表映射為DataFrame或者RDD,推薦使用DataFrame。

3)支持在DorisDB端完成數(shù)據(jù)過濾,減少數(shù)據(jù)傳輸量。

以上內(nèi)容,大部分是官方資料,中間增加了我的個人理解??偟膩碚f,從存儲機(jī)制、索引機(jī)制、運(yùn)行機(jī)制、支撐場景等維度進(jìn)行了簡要說明,確實(shí)也能解決一部分的應(yīng)用問題。

后續(xù)應(yīng)用深入后,再分享實(shí)踐相關(guān)的內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容