Druid 介紹和應用

Druid 介紹

提及 Druid,你們首先想到的是阿里的 Druid 數據庫鏈接池,而本文介紹的 Druid 是一個在大數據場景下的解決方案,是須要在複雜的海量數據下進行交互式實時數據展示的 BI/OLAP 工具。數據庫

它有三個特色:json

  • 處理的數據量規模較大。後端

  • 能夠進行數據的實時查詢展現。安全

  • 它的查詢模式是交互式的,這也說明其查詢併發能力有限。網絡

目前 Druid 普遍應用在國內外各個公司,好比阿里,滴滴,知乎,360,eBay,Hulu 等。架構

Druid 之因此可以在 OLAP 家族中佔據一席之地,主要依賴其強大的 MPP 架構設計,關於它的架構,這裏就不展開描述了,感興趣的同窗能夠登錄官網 druid.io 進行了解。併發

除了 MPP 架構外,它還運用到了四點重要的技術,分別是:負載均衡

  • 預聚合工具

  • 列式存儲學習

  • 字典編碼

  • 位圖索引

預聚合算是 Druid 的一個很是大的亮點,經過預聚合能夠減小數據的存儲以及避免查詢時不少沒必要要的計算。

因爲 OLAP 的分析場景大多隻關心某個列或者某幾個列的指標計算,所以數據很是適合列式存儲。

在列式存儲的基礎之上,再加上字段編碼,可以有效的提高數據的壓縮率,而後位圖索引讓不少查詢最終直接轉化成計算機層面的位計算,提高查詢效率。

Druid 既然是 OLAP 工具,那它和其餘 OLAP 工具備哪些差別呢?

 

圖 1:OLAP 工具的對比

從上圖能夠看出,Kylin 和 Druid 總體上相比較其餘兩個仍是頗有優點的:

相比較 Kylin,Druid 沒有模型管理和 cube 管理的能力,Kylin 沒法提供實時查詢。

相比較 ES,Druid 的優點在於聚合計算,ES 的優點在於查明細,在蘇寧,對 Druid 的使用,通常應用在須要對數據進行實時聚合查詢的場景。

Druid的應用場景

門店 App 系統

門店 App 系統是一款集數據服務、銷售開單、會員營銷、收發盤退、績效管理、V 購用戶溝通、學習中心等於一體的門店店員移動工做平臺,其銷售界面以下所示:

圖 2:銷售界面

 

圖 3:客流界面

 

門店 App 業務大體狀況以下:

  • 數據量:保存近幾年的數據。

  • 數據接入方式:Kafka 實時數據接入,隔天離線數據覆蓋昨天數據。

  • 查詢方式:實時查詢。

  • 業務實現:topN 實現銷售額曲線展現,groupby 分組樓層客流分佈,timeserise 作天彙總。

報表系統

 

大體狀況以下:

  • 數據量:保存近幾年數據。

  • 數據接入方式:Kafka 實時數據接入。

  • 查詢方式:實時查詢。

  • 業務實現:topN 實現銷售餅圖展現,groupby 分組實現大區銷售排名。

基於 OLAP 引擎的平臺架構

爲保證數據的一致性和統一性,該平臺基於 OLAP 引擎,爲集團各個業務提供統一的維度指標分析系統:

  • 百川系統經過 OLAP 引擎構建模型,OLAP 引擎根據業務需求,將模型拆分紅若干個 cube,存儲到底層的 Druid,Hive,PG 和 ES。咱們稱這個過程爲模型加速,另外,百川系統自身會構建各類各樣的指標。

  • 業務方,好比天工,諸葛等系統經過百川提供的指標,選擇其中一個或多個進行報表的構建,其查詢請求會發送到百川系統。

  • 百川系統構造 SQL 語句,再把請求發送到 OLAP 引擎,OLAP 引擎經過底層的 Spark 平臺,解析 SQL 語句,將請求路由到 Druid,ES,Hive 和 PG,其中,時序化數據的聚合查詢,將路由到 Druid 平臺,最後查詢結果一層一層彙總到上層的業務系統。

  • 整個系統的監控,經過雲跡系統、華佗系統等進行監控,將系統日誌接入雲跡,將系統的 metric 信息接入華佗。

隨着 Druid 平臺建設的不斷推動,使用 Druid 的業務也愈來愈多,在使用的過程當中也會遇到各類各樣的問題,下文總結了蘇寧業務開發人員在使用 Druid 中遇到的一些問題,但願對正在閱讀本文的讀者有些幫助。

Druid 使用建議

本小節主要想結合實際問題,給你們提供一些 Druid 的使用建議,供你們參考。

①什麼樣的業務適合用 Druid?

建議以下:

  • 時序化數據:Druid 能夠理解爲時序數據庫,全部的數據必須有時間字段。

  • 實時數據接入可容忍丟數據(tranquility):目前 tranquility 有丟數據的風險,因此建議實時和離線一塊兒用,實時接當天數據,離線次日把今天的數據所有覆蓋,保證數據完備性。

  • OLAP 查詢而不是 OLTP 查詢:Druid 查詢併發有限,不適合 OLTP 查詢。

  • 非精確的去重計算:目前 Druid 的去重都是非精確的。

  • 無 Join 操做:Druid 適合處理星型模型的數據,不支持關聯操做。

  • 數據沒有 update 更新操做,只對 segment 粒度進行覆蓋:因爲時序化數據的特色,Druid 不支持數據的更新。

②如何設置合理的 Granularity?

Granularity 設置

首先解釋下 segmentGranularity 和 queryGranularity,前者是 segment 的組成粒度,後者是 segment 的聚合粒度。

要求 queryGranularity 小於等於 segmentGranularity,而後在數據導入時,按照下面的規則進行設置。
segmentGranularity(離線數據導入的設置):

  • 導入的數據是天級別之內的:「hour」或者「day」。

  • 導入的數據是天級別以上的:「day」。

  • 導入的數據是年級別以上的:「month」。

須要說明的是,這裏咱們僅僅是簡單的經過 intervals 進行 segmentGranularity 的設置,更加合理的作法應該是結合每一個 segment 的大小以及查詢的複雜度進行綜合衡量。

考慮到 tranquility 實時任務的特殊性和數據的安全性,咱們建議實時數據導入時,segmentGranularity 設置成「hour」。

queryGranularity:根據業務查詢最小粒度和查詢複雜度來定,假設查詢只須要到小時粒度,則該參數設置爲「hour」。

③須要去重的維度到底需不須要定義到維度列中?

 

若是去重的維度只須要去重計算,沒有其餘的做用,譬如進行過濾或者做爲分組字段,咱們建議不要添加到維度列中,由於不添加的話,這樣數據的預聚合效果更好。

④如何選擇查詢方式?

經常使用的三種查詢:

  • select sum(A) from DS where time>? [timeseries]

  • select sum(A) from DS where time>? group by B order by C limit 2 [topN]

  • select sum(A) from DS where time>? group by B,C order by C limit 2[groupby]

沒有維度分組的場景使用 timeseries,單維度分組查詢的場景使用 topN,多維度分組查詢場景使用 groupby。

因爲 groupby 並不會將 limit 下推(Druid 新版本進行了優化,雖然能夠下推,可是對於指標的排序是不許確的),因此單維度的分組查詢,儘可能用 topN 查詢。

咱們作的工做

從 Druid 引入蘇寧以後,不久便承擔起了 OLAP 分析的重任,做爲底層核心引擎支撐模型和指標服務,併爲集團各條業務線的 OLAP 分析服務,在過去的時間裏,咱們作了不少工做,本文列舉一些進行說明。

①OCEP(Druid 集羣前置 proxy)

OCEP(Druid 集羣前置 proxy)

 

OCEP 是 Druid 集羣一個前置 proxy,經過它來提供更加完備的 Druid 集羣化和服務化能力,並解決當前 Druid 服務存在的各類問題。

它提供的功能主要有:

  • 訪問鑑權(針對每一個 datasource 提供 token 訪問鑑權,保證數據安全)。

  • 訪問審計(對每一個查詢都會生成惟一的 queryId,提供完整的請求來源)。

  • 請求攔截(對非預期的訪問,制定攔截策略,細化到具體的 datasource 和查詢語句)。

  • 請求路由(根據集羣名稱和 datasource,將請求路由到指定的 Druid 集羣,並根據後端 broker 的壓力,將請求負載均衡各個 broker 上)。

  • 服務隔離(可設置策略,對於不一樣的 datasource 的請求,可路由到指定的 broker 上,實現 broker 隔離)。

②Druid 查詢客戶端

官方提供的查詢方式是經過編寫 Json 文件,以 HTTP 的方式請求 Druid,然而這種方式的缺點也很明顯,首先 Json 內容書寫繁瑣,格式極易寫錯,另外在 Java 開發時,出現問題不利於定位。

 

json語句

 

因而咱們封裝了一層 Java API,以下圖:

 

③資源隔離

 

不一樣業務的數據量有大小之分以及對服務穩定性要求不同,咱們經過如下三點實現業務層面的隔離:

  • Historical 分組:集羣設置不一樣的 tier,存儲不一樣的業務數據。

  • Broker 隔離:經過 OCEP 設置 datasource 白名單,不一樣的 broker 只提供某個或某幾個 datasource 的查詢。

  • 冷熱數據隔離:經過設置 datasource 的 rule,將冷熱數據分別存儲在不一樣的 tier 中。

  • Druid 白名單控制。

集羣穩定性壓倒一切,防止控制之外的機器對集羣進行無效查詢和攻擊,咱們經過增長一個 whitelist 的 extension,以模塊的方式在服務端進行白名單的控制。

而且能夠針對不一樣的服務進行控制,將 whitelist 的配置文件寫在 Druid 的 metadata 的 config 表中,實現動態更新。

 

圖 14:白名單 extension

 

圖 15:Druid 白名單配置

④Druid 離線導入時對 intervals 的控制

有些離線導入的任務,佔用了 YARN 太多的資源,個別任務消耗了上千個或者上萬的 container 資源,分析發現是因爲業務設置的 segmentGranularity 不合理,最終會致使 segment 過多,產生不少 HDFS 小文件。

因而咱們在 overlord 服務端,增長參數「druid.indexer.intervals.maxLimit」,對離線任務進行判斷。

若是 segmentGranularity 和 interval 設置的不合理,將禁止提交。譬如,segmentGranularity 設置的是小時,interval 設置的間隔是 1 年,這種是不合理的,服務端將禁止數據導入。

 

離線導入對 intervals 的控制參數配置

⑤Coordinator 自動 merge segment 時啓動 task 的併發數控制

在集羣中,咱們打開了 coordinator 自動 merge segment 的功能,coordinator 默認每隔 30 分鐘,啓動 merge 線程,掃描全部的 datasource,將太小的 segment 按要求進行合併。

每當一批 segment 符合 merge 要求了,就會請求 overlord 進行啓動 merge task。

若是集羣內小 segment 不少,merge task 將啓動無數個,堵塞 middleManager 的 peon 資源,咱們增長限制 merge task 的併發數的參數,保證每次 merge 線程只啓動必定數量的 task。

設置 merge task 的併發數

⑥Druid 監控

監控對於任何一個系統而言都是很是重要的,能夠幫助咱們提早預知系統的健康情況,Druid 的監控主要有兩點,業務查詢狀況和平臺運行狀況。

前者主要包括 datasource 的查詢量、查詢耗時、網絡流量等;後者主要包括各個服務的 gc 狀況、cpu 和內存使用狀況、空閒 Jetty 線程數等。

咱們的監控方案是 Druid_Common 集羣和 Druid_OLAP 集羣相互監控,互相存儲對方的 metric 信息,而後經過 superset 展現。

 

Druid 的監控方案

將來規劃

Druid 在蘇寧還有很長一段路要走,不管從查詢優化方面仍是集羣管理方面,都有不少事情要作。
查詢優化方面:

  • 高基數問題:高基數查詢一直是 OLAP 查詢的一大痛點,新版本雖然支持 limit 下推,但也只是對維度進行排序的時候,才能保證準確性。

  • SQL 支持:進行 Druid 版本升級,提供豐富的 SQL 查詢接口。

  • 精準去重:目前 Druid 對去重的計算,不管是 HyperLogLog、ThetaSketch 仍是最新版本提供的 HLLSketch 都是非精確的,後面考慮是否能夠經過集成 bitmap 解決。

集羣管理方面:

  • Kafkaindex service 使用:tranquility 的時間窗口限制會形成延遲很大的數據丟失,並且實時 peon 的管理不夠靈活,某些場景下,也會形成數據丟失。

而 Kafka index service 的實時 peon 調用了 Kafka 底層的 API,管理更靈活,依賴 Kafka 實現數據的不丟不重。

  • Datasource 跨集羣遷移:Druid 不管是數據導入仍是數據查詢都很是依賴 Zookeeper,當集羣規模愈來愈大,datasource 愈來愈多的時候,Zookeeper 也許會成爲瓶頸。

這樣的話,就須要作 datasource 的遷移,而遷移工做涉及到 datasource 元數據和 HDFS 數據的遷移,如何讓遷移工做輕量化,是咱們須要思考的。

相關文章
相關標籤/搜索