大資料實時多維OLAP分析資料庫Apache Druid入門分享-上

itxiaoshen發表於2023-01-31

@

概述

定義

Apache Druid 官網地址 https://druid.apache.org/

Apache Druid 官網最新文件地址 https://druid.apache.org/docs/latest/design/

Apache Druid原始碼地址 https://github.com/apache/druid

Apache Druid是一個集時間序列資料庫(timeseries databases)、資料倉儲(data warehouses)和全文檢索日誌分析系統系統(logsearch systems)特點於一體的分析性資料平臺,由MetaMarket公司研發的⼀款針對海量資料進⾏⾼效能實時分析的OLAP引擎的實時分析型資料庫(包含儲存引擎和分析引擎),捐獻給Apache基⾦會。最新版本為25.0.0

注意:此Apache Druid非阿里巴巴開源專案資料庫連線池Druid,不要混為一談。

Apache Druid是一個分散式的、支援實時多維 OLAP 分析、列式儲存的資料處理系統,支援高速的實時資料讀取處理、支援實時靈活的多維資料分析查詢;最常被當作資料庫用以支援攝取、高效能查詢、高聚和高併發API 、高穩定執行的應用場景。Druid支援根據時間戳對資料進行預聚合攝入和聚合分析,在時序資料處理分析場景中也可以使用Druid。Druid有對應的GUI頁面,適用於面向事件型別的資料、實時資料提取、高效能查詢場景。

其中OLAP分析分為關係型聯機分析處理(ROLAP)和多維聯機分析處理(MOLAP),MOLAP需要資料預計算好為一個多維陣列,典型方式就是Cube,而ROLAP就是資料本身什麼樣就是什麼樣,查詢時透過MPP提高分散式計算能力。Druid是ROLAP路線,實時攝取資料,實時出結果,不像Kylin一樣,有一個顯式的預計算過程。

MPP和Lambda補充說明

  • MPP:俗稱大規模並行處理,資料庫叢集中,每個節點都有獨立的磁碟儲存系統跟記憶體系統,業務資料根據資料庫模型跟應用特點被劃分到各個節點,MPP就是將任務並行分散到多個節點,每個節點計算完畢後將結果彙總下來得到最終結果。
  • Lambda架構:該架構的設計是為了在處理大規模資料時,同時發揮流處理和批處理的優勢。透過批處理提供全面、準確的資料,透過流處理提供低延遲的資料,從而達到平衡延遲、吞吐量和容錯性的目的。為了滿足下游的即席查詢,批處理和流處理的結果會進行合併。一般有三層。
    • Batch Layer:批處理層,對離線的歷史資料進行預計算。
    • Speed Layer:加速處理層,處理實時的增量資料。
    • Serving Layer:合併層,計算歷史資料和實時資料都有了。

概述

  • 構建快速和現代化雲原生、流原生的實時分析型資料庫:Druid 是為快速查詢和快速攝入資料的工作流而設計的;Druid 有強大的 UI,執行時可操作查詢,支援高併發性,通常用於需要互動式、一致的使用者體驗。
  • 與現有資料管道輕鬆整合:Druid從Kafka和Amazon Kinesis等訊息佇列傳輸資料,從資料湖(HDFS、Amazon S3等)批次載入檔案。Druid支援最流行的結構化和半結構化資料檔案格式。
  • 在高併發性下進行快速、一致的查詢:Druid 對資料攝入和資料查詢的基準效能測試大大超過了傳統解決方案,結合了新穎的儲存思想、索引結構以及精確和近似查詢,實現亞秒級查詢。
  • 廣泛的適用性:Druid是專為實時和歷史資料的快速臨時查詢而構建;Druid為點選流、APM(應用效能管理系統)、供應鏈、網路遙測、數字營銷、風險/欺詐和許多其他型別的資料等場景解鎖了新的查詢型別和工作流;場景詳細說明如下:
    • 使用者活動和行為:Druid 經常用在點選流,訪問流和活動流資料上。具體場景包括:衡量使用者參與度,為產品釋出追蹤 A/B 測試資料,並瞭解使用者使用方式。Druid 可以做到精確和近似計算使用者指標,例如不重複計數指標、日活使用者指標(平均精度 98%)。Druid 可以用來做“漏斗分析”,測量有多少使用者做了某種操作,沒做某些操作。這對產品追蹤使用者註冊十分有用。
    • 網路流:Druid 常常用來收集和分析網路流資料。Druid 被用於管理以任意屬性切分組合的流資料。Druid 能夠提取大量網路流記錄,並且能夠在查詢時快速對數十個屬性組合和排序,這有助於網路流分析。這些屬性包括一些核心屬性,如 IP 和埠號,也包括一些額外新增的強化屬性,如地理位置、服務、應用、裝置和 ASN。
    • 數字營銷:Druid 常常用來儲存和查詢線上廣告資料。這些資料通常來自廣告服務商,它對衡量和理解廣告活動效果,點選穿透率,轉換率(消耗率)等指標至關重要。Druid 最初就是被設計成一個面向廣告資料的強大的面向使用者的分析型應用程式。在儲存廣告資料方面,Druid 已經有大量生產實踐,全世界有大量使用者在上千臺伺服器上儲存了 PB 級資料。
    • 應用效能管理:Druid 常常用於追蹤應用程式生成的可運營資料;和使用者活動使用場景類似,這些資料可以是關於使用者怎樣和應用程式互動的,它可以是應用程式自身上報的指標資料。Druid 可用於下鑽發現應用程式不同元件的效能如何,定位瓶頸和發現問題。不像許多傳統解決方案,Druid 具有更小儲存容量、更小複雜度、更大資料吞吐的特點。它可以快速分析數以千計屬性的應用事件,並計算複雜的載入、效能、利用率指標。比如基於95 %查詢延遲的 API 終端。可以以任何臨時屬性組織和切分資料,如以天為時間切分資料、以使用者畫像統計、按資料中心位置統計。
    • 物聯網和裝置指標:Driud 可以作為時間序列資料庫解決方案,來儲存處理伺服器和裝置的指標資料。收集機器生成的實時資料,執行快速臨時的分析,去估量效能、最佳化硬體資源和定位問題。和許多傳統時間序列資料庫不同,Druid 本質上是一個分析引擎。Druid 融合了時間序列資料庫、列式分析資料庫和檢索系統的理念。它在單個系統中支援了基於時間分割槽、列式儲存和搜尋索引。基於時間的查詢、聚合和檢索過濾查詢都會特別快。可以在指標中包括百萬唯一維度值,並隨意按任何維度組合 group 和 filter(Druid 中的 dimension 維度類似於時間序列資料庫中的 tag)。可以基於 tag group 和 rank,並計算大量複雜的指標。而且在 tag 上檢索和過濾會比傳統時間序列資料庫更快。
    • OLAP 和商業智慧:Druid 經常用於商業智慧場景。加速查詢和增強應用。和基於 Hadoop 的 SQL 引擎(如 Presto 或 Hive)不同,Druid 為高併發和亞秒級查詢而設計,透過 UI 強化互動式資料查詢。這使得 Druid 更適合做真實的視覺化互動分析。
  • 部署在公共、私有和混合雲中:Druid可以部署在任何*NIX環境的商用硬體上,無論是在雲中還是在內部;部署Druid都是很容易,透過新增和刪除Druid服務實現擴縮容。

特徵

Druid主要的優點在於支援流式和批次資料的匯入、高併發亞秒級查詢、儲存索引最佳化。

  • 低延遲互動式查詢:Druid提供低延遲實時資料攝取(⼊庫),並採⽤預聚合、列式儲存、點陣圖索引等⼿段使得海量資料分析能夠亞秒級響應。

  • ⾼可⽤性( High Available ):Druid 使⽤ HDFS/S3 作為 Deep Storage,Segment 會在多個Historical 節點上進⾏載入;攝取資料時也可以多副本攝取,保證資料可⽤性和容錯性。

  • 可伸縮( Horizontal Scalable ):Druid 部署架構都可以⽔平擴充套件,增加⼤量伺服器來加快資料攝取,在生產環境中可以部署到數十臺多數百臺伺服器組成的叢集中,可以提供每秒百萬條資料的寫入,針對萬億條記錄保證亞秒級的查詢。

  • 大規模並⾏處理( Parallel Processing ): Druid 可以在整個叢集中並⾏處理查詢。

  • 豐富的查詢能⼒( Rich Query ):Druid⽀持時間序列、 TopN、GroupBy等查詢,同時提供了2種查詢⽅式:API 和 SQL。除了原生的基於 JSON 的查詢外,Druid 還支援基於 HTTP 和 JDBC 的 SQL。

  • 列式儲存:Druid使用面相列的儲存,對於OLAP分析需要讀取列分析的場景加快了速度,同時一列資料中有很多共性的資料,資料的壓縮效果好,佔用空間小,支援快速掃描及聚合查詢。

  • 支援實時或者批次讀取資料:Druid支援實時獲取資料,實時獲取的資料可以實時查詢,也支援批次讀取資料。

  • 叢集自動平衡,方便運維:Druid叢集擴大或者縮小時,只需要增加或者減少對應的機器數,Druid叢集自動會平衡各個節點,不需要停機。

  • 對資料進行預聚合或預計算:Druid可以人為指定按照某些時間粒度對相同維度的資料進行在資料攝取階段預聚合計算,既加快了查詢速度,也減少了資料儲存空間。

  • 近似演算法:Druid 應用了近似 count-distinct、近似排序以及近似直方圖和分位數計算的演算法,這些演算法佔用有限的記憶體使用量,通常比精確計算要快得多;對於精度要求比速度更重要的場景,Druid還提供了精確 count-distint 和精確排序。

  • bitmap索引快速過濾:Druid中可以透過bitmap構建索引,對資料進行壓縮,加快查詢過濾速度。

  • 基於時間的分割槽:Druid 首先按時間對資料進行分割槽,另外同時可以根據其他欄位進行分割槽,這意味著基於時間的查詢將僅訪問與查詢時間範圍匹配的分割槽,這將大大提高基於時間的資料的效能。

  • 不會丟失資料的雲原生容錯架構:一旦 Druid 攝取了資料,副本就安全地儲存在深度儲存介質 (通常是雲端儲存、HDFS 或共享檔案系統)中。即使某個 Druid 服務發生故障,也可以以從深度儲存中恢復效據,對於僅影響的少數 Druid 服務的有限故障,副本可確保在系統恢復時仍然可以進行查詢。

  • 靈活的資料模式:Druid 優雅地適應不斷變化的資料模式和巢狀資料型別。

此外Druid也有不足之處,比如:

  • 有限的join能力,Druid適用於清洗好的資料實時寫入,不需要更新資料,所以資料在寫入Druid之前一般需要拉寬處理,在從Druid中查詢資料時,直接查詢這張寬表即可;在join右側的表都會自動存放記憶體再做關聯,這樣會降低效能;
  • 不支援多時間維度,所有維度為String型別。
  • 不支援精準去重。

適用場景

如果使用場景符合下面的一些特性,那麼Druid 將會是一個非常不錯的選擇:

  • 資料的插入頻率非常高,但是更新頻率非常低。
  • 大部分的查詢為聚合查詢(aggregation)和分組報表查詢(reporting queries);例如我們常使用的 "group by" 查詢,同時還有一些檢索和掃描查詢。
  • 查詢的延遲被限制在 100ms 到 幾秒鐘之間。
  • 具有時間屬性(Druid 針對時間做了特殊最佳化和設計)。
  • 在多表場景下,每次查詢僅命中一個大的分散式表,查詢又可能命中多個較小的 lookup 表。
  • 場景中包含高基維度資料列(例如 URL,使用者 ID 等),並且需要對其進行快速計數和排序。
  • 需要從 Kafka、HDFS、文字檔案或者物件儲存(例如,AWS S3)中載入資料。

不適用場景

如果使用場景是下面的一些情況的話,Druid 不是一個較好的選擇:

  • 根據主鍵對現有資料進行低延遲更新操作,Druid 支援流式插人,但不支援流式更新(更新操作透過後臺批處理作業完成)。
  • 不太關注延遲的離線資料系統,查詢的延遲不是系統設計的重要考慮。
  • 使用場景中包括大連線(將一個大事實表連線到另一個大事實表)且可以接受花費較長時間查詢響應。

橫向對比

image-20230131135956719

  • Druid:是一個實時處理時序資料的OLAP資料庫,因為它的索引首先按照時間分片,查詢的時候也是按照時間線去路由索引。適合預聚合模型,不適合即席查詢分享,不支援多事實表JOIN,不適合明細查詢。
  • Kylin:核心是Cube,Cube是一種預計算技術,基本思路是預先對資料作多維索引,查詢時只掃描索引而不訪問原始資料從而提速。不適合即席查詢(提前定於模型預聚合,預技術量大),不支援明細查詢,外部依賴較多,不支援多事實表Join。
  • Presto:它沒有使用MapReduce,大部分場景下比Hive快一個數量級,其中的關鍵是所有的處理都在記憶體中完成。不支援預聚合,自己沒儲存。
  • Impala:基於記憶體運算,速度快,支援的資料來源沒有Presto多。不支援預聚合,自己沒儲存。
  • Spark SQL:基於Spark平臺上的一個OLAP框架,基本思路是增加機器來平行計算,從而提高查詢速度。
  • ElasticSearch:最大的特點是使用了倒排索引解決索引問題。根據研究,ES在資料獲取和聚集用的資源比在Druid高。不支援預聚合,不適合超大規模資料處理,組合查詢效能欠佳。
  • ClickHouse:C++編寫的高效能OLAP工具,不支援高併發,資料量超大會出現瓶頸(儘量選擇預聚合出結果表),非常吃CPU資源,支援MVCC。

框架選型:從超大資料的查詢效率來看 Druid > Kylin > Presto > Spark SQL,從支援的資料來源種類來講 Presto > Spark SQL > Kylin > Druid。

部署

單機部署

# 下載apache-druid最新版本25.0.0
wget https://dlcdn.apache.org/druid/25.0.0/apache-druid-25.0.0-bin.tar.gz
# 下載相容hadoop3的apache-druid最新版本25.0.0
wget https://dlcdn.apache.org/druid/25.0.0/apache-druid-25.0.0-hadoop3-bin.tar.gz
# 解壓檔案
tar -xvf apache-druid-25.0.0-bin.tar.gz
# 進入目錄
cd apache-druid-25.0.0

image-20230131150345801

  • bin:工具指令碼
  • conf:配置檔案
  • extensions:druid的擴充套件包
  • hadoop-dependencies:druid的hadoop依賴包
  • lib:核心依賴包
  • licenses:licenses檔案
  • quickstart:快速啟動相關檔案,包含示例資料
# 單機啟動druid
./bin/start-druid -m 16g

image-20230131152024903

啟動後在druid的根目錄下產生兩個目錄,一個log和一個var。所有持久狀態如叢集後設資料儲存和服務段都儲存在Druid根目錄下的var目錄中;每個服務寫入var/sv下的日誌檔案,可以透過刪除整個var目錄將Druid恢復到安裝後的原始狀態。

image-20230131152931041

訪問Druid的控制檯頁面:http://192.168.5.52:8888/

image-20230131153308964

入門示例

拿官方提供quickstart的示例資料檔案來演示

image-20230131163104678

在“查詢”檢視中,單擊“連線外部資料”。選擇“本地磁碟”,輸入值(分別輸入基本目錄和萬用字元檔案過濾器(由UI提供),允許您一次指定要攝入的多個檔案)後單擊連線資料。

image-20230131172255098

在Parse頁面上在將資料載入到Druid之前可以檢查原始資料和執行操作

image-20230131163627727

單擊Done返回到Query檢視,該檢視顯示新生成的查詢,查詢將樣例資料插入到名為wikipedia(原來為wikiticker-2015-09-12-sampled,修改表名)的表中。

生成SQL如下

REPLACE INTO "wikipedia" OVERWRITE ALL
WITH "ext" AS (SELECT *
FROM TABLE(
  EXTERN(
    '{"type":"local","baseDir":"quickstart/tutorial/","filter":"wikiticker-2015-09-12-sampled.json.gz"}',
    '{"type":"json"}',
    '[{"name":"time","type":"string"},{"name":"channel","type":"string"},{"name":"cityName","type":"string"},{"name":"comment","type":"string"},{"name":"countryIsoCode","type":"string"},{"name":"countryName","type":"string"},{"name":"isAnonymous","type":"string"},{"name":"isMinor","type":"string"},{"name":"isNew","type":"string"},{"name":"isRobot","type":"string"},{"name":"isUnpatrolled","type":"string"},{"name":"metroCode","type":"long"},{"name":"namespace","type":"string"},{"name":"page","type":"string"},{"name":"regionIsoCode","type":"string"},{"name":"regionName","type":"string"},{"name":"user","type":"string"},{"name":"delta","type":"long"},{"name":"added","type":"long"},{"name":"deleted","type":"long"}]'
  )
))
SELECT
  TIME_PARSE("time") AS "__time",
  "channel",
  "cityName",
  "comment",
  "countryIsoCode",
  "countryName",
  "isAnonymous",
  "isMinor",
  "isNew",
  "isRobot",
  "isUnpatrolled",
  "metroCode",
  "namespace",
  "page",
  "regionIsoCode",
  "regionName",
  "user",
  "delta",
  "added",
  "deleted"
FROM "ext"
PARTITIONED BY DAY

單擊Run執行查詢。這個任務可能需要一兩分鐘才能完成。完成後,任務將顯示其持續時間和插入到表中的行數。檢視被設定為自動重新整理,因此不需要重新整理瀏覽器就能看到狀態變化。

image-20230131172001331

輸入SQL,點選執行查詢資料

SELECT
  channel,
  COUNT(*)
FROM "wikipedia"
GROUP BY channel
ORDER BY COUNT(*) DESC

image-20230131172545737

也可以使用Druid SQL API提交和取消Druid SQL查詢。Druid SQL API可以在https://ROUTER:8888/druid/v2/sql上找到,其中ROUTER是Druid ROUTER的IP地址.

curl -XPOST -H'Content-Type: application/json' http://localhost:8888/druid/v2/sql/ -d @wikipedia-top-pages-sql.json

image-20230131180123024

Druid的原生查詢語言是基於HTTP的JSON,可以檢視wikipedia-top-pages.json的內容

image-20230131225149365

{
  "queryType" : "topN",
  "dataSource" : "wikipedia",
  "intervals" : ["2015-09-12/2015-09-13"],
  "granularity" : "all",
  "dimension" : "page",
  "metric" : "count",
  "threshold" : 10,
  "aggregations" : [
    {
      "type" : "count",
      "name" : "count"
    }
  ]
}

可以透過http請求也可以透過druid控制檯查詢

curl -X POST 'http://localhost:8888/druid/v2/?pretty' -H 'Content-Type:application/json' -H 'Accept:application/x-jackson-smile' -d @wikipedia-top-pages.json

image-20230131225047677

  • 本人部落格網站IT小神 www.itxiaoshen.com

相關文章