OLAP引擎這麼多,為什麼蘇寧選擇用Druid?

【51CTO.com原創稿件】隨著公司業務增長迅速,數據量越來越大,數據的種類也越來越豐富,分析人員對數據處理的響應延時要求也越來越高,傳統的大數據處理工具已經無法滿足業務的需求。


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


特別是 OLAP 分析場景,需要對各種維度和度量進行上卷、下鑽、切片和切塊分析,並要求分析結果能夠實時返回。

因此我們調研和對比了一些目前主流的 OLAP 分析工具,針對聚合計算的實時分析,我們引入了開源分析工具 Druid。

Druid 介紹

說起 Druid,大家首先想到的是阿里的 Druid 數據庫連接池,而本文介紹的 Druid 是一個在大數據場景下的解決方案,是需要在複雜的海量數據下進行交互式實時數據展現的 BI/OLAP 工具。

它有三個特點:

  • 處理的數據量規模較大。
  • 可以進行數據的實時查詢展示。
  • 它的查詢模式是交互式的,這也說明其查詢併發能力有限。

目前 Druid 廣泛應用在國內外各個公司,比如阿里,滴滴,知乎,360,eBay,Hulu 等。

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

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

  • 預聚合
  • 列式存儲
  • 字典編碼
  • 位圖索引

預聚合算是 Druid 的一個非常大的亮點,通過預聚合可以減少數據的存儲以及避免查詢時很多不必要的計算。

由於 OLAP 的分析場景大多隻關心某個列或者某幾個列的指標計算,因此數據非常適合列式存儲。

在列式存儲的基礎之上,再加上字段編碼,能夠有效的提升數據的壓縮率,然後位圖索引讓很多查詢最終直接轉化成計算機層面的位計算,提升查詢效率。

Druid 既然是 OLAP 工具,那它和其他 OLAP 工具有哪些差異呢?


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 1:OLAP 工具的對比

從上圖可以看出,Kylin 和 Druid 整體上相比較其他兩個還是很有優勢的:

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

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

Druid 在蘇寧的應用場景

蘇寧很多業務場景都使用到了 Druid,本文將列舉兩個例子,分別是門店 App 系統以及諸葛系統。

門店 App 系統

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


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 2:銷售界面

OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 3:客流界面

門店 App 業務大致情況如下:

  • 數據量:保存近幾年的數據。
  • 數據接入方式:Kafka 實時數據接入,隔天離線數據覆蓋昨天數據。
  • 查詢方式:實時查詢。
  • 業務實現:topN 實現銷售額曲線展示,groupby 分組樓層客流分佈,timeserise 做天彙總。

諸葛報表系統

諸葛報表系統是蘇寧重要的系統之一,能夠幫助業務做出決策分析,減少手工分析成本,幫助提高銷售,該系統可以主動給業務發送銷售數據,推動業務進行銷售關注和分析。


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 4:諸葛報表系統

諸葛業務大致情況如下:

  • 數據量:保存近幾年數據。
  • 數據接入方式:Kafka 實時數據接入。
  • 查詢方式:實時查詢。
  • 業務實現:topN 實現銷售餅圖展示,groupby 分組實現大區銷售排名。

上文簡單介紹了一下什麼是 Druid 以及 Druid 在蘇寧的兩個業務場景應用,那 Druid 在蘇寧的平臺建設是怎樣的呢?

Druid 在蘇寧的平臺建設


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 5:兩種架構

Druid 的平臺建設在蘇寧主要有兩種:

  • 通過 OCEP(提供負載均衡,查詢路由功能等),使用 Druid 原生的能力,滿足業務一系列的需求。
  • 結合蘇寧的天工系統和百川系統,Druid 作為 OLAP 引擎的底層加速系統,提供統一報表的查詢能力。

目前,大部分的業務使用 Druid 的方式主要還是第一種,有少量的業務使用的是第二種方式,隨著第二種方式的逐漸成熟,後面大家的業務會逐漸從第一種方式遷移到第二種上去,實現資源統一。

基於 OCEP 的平臺架構


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 6:基於 OCEP 的平臺架構

該平臺主要依賴 OCEP,對外提供一系列的 OLAP 查詢服務,滿足集團內部各種業務的維度指標分析需求:

  • 通過 tranquility 實時消費業務數據,發送到 Druid 的 realtime peon,並進行 handoff 持久化到 HDFS 上,由 coordinator 進行加載到 historical 中,提供查詢服務。
  • 通過蘇寧自研的 IDE 任務調度系統,將 HDFS 上的離線數據(一般是數倉數據)經過 mapreduce 任務處理完寫入到 Druid 指定的 HDFS 路徑下,同樣由 coordinator 進行加載到 historical 中,提供查詢服務。
  • 最後通過 OCEP,將業務的查詢路由到各個 broker 上,broker 再分發給 historical,經過 historical 計算後,再向上一層一層返回給業務。

基於 OLAP 引擎的平臺架構


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 7:基於 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?


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 8:Granularity 設置

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

要求 queryGranularity 小於等於 segmentGranularity,然後在數據導入時,按照下面的規則進行設置。

segmentGranularity(離線數據導入的設置):

  • 導入的數據是天級別以內的:“hour”或者“day”。
  • 導入的數據是天級別以上的:“day”。
  • 導入的數據是年級別以上的:“month”。

需要說明的是,這裡我們僅僅是簡單的通過 intervals 進行 segmentGranularity 的設置,更加合理的做法應該是結合每個 segment 的大小以及查詢的複雜度進行綜合衡量。

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

queryGranularity:根據業務查詢最小粒度和查詢複雜度來定,假設查詢只需要到小時粒度,則該參數設置為“hour”。

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


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 9:去重維度定義

如果去重的維度只需要去重計算,沒有其他的作用,譬如進行過濾或者作為分組字段,我們建議不要添加到維度列中,因為不添加的話,這樣數據的預聚合效果更好。

④如何選擇查詢方式?

常用的三種查詢:

  • 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)


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 10: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 開發時,出現問題不利於定位。


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 11:Json 語句

於是我們封裝了一層 Java API,如下圖:


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 12:Druid Java Client

③資源隔離


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 13:資源隔離

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

  • Historical 分組:集群設置不同的 tier,存儲不同的業務數據。
  • Broker 隔離:通過 OCEP 設置 datasource 白名單,不同的 broker 只提供某個或某幾個 datasource 的查詢。
  • 冷熱數據隔離:通過設置 datasource 的 rule,將冷熱數據分別存儲在不同的 tier 中。
  • Druid 白名單控制。

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

並且可以針對不同的服務進行控制,將 whitelist 的配置文件寫在 Druid 的 metadata 的 config 表中,實現動態更新。


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 14:白名單 extension

OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 15:Druid 白名單配置

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

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

於是我們在 overlord 服務端,增加參數“druid.indexer.intervals.maxLimit”,對離線任務進行判斷。

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


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 16:離線導入對 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。


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 17:設置 merge task 的併發數

⑥Druid 監控

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

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

我們的監控方案是 Druid_Common 集群和 Druid_OLAP 集群相互監控,互相存儲對方的 metric 信息,然後通過 superset 展示。


OLAP引擎這麼多,為什麼蘇寧選擇用Druid?


圖 18: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 數據的遷移,如何讓遷移工作輕量化,是我們需要思考的。

簡介:蘇寧易購 IT 總部大數據中心大數據平臺研發工程師。多年大數據底層平臺開發經驗。現負責蘇寧大數據底層平臺的計算資源調度平臺以及 Druid 平臺的研發工作,提供離線計算平臺和實時計算平臺的資源調度方案,提供基於 Druid 的 OLAP 平臺,為集團各種維度指標分析業務提供穩定保障。


分享到:


相關文章: