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


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

Druid vs 其他系統

Druid vs Impala/Shark

Druid和Impala、Shark 的比較基本上可以歸結為需要設計什么樣的系統

Druid被設計用於:

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

查詢速度不同:

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

數據的獲取不同:

  • Druid可以獲取實時數據。
  • Impala/Shark是基於HDFS或者其他后備存儲,限制了數據獲取的速度。

查詢的形式不同:

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

Druid vs Elasticsearch

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

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能接受的數據的格式相對簡單,比如不能處理嵌套結構的數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM