雲計算

實時分析性數據庫 Druid 架構解析

Druid 是一個實時分析型的數據庫,用於大規模實時數據導入、快速查詢分析的場景,包括網站訪問點擊流分析、網絡性能監控分析、應用性能指標存儲與分析、供應鏈分析、廣告分析等。

image.png

Druid 的核心集成了數據倉庫、時序數據庫、日誌搜索系統的設計,主要包含如下特性:

  1. 列式存儲:Druid 使用列存方式組織數據,訪問時可按需加載訪問到的列,支持快速的掃描和聚合計算能力;同時數據按列式存儲,能極大的提升數據的壓縮率。
  2. 分佈式可擴展:Druid 集群可擴展至上百臺服務器,可以高併發出力讀寫請求,提供每秒百萬級的數據導入,以及亞秒級的查詢延時。
  3. 支持實時及批量導入:Druid 支持實時或批量方式導入數據,非常方便點支持從 Kafka、Hadoop 等數據源導入數據。
  4. 高可用&負載均衡:Druid 集群支持在線的增加、移除服務節點,集群會進行自動的負載均衡,當有節點故障時,Druid 通過也可通過多副本高可用的方式自動 Failover。
  5. 雲原生架構:Druid 將數據存儲在外部 Deep Storage(例如 雲存儲、HDFS 等),即使 Druid 服務節點故障,也不影響數據的可靠性。
  6. 索引加速:Druid 通過位圖方式自動對數據建索引,支持快速的索引過濾。
  7. 時間分區:Druid 會先將數據按時間分區,也可根據其他方式進一步分區,基於時間範圍的查詢只會訪問對應時間範圍內地數據。
  8. 預聚合:Druid 支持在導入數據時對數據進行提前的聚合分析,例如sum、count、min、max等,作為數據的元數據存儲,當實際訪問時,可直接訪問預聚合好的數據。
  9. SQL 支持:Druid 同時支持 SQL、HTTP 方式訪問,表達能力強,靈活方便。

Druid 數據模型

架構解析

核心組件

  • Coordinator 負責集群的協調及數據高可用
  • Overlord 控制集群數據導入任務的分配
  • Broker 處理客戶端查詢請求
  • Router 是可選的路由組件
  • Historical 負責可查詢數據的存儲
  • MiddleMangager 負責數據的導入

部署方式

Druid 的各個組件可以隨意部署,但根據組件的職能,會分成三類,每一類組件建議在服務器上混部。

  • Master Servers:運行集群的 Coordinator 與 Overlord 控制類的組件。
  • Query Servers:運行集群查詢類組件,包括 Broker、Router
  • Data Servers:運行集群數據導入、存儲相關組件,包括 Middle Managers、Histricals

外部依賴

Druid 本身不存儲數據,數據的存儲依賴於外部的組件,數據的存儲(Deep Storage)依賴外部的存儲,例如 AWS S3、阿里雲 OSS、HDFS 等分佈式存儲,雲數據存儲依賴 MySQL、PostgreSQL 等數據庫;依賴 Zookeeper 實現服務發現、Leader 選舉等功能。

Deep Storage

Druid 本身不存儲數據,而將數據存儲到外部的 Deep Storage,由 Deep Storage 保證數據的可靠存儲,例如 AWS S3、阿里雲 OSS、HDFS 等分佈式存儲。

Druid 的數據會按數據順序組織,並按時間維度對數據進行分區存儲,一段時間範圍的數據會存儲到一起,組成一個 Segment。數據在 Segment 裡會按列存方式進行壓縮存儲,並對 Dimension 數據建立索引。
image.png

Segment 結構

Druid 的所有數據都包含時間戳列,還包含多個 Dimensions 以及 Metrics 列,其中 Dimension 列可支持快速過濾、聚合,Druid 在存儲 Dimension 列時,會進行壓縮存儲,並通過位圖方式建索引,每一列的數據包含

  1. Dictionary:存儲列值到 整型 ID 的映射
  2. Column Data:根據 1產生的一系列的整型 ID,進行壓縮存儲
  3. Inverted Index(Bitmaps):針對 Column 裡每個不同的 value,會建一個位圖倒排索引

image.png
比如 Page 列的存儲,包含 "Justin Bieber", "Ke$ha" 兩個取值,該列對應的存儲類似如下三個部分

1: Dictionary that encodes column values
  {
    "Justin Bieber": 0,
    "Ke$ha":         1
  }

2: Column data
  [0,
   0,
   1,
   1]

3: Bitmaps - one for each unique value of the column
  value="Justin Bieber": [1,1,0,0]
  value="Ke$ha":         [0,0,1,1]
 

當某一段時間範圍內地數據量很大時,在將數據存儲為 Segments 時,可以採用 sharding 策略,比如按文件大小切分 Segments、或根據指定的 Dimension 進行 Hash 分到多個 Segments,在檢索的時候,能進一步減少需要查詢的數據。

讀寫流程

數據導入

Druid 支持從 Kafka、Hadoop 裡導入數據,數據導入以 Task 方式進行,Overlord 負責導入任務的分配,Middle Manager 負責實際的數據導入,數據會先寫到 Middle Manager 的內存,積累到一定大小或時間窗口後,數據會組織為 Segment 寫到 Deep Storage,並將 Segment 的元數據寫入到 Metadata Storage。

Coordinator 會週期性的檢測 Metadata Storage,當發現新的 Segment 產生時,會將 Segment 根據負載情況分給其中的部分 Historical(根據副本數) 節點管理,Historical 節點接管 Segment 的管理,這部分 Segment 即可用於查詢。
image.png

數據查詢

Broker 接收數據的查詢請求,根據 Metadata 的信息,計算出查詢關聯的 Middle Managers、Historicals 節點,並將請求發送到對應的節點, Middle Managers、Historicals 根據查詢的時間範圍,找出所有可能包含查詢數據的 Segments,並從中過濾出滿足條件的數據,Broker 負責將查詢結果進行彙總返回給客戶端。
image.png

總結

  1. Druid 與傳統數據庫通過讀寫 API 寫入數據的方式不同,通過 Pull 方式拉取數據,對接常用的 Kafka、HDFS等大數據生態數據源。
  2. 藉助外部可靠的 Deep Storage 和 Meatadata store 來實現數據、元數據的存儲,將 Druid 從數據存儲的高可靠管理中解放,讓各個組件的實現都非常輕量;
  3. Druid 的實現高度模塊化,每個模塊有獨立的職能,但因為組件非常多,在部署管理上稍微有些複雜。
  4. 通過列式存儲以及位圖索引,極大的降低存儲成本,並支持高效的數據過濾查詢。
  5. 通過時間分區策略,對事件型、時序類型場景非常友好,能快速根據查詢時間範圍降低掃描的數據量。

Leave a Reply

Your email address will not be published. Required fields are marked *