Druid Storage 原理(轉)

作者: 康凱森

日期: 2017-11-02

分類:?OLAP

What is Druid

Why Druid

Druid 架構

Column

Segment

Segment的存儲格式

指標列的存儲格式

String 維度的存儲格式

Segment生成過程

Segment load過程

Segment Query過程

Druid的編碼和壓縮

總結

參考資料

本文主要介紹Druid Storage的原理蕊程,包括Druid Storage的存儲格式剥懒,不同列的Serde方式啤覆,以及Druid Storage的底層查詢原理。在介紹Druid Storage之前秧荆,我先對Druid的整體架構和核心概念做下簡單介紹亚亲。

What is Druid

Druid是一個開源的實時OLAP系統(tǒng)氏堤,可以對超大規(guī)模數(shù)據(jù)提供亞秒級查詢,其具有以下特點:

列式存儲

倒排索引 (基于Bitmap實現(xiàn))

分布式的Shared-Nothing架構 (高可用慢蜓,易擴展是Druid的設計目標)

實時攝入 (數(shù)據(jù)被Druid實時攝入后便可以立即查詢)

Why Druid

為了能夠提取利用大數(shù)據(jù)的商業(yè)價值亚再,我們必然需要對數(shù)據(jù)進行分析,尤其是多維分析胀瞪, 但是在幾年前针余,整個業(yè)界并沒有一款很好的OLAP工具,各種多維分析的方式如下圖所示:

其中直接基于Hive凄诞,MR圆雁,Spark的方式查詢速度一般十分慢,并發(fā)低帆谍;而傳統(tǒng)的關系型數(shù)據(jù)庫無法支撐大規(guī)模數(shù)據(jù)伪朽;以HBase為代表的NoSQL數(shù)據(jù)庫也無法提供高效的過濾,聚合能力汛蝙。正因為現(xiàn)有工具有著各種各樣的痛點烈涮,Druid應運而生朴肺,以下幾點自然是其設計目標:

快速查詢

可以支撐大規(guī)模數(shù)據(jù)集

高效的過濾和聚合

實時攝入

Druid 架構

Druid的整體架構如上圖所示,其中主要有3條路線:

實時攝入的過程: 實時數(shù)據(jù)會首先按行攝入Real-time Nodes坚洽,Real-time Nodes會先將每行的數(shù)據(jù)加入到1個map中戈稿,等達到一定的行數(shù)或者大小限制時,Real-time Nodes 就會將內存中的map 持久化到磁盤中讶舰,Real-time Nodes 會按照segmentGranularity將一定時間段內的小文件merge為一個大文件鞍盗,生成Segment,然后將Segment上傳到Deep Storage(HDFS跳昼,S3)中般甲,Coordinator知道有Segment生成后,會通知相應的Historical Node下載對應的Segment鹅颊,并負責該Segment的查詢间雀。

離線攝入的過程: 離線攝入的過程比較簡單财松,就是直接通過MR job 生成Segment媒区,剩下的邏輯和實時攝入相同:

用戶查詢過程: 用戶的查詢都是直接發(fā)送到Broker Node扩然,Broker Node會將查詢分發(fā)到Real-time節(jié)點和Historical節(jié)點,然后將結果合并后返回給用戶帝雇。

各節(jié)點的主要職責如下:

Historical Nodes

Historical 節(jié)點是整個Druid集群的骨干挽牢,主要負責加載不可變的segment,并負責Segment的查詢(注意摊求,Segment必須加載到Historical 的內存中才可以提供查詢)禽拔。Historical 節(jié)點是無狀態(tài)的,所以可以輕易的橫向擴展和快速恢復室叉。Historical 節(jié)點load和un-load segment是依賴ZK的睹栖,但是即使ZK掛掉,Historical依然可以對已經(jīng)加載的Segment提供查詢茧痕,只是不能再load 新segment野来,drop舊segment。

Broker Nodes

Broker 節(jié)點是Druid查詢的入口踪旷,主要負責查詢的分發(fā)和Merge曼氛。 之外,Broker還會對不可變的Segment的查詢結果進行LRU緩存令野。

Coordinator Nodes

Coordinator 節(jié)點主要負責Segment的管理舀患。Coordinator 節(jié)點會通知Historical節(jié)點加載新Segment,刪除舊Segment气破,復制Segment聊浅,以及Segment間的復雜均衡。

Coordinator 節(jié)點依賴ZK確定Historical的存活和集群Segment的分布。

Real-time Node

實時節(jié)點主要負責數(shù)據(jù)的實時攝入低匙,實時數(shù)據(jù)的查詢旷痕,將實時數(shù)據(jù)轉為Segment,將Segment Hand off 給Historical 節(jié)點顽冶。

Zookeeper

Druid依賴ZK實現(xiàn)服務發(fā)現(xiàn)欺抗,數(shù)據(jù)拓撲的感知,以及Coordinator的選主强重。

Metadata Storage

Metadata storage(Mysql) 主要用來存儲 Segment和配置的元數(shù)據(jù)佩迟。當有新Segment生成時,就會將Segment的元信息寫入metadata store, Coordinator 節(jié)點會監(jiān)控Metadata store 從而知道何時load新Segment竿屹,何時drop舊Segment。注意灸姊,查詢時不會涉及Metadata store拱燃。

Deep Storage

Deep storage (S3 and HDFS)是作為Segment的永久備份,查詢時同樣不會涉及Deep storage力惯。

Column

Druid中的列主要分為3類:時間列碗誉,維度列,指標列父晶。Druid在數(shù)據(jù)攝入和查詢時都依賴時間列哮缺,這也是合理的,因為多維分析一般都帶有時間維度甲喝。維度和指標是OLAP系統(tǒng)中常見的概念尝苇,維度主要是事件的屬性,在查詢時一般用來filtering 和 group by埠胖,指標是用來聚合和計算的糠溜,一般是數(shù)值類型,像count,sum直撤,min非竿,max等。

Druid中的維度列支持String谋竖,Long红柱,F(xiàn)loat,不過只有String類型支持倒排索引蓖乘;指標列支持Long锤悄,F(xiàn)loat,Complex嘉抒, 其中Complex指標包含HyperUnique铁蹈,Cardinality,Histogram,Sketch等復雜指標握牧。強類型的好處是可以更好的對每1列進行編碼和壓縮容诬, 也可以保證數(shù)據(jù)索引的高效性和查詢性能。

Segment

前面提到過沿腰,Druid中會按時間段生成不可變的帶倒排索引的列式文件览徒,這個文件就稱之為Segment,Segment是Druid中數(shù)據(jù)存儲颂龙、復制习蓬、均衡、以及計算的基本單元措嵌, Segment由dataSource_beginTime_endTime_version_shardNumber唯一標識躲叼,1個segment一般包含5–10 million行記錄,大小一般在300~700mb企巢。

Segment的存儲格式

Druid segment的存儲格式如上圖所示枫慷,包含3部分:

version文件

meta 文件

數(shù)據(jù)文件

其中meta文件主要包含每1列的文件名和文件的偏移量。(注浪规,druid為了減少文件描述符或听,將1個segment的所有列都合并到1個大的smoosh中,由于druid訪問segment文件的時候采用MMap的方式笋婿,所以單個smoosh文件的大小不能超過2G誉裆,如果超過2G,就會寫到下一個smoosh文件)缸濒。

在smoosh文件中足丢,數(shù)據(jù)是按列存儲中,包含時間列庇配,維度列和指標列霎桅,其中每1列會包含2部分:ColumnDescriptor和binary數(shù)據(jù)。其中ColumnDescriptor主要保存每1列的數(shù)據(jù)類型和Serde的方式讨永。

smoosh文件中還有index.drd文件和metadata.drd文件滔驶,其中index.drd主要包含該segment有哪些列,哪些維度卿闹,該Segment的時間范圍以及使用哪種bitmap揭糕;metadata.drd主要包含是否需要聚合,指標的聚合函數(shù)锻霎,查詢粒度著角,時間戳字段的配置等。

指標列的存儲格式

我們先來看指標列的存儲格式:

指標列的存儲格式如上圖所示:

version

value個數(shù)

每個block的value的個數(shù)(druid對Long和Float類型會按block進行壓縮旋恼,block的大小是64K)

壓縮類型 (druid目前主要有LZ4和LZF倆種壓縮算法)

編碼類型 (druid對Long類型支持差分編碼和Table編碼兩種方式吏口,Table編碼就是將long值映射到int,當指標列的基數(shù)小于256時,druid會選擇Table編碼产徊,否則會選擇差分編碼)

編碼的header (以差分編碼為例昂勒,header中會記錄版本號,base value舟铜,每個value用幾個bit表示)

每個block的header (主要記錄版本號戈盈,是否允許反向查找,value的數(shù)量谆刨,列名長度和列名)

每1列具體的值

Long型指標

Druid中對Long型指標會先進行編碼塘娶,然后按block進行壓縮。編碼算法包含差分編碼和table編碼痊夭,壓縮算法包含LZ4和LZF刁岸。

Float型指標

Druid對于Float類型的指標不會進行編碼,只會按block進行壓縮她我。

Complex型指標

Druid對于HyperUnique虹曙,Cardinality,Histogram鸦难,Sketch等復雜指標不會進行編碼和壓縮處理,每種復雜指標的Serde方式由每種指標自己的ComplexMetricSerde實現(xiàn)類實現(xiàn)员淫。

String 維度的存儲格式

String維度的存儲格式如上圖所示合蔽,前面提到過,時間列介返,維度列拴事,指標列由兩部分組成:ColumnDescriptor和binary數(shù)據(jù)。 String維度的binary數(shù)據(jù)主要由3部分組成:dict圣蝎,字典編碼后的id數(shù)組刃宵,用于倒排索引的bitmap。

以上圖中的D2維度列為例徘公,總共有4行牲证,前3行的值是meituan,第4行的值是dianing关面。Druid中dict的實現(xiàn)十分簡單坦袍,就是一個hashmap。圖中dict的內容就是將meituan編碼為0等太,dianping編碼為1捂齐。 Id數(shù)組的內容就是用編碼后的ID替換掉原始值,所以就是[1,1,1,0]缩抡。第3部分的倒排索引就是用bitmap表示某個值是否出現(xiàn)在某行中奠宜,如果出現(xiàn)了,bitmap對應的位置就會置為1,如圖:meituan在前3行中都有出現(xiàn)压真,所以倒排索引1:[1,1,1,0]就表示meituan在前3行中出現(xiàn)娩嚼。

顯然,倒排索引的大小是列的基數(shù)*總的行數(shù)榴都,如果沒有處理的話結果必然會很大待锈。不過好在如果維度列如果基數(shù)很高的話,bitmap就會比較稀疏嘴高,而稀疏的bitmap可以進行高效的壓縮竿音。

Segment生成過程

Add Row to Map

Begin persist to disk

Write version file

Merge and write dimension dict

Write time column

Write metric column

Write dimension column

Write index.drd

Merge and write bitmaps

Write metadata.drd

Segment load過程

Read version

Load segment to MappedByteBuffer

Get column offset from meta

Deserialize each column from ByteBuffer

Segment Query過程

Druid查詢的最小單位是Segment,Segment在查詢之前必須先load到內存拴驮,load過程如上一步所述春瞬。如果沒有索引的話,我們的查詢過程就只能Scan的套啤,遇到符合條件的行選擇出來宽气,但是所有查詢都進行全表Scan肯定是不可行的,所以我們需要索引來快速過濾不需要的行潜沦。Druid的Segmenet查詢過程如下:

構造1個Cursor進行迭代

查詢之前構造出Fliter

根據(jù)Index匹配Fliter萄涯,得到滿足條件的Row的Offset

根據(jù)每列的ColumnSelector去指定Row讀取需要的列。

Druid的編碼和壓縮

前面已經(jīng)提到了唆鸡,Druid對Long型的指標進行了差分編碼和Table編碼涝影,Long型和Float型的指標進行了LZ4或者LZF壓縮。

其實編碼和壓縮本質上是一個東西争占,一切熵增的編碼都是壓縮燃逻。 在計算機領域,我們一般把針對特定類型的編碼稱之為編碼臂痕,針對任意類型的通用編碼稱之為壓縮伯襟。

編碼和壓縮的本質就是讓每一個bit盡可能帶有更多的信息。

總結

本文主要分享了Druid Storage的眼里握童,既然Druid Storage專門為了OLAP場景設計姆怪,我們在Kylin中是不是可以用Druid Storage 替換掉HBase呢? 下一篇我將分享《Apache Kylin on Druid Storage 原理和實踐》



原文鏈接:

https://blog.bcmeng.com/post/druid-storage.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末澡绩,一起剝皮案震驚了整個濱河市片效,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌英古,老刑警劉巖淀衣,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異召调,居然都是意外死亡膨桥,警方通過查閱死者的電腦和手機蛮浑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來只嚣,“玉大人沮稚,你說我怎么就攤上這事〔嵛瑁” “怎么了蕴掏?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長调鲸。 經(jīng)常有香客問我盛杰,道長,這世上最難降的妖魔是什么藐石? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任即供,我火速辦了婚禮,結果婚禮上于微,老公的妹妹穿的比我還像新娘逗嫡。我一直安慰自己,他們只是感情好株依,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布驱证。 她就那樣靜靜地躺著,像睡著了一般恋腕。 火紅的嫁衣襯著肌膚如雪抹锄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天吗坚,我揣著相機與錄音祈远,去河邊找鬼呆万。 笑死商源,一個胖子當著我的面吹牛,可吹牛的內容都是我干的谋减。 我是一名探鬼主播牡彻,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼出爹!你這毒婦竟也來了庄吼?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤严就,失蹤者是張志新(化名)和其女友劉穎总寻,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梢为,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡渐行,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年轰坊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祟印。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡肴沫,死狀恐怖,靈堂內的尸體忽然破棺而出蕴忆,到底是詐尸還是另有隱情颤芬,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布套鹅,位于F島的核電站站蝠,受9級特大地震影響,放射性物質發(fā)生泄漏芋哭。R本人自食惡果不足惜沉衣,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望减牺。 院中可真熱鬧豌习,春花似錦、人聲如沸拔疚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稚失。三九已至栋艳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間句各,已是汗流浹背吸占。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凿宾,地道東北人矾屯。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像初厚,于是被迫代替她去往敵國和親件蚕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內容

  • 我們知道Druid能夠同時提供對大數(shù)據(jù)集的實時攝入和高效復雜查詢的性能产禾,主要原因就是它獨到的架構設計和基于Data...
    allin8116閱讀 478評論 0 2
  • 我們知道Druid能夠同時提供對大數(shù)據(jù)集的實時攝入和高效復雜查詢的性能排作,主要原因就是它獨到的架構設計和基于Data...
    零度沸騰_yjz閱讀 21,508評論 3 17
  • Druid.io(以下簡稱Druid)是面向海量數(shù)據(jù)的、用于實時查詢與分析的OLAP存儲系統(tǒng)亚情。Druid的四大關鍵...
    大詩兄_zl閱讀 6,449評論 0 9
  • Druid io總體設計 1.Druid模塊架構 1.1 Druid簡介 最新版本的Druid采用了位圖索引妄痪、字典...
    小武大講堂閱讀 1,820評論 0 2
  • 概覽 事件流的分析 druid 提供了快速的分析查詢一個高并發(fā),在實時節(jié)點和歷史節(jié)點上楞件;強大的用戶交互界面衫生; 重構...
    93張先生閱讀 4,095評論 1 1