Druid高效架構(gòu)

我們知道Druid能夠同時提供對大數(shù)據(jù)集的實時攝入和高效復(fù)雜查詢的性能步势,主要原因就是它獨到的架構(gòu)設(shè)計和基于Datasource與Segment的數(shù)據(jù)存儲結(jié)構(gòu)。接下來我們會分別從數(shù)據(jù)存儲和系統(tǒng)節(jié)點架構(gòu)兩方面來深入了解一下Druid的架構(gòu)妈嘹。

數(shù)據(jù)存儲

Druid將數(shù)據(jù)組織成Read-Optimized的結(jié)構(gòu)柳琢,而這也是Druid能夠支持交互式查詢的關(guān)鍵。Druid中的數(shù)據(jù)存儲在被稱為datasource中润脸,類似RDMS中的table柬脸。每個datasource按照時間劃分,如果你有需求也可以進(jìn)一步按其它屬性劃分毙驯。每個時間范圍稱為一個chunk(比如你按天分區(qū)倒堕,則一個chunk為一天)。在chunk中數(shù)據(jù)由被分為一個或多個segment(segment是數(shù)據(jù)實際存儲結(jié)構(gòu)爆价,Datasource垦巴、Chunk只是一個邏輯概念),每個segment都是一個單獨的文件铭段,通常包含幾百萬行數(shù)據(jù)骤宣,這些segment是按照時間組織成的chunk,所以在按照時間查詢數(shù)據(jù)時序愚,效率非常高憔披。

Datasource

數(shù)據(jù)分區(qū)

任何分布式存儲/計算系統(tǒng),都需要對數(shù)據(jù)進(jìn)行合理的分區(qū),從而實現(xiàn)存儲和計算的均衡芬膝,以及數(shù)據(jù)并行化望门。而Druid本身處理的是事件數(shù)據(jù),每條數(shù)據(jù)都會帶有一個時間戳蔗候,所以很自然的就可以使用時間進(jìn)行分區(qū)怒允。比如上圖埂软,我們指定了分區(qū)粒度為為天锈遥,那么每天的數(shù)據(jù)都會被單獨存儲和查詢(一個分區(qū)下有多個Segment的原因往下看)。
使用時間分區(qū)我們很容易會想到一個問題勘畔,就是很可能每個時間段的數(shù)據(jù)量是不均衡的(想一想我們的業(yè)務(wù)場景)所灸,而Duid為了解決這種問題,提供了“二級分區(qū)”炫七,每一個二級分區(qū)稱為一個Shard(這才是物理分區(qū))爬立。通過設(shè)置每個Shard的所能存儲的目標(biāo)值和Shard策略浑劳,來完成shard的分區(qū)塘慕。Druid目前支持兩種Shard策略:Hash(基于維值的Hash)和Range(基于某個維度的取值范圍)蒋院。上圖中坊夫,2000-01-01和2000-01-03的每個分區(qū)都是一個Shard鼎姊,由于2000-01-02的數(shù)據(jù)量比較多化漆,所以有兩個Shard棠绘。

Segment

Shard經(jīng)過持久化之后就稱為了Segment苟翻,Segment是數(shù)據(jù)存儲的止、復(fù)制檩坚、均衡(Historical的負(fù)載均衡)和計算的基本單元了。Segment具有不可變性诅福,一個Segment一旦創(chuàng)建完成后(MiddleManager節(jié)點發(fā)布后)就無法被修改匾委,只能通過生成一個新的Segment來代替舊版本的Segment。

Segment內(nèi)部存儲結(jié)構(gòu)

接下來我們可以看下Segment文件的內(nèi)部存儲結(jié)構(gòu)氓润。因為Druid采用列式存儲赂乐,所以每列數(shù)據(jù)都是在獨立的結(jié)構(gòu)中存儲(并不是獨立的文件,是獨立的數(shù)據(jù)結(jié)構(gòu)咖气,因為所有列都會存儲在一個文件中)挨措。Segment中的數(shù)據(jù)類型主要分為三種:時間戳、維度列和指標(biāo)列采章。


Segment數(shù)據(jù)列

對于時間戳列和指標(biāo)列运嗜,實際存儲是一個數(shù)組,Druid采用LZ4壓縮每列的整數(shù)或浮點數(shù)悯舟。當(dāng)收到查詢請求后担租,會拉出所需的行數(shù)據(jù)(對于不需要的列不會拉出來),并且對其進(jìn)行解壓縮抵怎。解壓縮完之后奋救,在應(yīng)用具體的聚合函數(shù)岭参。
對于維度列不會像指標(biāo)列和時間戳這么簡單,因為它需要支持filter和group by尝艘,所以Druid使用了字典編碼(Dictionary Encoding)和位圖索引(Bitmap Index)來存儲每個維度列演侯。每個維度列需要三個數(shù)據(jù)結(jié)構(gòu):

  1. 需要一個字典數(shù)據(jù)結(jié)構(gòu),將維值(維度列值都會被認(rèn)為是字符串類型)映射成一個整數(shù)ID背亥。
  2. 使用上面的字典編碼秒际,將該列所有維值放在一個列表中。
  3. 對于列中不同的值狡汉,使用bitmap數(shù)據(jù)結(jié)構(gòu)標(biāo)識哪些行包含這些值娄徊。

Druid針對維度列之所以使用這三個數(shù)據(jù)結(jié)構(gòu),是因為:

  1. 使用字典將字符串映射成整數(shù)ID盾戴,可以緊湊的表示結(jié)構(gòu)2和結(jié)構(gòu)3中的值寄锐。
  2. 使用Bitmap位圖索引可以執(zhí)行快速過濾操作(找到符合條件的行號,以減少讀取的數(shù)據(jù)量)尖啡,因為Bitmap可以快速執(zhí)行AND和OR操作橄仆。
  3. 對于group by和TopN操作需要使用結(jié)構(gòu)2中的列值列表。

我們以上面"Page"維度列為例衅斩,可以具體看下Druid是如何使用這三種數(shù)據(jù)結(jié)構(gòu)存儲維度列:

1. 使用字典將列值映射為整數(shù)
{
"Justin Bieher":0,
"ke$ha":1
}
2. 使用1中的編碼盆顾,將列值放到一個列表中
[0,0,1,1]
3. 使用bitmap來標(biāo)識不同列值
value = 0: [1,1,0,0] //1代表該行含有該值,0標(biāo)識不含有
value = 1: [0,0,1,1]

下圖是以advertiser列為例矛渴,描述了advertiser列的實際存儲結(jié)構(gòu):


advertiser列值存儲

前兩種存儲結(jié)構(gòu)在最壞情況下會根據(jù)數(shù)據(jù)量增長而成線性增長(列數(shù)據(jù)中的每行都不相同)椎扬,而第三種由于使用Bitmap存儲(本身是一個稀疏矩陣),所以對它進(jìn)行壓縮具温,可以得到非巢系樱客觀的壓縮比。Druid而且運用了Roaring Bitmap(http://roaringbitmap.org/)能夠?qū)嚎s后的位圖直接進(jìn)行布爾運算铣猩,可以大大提高查詢效率和存儲效率(不需要解壓縮)揖铜。

Segment命名

高效的數(shù)據(jù)查詢,不僅僅體現(xiàn)在文件內(nèi)容的存儲結(jié)構(gòu)上达皿,還有一點很重要天吓,就是文件的命名上。試想一下峦椰,如果一個Datasource下有幾百萬個Segment文件龄寞,我們又如何快速找出我們所需要的文件呢?答案就是通過文件名稱快速索引查找汤功。
Segment的命名包含四部分:數(shù)據(jù)源(Datasource)物邑、時間間隔(包含開始時間和結(jié)束時間兩部分)、版本號和分區(qū)(Segment有分片的情況下才會有)。

test-datasource_2018-05-21T16:00:00.000Z_2018-05-21T17:00:00.000Z_2018-05-21T16:00:00.000Z_1
數(shù)據(jù)源名稱_開始時間_結(jié)束時間_版本號_分區(qū)

分片號是從0開始色解,如果分區(qū)號為0茂嗓,則可以省略:test-datasource_2018-05-21T16:00:00.000Z_2018-05-21T17:00:00.000Z_2018-05-21T16:00:00.000Z
還需要注意如果一個時間間隔segment由多個分片組成,則在查詢該segment的時候科阎,需要等到所有分片都被加載完成后述吸,才能夠查詢(除非使用線性分片規(guī)范(linear shard spec),允許在未加載完成時查詢)锣笨。

字段 是否必須 描述
datasource segment所在的Datasource
開始時間 該Segment所存儲最早的數(shù)據(jù)蝌矛,時間格式是ISO 8601。開始時間和結(jié)束時間是通過segmentGranularity設(shè)置的時間間隔
結(jié)束時間 該segment所存儲最晚的數(shù)據(jù)票唆,時間格式是ISO 8601
版本號 因為Druid支持批量覆蓋操作朴读,當(dāng)批量攝入與之前相同數(shù)據(jù)源屹徘、相同時間間隔數(shù)據(jù)時走趋,數(shù)據(jù)就會被覆蓋,這時候版本號就會被更新噪伊。Druid系統(tǒng)的其它部分感知到這個信號后簿煌,就會把就舊數(shù)據(jù)刪除,使用新版本的數(shù)據(jù)(這個切換很快)鉴吹。版本號也是是用的ISO 8601時間戳姨伟,但是這個時間戳代表首次啟動的時間
分區(qū)號 segment如果采用分區(qū),才會有該標(biāo)識

Segment物理存儲實例

下面我們以一個實例來看下Segment到底以什么形式存儲的豆励,我們以本地導(dǎo)入方式將下面數(shù)據(jù)導(dǎo)入到Druid中夺荒。

{"time": "2018-11-01T00:47:29.913Z","city": "beijing","sex": "man","gmv": 20000}
{"time": "2018-11-01T00:47:33.004Z","city": "beijing","sex": "woman","gmv": 50000}
{"time": "2018-11-01T00:50:33.004Z","city": "shanghai","sex": "man","gmv": 10000}

我們以單機形式運行Druid,這樣Druid生成的Segment文件都在${DRUID_HOME}/var/druid/segments 目錄下良蒸。

Segment目錄

segment通過datasource_beginTime_endTime_version_shard用于唯一標(biāo)識技扼,在實際存儲中是以目錄的形式表現(xiàn)的。

Segment目錄

可以看到Segment中包含了Segment描述文件(descriptor.json)和壓縮后的索引數(shù)據(jù)文件(index.zip)嫩痰,我們主要看的也是index.zip這個文件剿吻,對其進(jìn)行解壓縮。


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

首先看下factory.json這個文件串纺,這個文件并不是segment具體存儲段數(shù)據(jù)的文件丽旅。因為Druid通過使用MMap(一種內(nèi)存映射文件的方式)的方式訪問Segment文件,通過查看這個文件內(nèi)容來看纺棺,貌似是用于MMap讀取文件所使用的(不太了解MMap)?

#factory.json文件內(nèi)容
{"type":"mMapSegmentFactory"}

Druid實際存儲Segment數(shù)據(jù)文件是:version.bin榄笙、meta.smoosh和xxxxx.smoosh這三個文件,下面分別看下這三個文件的內(nèi)容祷蝌。
version.bin是一個存儲了4個字節(jié)的二進(jìn)制文件茅撞,它是Segment內(nèi)部版本號(隨著Druid發(fā)展,Segment的格式也在發(fā)展),目前是V9乡翅,以Sublime打開該文件可以看到:

0000 0009 

meta.smoosh里面存儲了關(guān)于其它smoosh文件(xxxxx.smoosh)的元數(shù)據(jù)鳞疲,里面記錄了每一列對應(yīng)文件和在文件的偏移量。除了列信息外蠕蚜,smoosh文件還包含了index.drd和metadata.drd尚洽,這部分是關(guān)于Segment的一些額外元數(shù)據(jù)信息。

#版本號,該文件所能存儲的最大值(2G),smooth文件數(shù)
v1,2147483647,1
# 列名,文件名,起始偏移量,結(jié)束偏移量
__time,0,0,154
city,0,306,577
gmv,0,154,306
index.drd,0,841,956
metadata.drd,0,956,1175
sex,0,577,841

再看00000.smoosh文件前靶累,我們先想一下為什么這個文件被命名為這種樣式腺毫?因為Druid為了最小化減少打開文件的句柄數(shù),它會將一個Segment的所有列數(shù)據(jù)都存儲在一個smoosh文件中挣柬,也就是xxxxx.smoosh這個文件潮酒。但是由于Druid使用MMap來讀取Segment文件,而MMap需要保證每個文件大小不能超過2G(Java中的MMapByteBuffer限制)邪蛔,所以當(dāng)一個smoosh文件大于2G時急黎,Druid會將新數(shù)據(jù)寫入到下一個smoosh文件中。這也就是為什么這些文件命名是這樣的侧到,這里也對應(yīng)上了meta文件中為什么還要標(biāo)識列所在的文件名勃教。
通過meta.smoosh的偏移量也能看出,00000.smoosh文件中數(shù)據(jù)是按列進(jìn)行存儲的匠抗,從上到下分別存儲的是時間列故源、指標(biāo)列、維度列汞贸。對于每列主要包會含兩部分信息:ColumnDescriptor和binary數(shù)據(jù)绳军。columnDescriptor是一個使用Jackson序列化的對象,它包含了該列的一些元數(shù)據(jù)信息矢腻,比如數(shù)據(jù)類型门驾、是否是多值等。而binary則是根據(jù)不同數(shù)據(jù)類型進(jìn)行壓縮存儲的二進(jìn)制數(shù)據(jù)踏堡。

^@^@^@d{"valueType":"LONG","hasMultipleValues":false,"parts":[{"type":"long","byteOrder":"LITTLE_ENDIAN"}]}^B^@^@^@^C^@^@ ^@^A^A^@^@^@^@"^@^@^@^A^@^@^@^Z^@^@^@^@¢yL?ìf^A^@^@<8c>X^H^@<80>?^Wàìf^A^@^@^@^@^@d{"valueType":"LONG","hasMultipleValues":false,"parts":[{"type":"long","byteOrder":"LITTLE_ENDIAN"}]}^B^@^@^@^C^@^@ ^@^A^A^@^@^@^@ ^@^@^@^A^@^@^@^X^@^@^@^@1 N^@^A^@"P?^H^@<80>^P'^@^@^@^@^@^@^@^@^@<9a>{"valueType":"STRING","hasMultipleValues":false,"parts":[{"type":"stringDictionary","bitmapSerdeFactory":{"type":"concise"},"byteOrder":"LITTLE_ENDIAN"}]}^B^@^@^@^@^A^A^@^@^@#^@^@^@^B^@^@^@^K^@^@^@^W^@^@^@^@beijing^@^@^@^@shanghai^B^A^@^@^@^C^@^A^@^@^A^A^@^@^@^@^P^@^@^@^A^@^@^@^H^@^@^@^@0^@^@^A^A^@^@^@^@^\^@^@^@^B^@^@^@^H^@^@^@^P^@^@^@^@<80>^@^@^C^@^@^@^@<80>^@^@^D^@^@^@<9a>{"valueType":"STRING","hasMultipleValues":false,"parts":[{"type":"stringDictionary","bitmapSerdeFactory":{"type":"concise"},"byteOrder":"LITTLE_ENDIAN"}]}^B^@^@^@^@^A^A^@^@^@^\^@^@^@^B^@^@^@^G^@^@^@^P^@^@^@^@man^@^@^@^@woman^B^A^@^@^@^C^@^A^@^@^A^A^@^@^@^@^P^@^@^@^A^@^@^@^H^@^@^@^@0^@^A^@^A^@^@^@^@^\^@^@^@^B^@^@^@^H^@^@^@^P^@^@^@^@<80>^@^@^E^@^@^@^@<80>^@^@^B^A^@^@^@^@&^@^@^@^C^@^@^@^G^@^@^@^O^@^@^@^V^@^@^@^@gmv^@^@^@^@city^@^@^@^@sex^A^A^@^@^@^[^@^@^@^B^@^@^@^H^@^@^@^O^@^@^@^@city^@^@^@^@sex^@^@^Afì<91>D^@^@^@^Af??,^@^@^@^@^R{"type":"concise"}{"container":{},"aggregators":[{"type":"longSum","name":"gmv","fieldName":"gmv","expression":null}],"timestampSpec":{"column":"time","format":"auto","missingValue":null},"queryGranularity":{"type":"none"},"rollup":true}

smooth文件中的binary數(shù)據(jù)經(jīng)過LZ4或Bitmap壓縮猎唁,所以無法看到數(shù)據(jù)原始內(nèi)容。

在smooth文件最后還包含了兩部分?jǐn)?shù)據(jù)顷蟆,分別是index.drd和metadata.drd诫隅。其中index.drd中包含了Segment中包含哪些度量、維度帐偎、時間范圍逐纬、以及使用哪種bitmap。metadata.drd中存儲了指標(biāo)聚合函數(shù)削樊、查詢粒度豁生、時間戳配置等(上面內(nèi)容的最后部分)兔毒。
下圖是物理存儲結(jié)構(gòu)圖,存儲未壓縮和編碼的數(shù)據(jù)就是最右邊的內(nèi)容甸箱。

Segment物理存儲

Segment創(chuàng)建

Segment都是在MiddleManager節(jié)點中創(chuàng)建的育叁,并且處在MiddleManager中的Segment在狀態(tài)上都是可變的并且未提交的(提交到DeepStorage之后,數(shù)據(jù)就不可改變)芍殖。
Segment從在MiddleManager中創(chuàng)建到傳播到Historical中豪嗽,會經(jīng)歷以下幾個步驟:

  1. MiddleManager中創(chuàng)建Segment文件,并將其發(fā)布到Deep Storage豌骏。
  2. Segment相關(guān)的元數(shù)據(jù)信息被存儲到MetaStore中龟梦。
  3. Coordinator進(jìn)程根據(jù)MetaStore中得知Segment相關(guān)的元數(shù)據(jù)信息后,根據(jù)規(guī)則的設(shè)置分配給復(fù)合條件的Historical節(jié)點窃躲。
  4. Historical節(jié)點得到Coordinator指令后计贰,自動從DeepStorage中拉取Segment數(shù)據(jù)文件,并通過Zookeeper向集群聲明負(fù)責(zé)提供該Segment數(shù)據(jù)相關(guān)的查詢服務(wù)蒂窒。
  5. MiddleManager在得知Historical負(fù)責(zé)該Segment后躁倒,會丟棄該Segment文件,并向集群聲明不在負(fù)責(zé)該Segment相關(guān)的查詢刘绣。

如何配置分區(qū)

可以通過granularitySpec中的segmentGranularity設(shè)置segment的時間間隔(http://druid.io/docs/latest/ingestion/ingestion-spec.html#granularityspec)樱溉。為了保證Druid的查詢效率,每個Segment文件的大小建議在300MB~700MB之間纬凤。如果超過這個范圍,可以修改時間間隔或者使用分區(qū)來進(jìn)行優(yōu)化(配置partitioningSpec中的targetPartitionSize撩嚼,官方建議設(shè)置500萬行以上停士;http://druid.io/docs/latest/ingestion/hadoop.html#partitioning-specification)。

系統(tǒng)架構(gòu)詳解

我們知道Druid節(jié)點類型有五種:Overload完丽、MiddleManager恋技、Coordinator、Historical和Broker逻族。


Druid架構(gòu)

Overload和MiddleManager主要負(fù)責(zé)數(shù)據(jù)攝入(對于沒有發(fā)布的Segment蜻底,MiddleManager也提供查詢服務(wù));Coordinator和Historical主要負(fù)責(zé)歷史數(shù)據(jù)的查詢聘鳞;Broker節(jié)點主要負(fù)責(zé)接收Client查詢請求薄辅,拆分子查詢給MiddleManager和Historical節(jié)點,然后合并查詢結(jié)果返回給Client抠璃。其中Overload是MiddleManager的master節(jié)點站楚,Coordinator是Historical的master節(jié)點。

索引服務(wù)

Druid提供一組支持索引服務(wù)(Indexing Service)的組件搏嗡,也就是Overload和MiddleManager節(jié)點窿春。索引服務(wù)是一種高可用的分布式服務(wù)拉一,用于運行跟索引相關(guān)的任務(wù),索引服務(wù)是數(shù)據(jù)攝入創(chuàng)建和銷毀Segment的主要方式(還有一種是采用實時節(jié)點的方式旧乞,但是現(xiàn)在已經(jīng)廢棄了)蔚润。索引服務(wù)支持以pull或push的方式攝入外部數(shù)據(jù)。
索引服務(wù)采用的是主從架構(gòu)尺栖,Overload為主節(jié)點抽碌,MiddleManager是從節(jié)點。索引服務(wù)架構(gòu)圖如下圖所示:

索引服務(wù)

索引服務(wù)由三部分組件組成:用于執(zhí)行任務(wù)的Peon(勞工)組件决瞳、用于管理Peon的MiddleManager組件和分配任務(wù)給MiddleManager的Overload組件货徙。MiddleManager和Overload組件可以部署在相同節(jié)點也可以跨節(jié)點部署,但是Peon和MiddleManager是部署在同一個節(jié)點上的皮胡。
索引服務(wù)架構(gòu)和Yarn的架構(gòu)很像:

  • Overlaod節(jié)點相當(dāng)于Yarn的ResourceManager痴颊,負(fù)責(zé)集群資源管理和任務(wù)分配。
  • MiddleManager節(jié)點相當(dāng)于Yarn的NodeManager屡贺,負(fù)責(zé)接受任務(wù)和管理本節(jié)點的資源蠢棱。
  • Peon節(jié)點相當(dāng)于Yarn的Container,執(zhí)行節(jié)點上具體的任務(wù)甩栈。

Overload節(jié)點

Overload作為索引服務(wù)的主節(jié)點泻仙,對外負(fù)責(zé)接受索引任務(wù),對內(nèi)負(fù)責(zé)將任務(wù)分解并下發(fā)給MiddleManager量没。Overload有兩種運行模式:

  • 本地模式(Local Mode):默認(rèn)模式玉转。本地模式下的Overload不僅負(fù)責(zé)任務(wù)協(xié)調(diào)工作,還會負(fù)責(zé)啟動一些peon來完成具體的任務(wù)殴蹄。
  • 遠(yuǎn)程模式(Remote Mode):該模式下究抓,Overload和MiddleManager運行在不同的節(jié)點上,它僅負(fù)責(zé)任務(wù)的協(xié)調(diào)工作袭灯,不負(fù)責(zé)完成具體的任務(wù)刺下。

Overload提供了一個UI客戶端,可以用于查看任務(wù)稽荧、運行任務(wù)和終止任務(wù)等橘茉。

http://<OVERLORD_IP>:<port>/console.html

Overload提供了RESETful的訪問形式,所以客戶端可以通過HTTP POST形式向請求節(jié)點提交任務(wù)姨丈。

http://<OVERLORD_IP>:<port>/druid/indexer/v1/task //提交任務(wù)
http://<OVERLORD_IP>:<port>/druid/indexer/v1/task/{task_id}/shutdown //殺死任務(wù)

MiddleManager節(jié)點

MiddleManager是執(zhí)行任務(wù)的工作節(jié)點畅卓,MiddleManager會將任務(wù)單獨發(fā)給每個單獨JVM運行的Peon(因為要把資源和日志進(jìn)行隔離),每個Peon一次只能運行一個任務(wù)构挤。

Peon節(jié)點

Peon在單個JVM中運行單個任務(wù)髓介,MiddleManager負(fù)責(zé)為任務(wù)創(chuàng)建Peon。

Coordinator節(jié)點

Coordinator是Historical的mater節(jié)點筋现,它主要負(fù)責(zé)管理和分發(fā)Segment唐础。具體工作就是:告知Historical加載或刪除Segment箱歧、管理Segment副本以及負(fù)載Segment在Historical上的均衡。
Coordinator是定期運行的一膨,并且運行間隔可以通過配置參數(shù)配置呀邢。每次Coordinator運行都會通過Zookeeper獲取當(dāng)前集群狀態(tài),通過評估集群狀態(tài)來采取適當(dāng)?shù)牟僮?比如均衡負(fù)載Segment)豹绪。Coordinator會連接數(shù)據(jù)庫(MetaStore)价淌,數(shù)據(jù)庫中存儲了Segment信息和規(guī)則(Rule)。Segment表中列出了需要加載到集群中的所有Segment瞒津,Coordinator每次運行都會從Segment表來拉取Segment列表并與當(dāng)前集群的Segment對比蝉衣,如果發(fā)現(xiàn)數(shù)據(jù)庫中不存在的Segment,但是在集群中還有巷蚪,就會把它從集群刪掉病毡;規(guī)則表定義了如何處理Segment,規(guī)則的作用就是我們可以通過配置一組規(guī)則屁柏,來操作集群加載Segment或刪除Segment啦膜。關(guān)于如何配置規(guī)則,可以查看:http://druid.io/docs/latest/operations/rule-configuration.html淌喻。

Historical節(jié)點加載Segment前僧家,會進(jìn)行容量排序,哪個Historical節(jié)點的Segment最少裸删,則它就具有最高的加載權(quán)八拱。Coordinator不會直接Historical節(jié)點通信,而是將Segment信息放到一個隊列中烁落,Historical節(jié)點去隊列取Segment描述信息乘粒,并且加載該Segment到本節(jié)點。
Coordinator提供了一UI界面伤塌,用于顯示集群信息和規(guī)則配置:

http://<COORDINATOR_IP>:<COORDINATOR_PORT>

Historical節(jié)點

Historical節(jié)點負(fù)責(zé)管理歷史Segment,Historical節(jié)點通過Zookeeper監(jiān)聽指定的路徑來發(fā)現(xiàn)是否有新的Segment需要加載(Coordinator通過分配算法指定具體的Historical)轧铁。
上面通過Coordinator知道每聪,當(dāng)有新的Segment需要加載的時候,Coordinator會將其放到一個隊列中齿风。當(dāng)Historical節(jié)點收到有新的Segment時候药薯,就會檢測本地cache和磁盤,查看是否有該Segment信息救斑。如果沒有Historical節(jié)點會從Zookeeper中拉取該Segment相關(guān)的信息童本,然后進(jìn)行下載。


Historical加載Segment

Broker

Broker節(jié)點是負(fù)責(zé)轉(zhuǎn)發(fā)Client查詢請求的脸候,Broker通過zookeeper能夠知道哪個Segment在哪些節(jié)點上穷娱,Broker會將查詢轉(zhuǎn)發(fā)給相應(yīng)節(jié)點绑蔫。所有節(jié)點返回數(shù)據(jù)后,Broker會將所有節(jié)點的數(shù)據(jù)進(jìn)行合并泵额,然后返回給Client配深。
Broker會有一個LRU(高速緩存失效策略),來緩存每Segment的結(jié)果嫁盲。這個緩存可以是本地緩存篓叶,也可以借助外部緩存系統(tǒng)(比如memcached),第三方緩存可以在所有broker中共享Segment結(jié)果羞秤。當(dāng)Borker接收到查詢請求后缸托,會首先查看本地是否有對應(yīng)的查詢數(shù)據(jù),對于不存在的Segment數(shù)據(jù)瘾蛋,會將請求轉(zhuǎn)發(fā)給Historical節(jié)點俐镐。

broker查詢

Broker不會緩存實時數(shù)據(jù),因為實時數(shù)據(jù)處于不可靠狀態(tài)瘦黑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末京革,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子幸斥,更是在濱河造成了極大的恐慌匹摇,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甲葬,死亡現(xiàn)場離奇詭異廊勃,居然都是意外死亡,警方通過查閱死者的電腦和手機经窖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門坡垫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人画侣,你說我怎么就攤上這事冰悠。” “怎么了配乱?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵溉卓,是天一觀的道長。 經(jīng)常有香客問我搬泥,道長桑寨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任忿檩,我火速辦了婚禮尉尾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘燥透。我一直安慰自己沙咏,他們只是感情好辨图,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著芭碍,像睡著了一般徒役。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窖壕,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天忧勿,我揣著相機與錄音,去河邊找鬼瞻讽。 笑死鸳吸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的速勇。 我是一名探鬼主播晌砾,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烦磁!你這毒婦竟也來了养匈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤都伪,失蹤者是張志新(化名)和其女友劉穎呕乎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陨晶,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡猬仁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了先誉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湿刽。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖褐耳,靈堂內(nèi)的尸體忽然破棺而出诈闺,到底是詐尸還是另有隱情,我是刑警寧澤铃芦,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布买雾,位于F島的核電站,受9級特大地震影響杨帽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嗤军,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一注盈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叙赚,春花似錦老客、人聲如沸僚饭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳍鸵。三九已至,卻和暖如春尉间,著一層夾襖步出監(jiān)牢的瞬間偿乖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工哲嘲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贪薪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓眠副,卻偏偏與公主長得像画切,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子囱怕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 我們知道Druid能夠同時提供對大數(shù)據(jù)集的實時攝入和高效復(fù)雜查詢的性能霍弹,主要原因就是它獨到的架構(gòu)設(shè)計和基于Data...
    allin8116閱讀 478評論 0 2
  • Druid基本概念及架構(gòu)介紹 1.什么是Druid Druid是一個專為大型數(shù)據(jù)集上的高性能切片和OLAP分析而設(shè)...
    it_zzy閱讀 53,034評論 0 32
  • 1、系統(tǒng)架構(gòu) Druid集群是由不同類型的節(jié)點組成的娃弓,每個類型的節(jié)點被設(shè)計用來執(zhí)行一組特定的任務(wù)典格。不同的節(jié)點類型操...
    LZhan閱讀 250評論 0 0
  • 什么是Druid Druid是一個高效的數(shù)據(jù)查詢系統(tǒng),主要解決的是對于大量的基于時序的數(shù)據(jù)進(jìn)行聚合查詢忘闻。數(shù)據(jù)可以實...
    Hanze2111閱讀 55,761評論 5 29
  • 概覽 事件流的分析 druid 提供了快速的分析查詢一個高并發(fā)钝计,在實時節(jié)點和歷史節(jié)點上;強大的用戶交互界面齐佳; 重構(gòu)...
    93張先生閱讀 4,095評論 1 1