Druid(準)實時分析統計數據庫——列存儲+高效壓縮

Druid是一個開源的、分佈式的、列存儲系統,特別適用於大數據上的(準)實時分析統計。且具備較好的穩定性(Highly Available)。 其相對比較輕量級,文檔很是完善,也比較容易上手。

Druid vs 其餘系統

Druid vs Impala/Shark

Druid和Impala、Shark 的比較基本上能夠歸結爲須要設計什麼樣的系統html

Druid被設計用於:node

  1. 一直在線的服務
  2. 獲取實時數據
  3. 處理slice-n-dice式的即時查詢

查詢速度不一樣:mysql

  • Druid是列存儲方式,數據通過壓縮加入到索引結構中,壓縮增長了RAM中的數據存儲能力,可以使RAM適應更多的數據快速存取。索引結構意味着,當添加過濾器來查詢,Druid少作一些處理,將會查詢的更快。
  • Impala/Shark能夠認爲是HDFS之上的後臺程序緩存層。 可是他們沒有超越緩存功能,真正的提升查詢速度。

數據的獲取不一樣:算法

  • Druid能夠獲取實時數據。
  • Impala/Shark是基於HDFS或者其餘後備存儲,限制了數據獲取的速度。

查詢的形式不一樣:sql

  • Druid支持時間序列和groupby樣式的查詢,但不支持join。
  • Impala/Shark支持SQL樣式的查詢。

Druid vs Elasticsearch

Elasticsearch(ES) 是基於Apache Lucene的搜索服務器。它提供了全文搜索的模式,並提供了訪問原始事件級數據。 Elasticsearch還提供了分析和彙總支持。根據研究,ES在數據獲取和彙集用的資源比在Druid高。json

Druid側重於OLAP工做流程。Druid是高性能(快速彙集和獲取)以較低的成本進行了優化,並支持普遍的分析操做。Druid提供告終構化的事件數據的一些基本的搜索支持。緩存

 

Segment: Druid中有個重要的數據單位叫segment,其是Druid經過bitmap indexing從raw data生成的(batch or realtime)。segment保證了查詢的速度。能夠本身設置每一個segment對應的數據粒度,這個應用中廣告流量查詢的最小粒度是天,因此天天的數據會被建立成一個segment。注意segment是不可修改的,若是須要修改,只可以修改raw data,從新建立segment了。服務器

架構

Druid自己包含5個組成部分:Broker nodes, Historical nodes, Realtime nodes, Coordinator Nodes和indexing services. 分別的做用以下:架構

  • Broker nodes: 負責響應外部的查詢請求,經過查詢Zookeeper將請求劃分紅segments分別轉發給Historical和Real-time nodes,最終合併並返回查詢結果給外部;
  • Historial nodes: 負責’Historical’ segments的存儲和查詢。其會從deep storage中load segments,並響應Broder nodes的請求。Historical nodes一般會在本機同步deep storage上的部分segments,因此即便deep storage不可訪問了,Historical nodes仍是能serve其同步的segments的查詢;
  • Real-time nodes: 用於存儲和查詢熱數據,會按期地將數據build成segments移到Historical nodes。通常會使用外部依賴kafka來提升realtime data ingestion的可用性。若是不須要實時ingest數據到cluter中,能夠捨棄Real-time nodes,只定時地batch ingestion數據到deep storage;
  • Coordinator nodes: 能夠認爲是Druid中的master,其經過Zookeeper管理Historical和Real-time nodes,且經過Mysql中的metadata管理Segments
  • Druid中一般還會起一些indexing services用於數據導入,batch data和streaming data均可以經過給indexing services發請求來導入數據。

Druid還包含3個外部依賴分佈式

  • Mysql:存儲Druid中的各類metadata(裏面的數據都是Druid自身建立和插入的),包含3張表:」druid_config」(一般是空的), 「druid_rules」(coordinator nodes使用的一些規則信息,好比哪一個segment從哪一個node去load)和「druid_segments」(存儲每一個segment的metadata信息);
  • Deep storage: 存儲segments,Druid目前已經支持本地磁盤,NFS掛載磁盤,HDFS,S3等。Deep Storage的數據有2個來源,一個是batch Ingestion, 另外一個是real-time nodes;
  • ZooKeeper: 被Druid用於管理當前cluster的狀態,好比記錄哪些segments從Real-time nodes移到了Historical nodes;

查詢

Druid的查詢是經過給Broker Nodes發送HTTP POST請求(也能夠直接給Historical or Realtime Node),具體可見Druid官方文檔。查詢條件的描述是json文件,查詢的response也是json格式。Druid的查詢包含以下4種:

  • Time Boundary Queries: 用於查詢所有數據的時間跨度
  • groupBy Queries: 是Druid的最典型查詢方式,很是相似於Mysql的groupBy查詢。query body中幾個元素能夠這麼理解:
    • 「aggregation」: 對應mysql」select XX from」部分,即你想查哪些列的聚合結果;
    • 「dimensions」: 對應mysql」group by XX」,即你想基於哪些列作聚合;
    • 「filter」: 對應mysql」where XX」條件,即過濾條件;
    • 「granularity」: 數據聚合的粒度;
  • Timeseries queries: 其統計知足filter條件的」rows」上某幾列的聚合結果,相比」groupBy Queries」不指定基於哪幾列進行聚合,效率更高;
  • TopN queries: 用於查詢某一列上按照某種metric排序的最多見的N個values;

本文小結

  1. Druid是一個開源的,分佈式的,列存儲的,適用於實時數據分析的系統,文檔詳細,易於上手;
    • Druid在設計時充分考慮到了Highly Available,各類nodes掛掉都不會使得druid中止工做(可是狀態會沒法更新);
    • Druid中的各個components之間耦合性低,若是不須要streaming data ingestion徹底能夠忽略realtime node;
    • Druid的數據單位Segment是不可修改的,咱們的作法是生成新的segments替換現有的;
    • Druid使用Bitmap indexing加速column-store的查詢速度,使用了一個叫作CONCISE的算法來對bitmap indexing進行壓縮,使得生成的segments比原始文本文件小不少;
  2. 在咱們的應用場景下(一共10幾臺機器,數據大概100列,行數是億級別),平均查詢時間<2秒,是一樣機器數目的Mysql cluter的1/100 ~ 1/10;
  3. Druid的一些「侷限」:
    • Segment的不可修改性簡化了Druid的實現,可是若是你有修改數據的需求,必須從新建立segment,而bitmap indexing的過程是比較耗時的;
    • Druid能接受的數據的格式相對簡單,好比不能處理嵌套結構的數據
相關文章
相關標籤/搜索