jeremygo

jeremygo

我是把下一颗珍珠串在绳子上的人

Druid 查詢最佳實踐

前言#

Druid 是一個分佈式的、支持實時多維分析的數據處理系統,既支持高速的數據實時攝入處理,也支持實時且靈活的多維數據分析查詢,同時支持根據時間戳對數據進行預聚合攝入和聚合分析。

名詞含義
時間戳列數據的時間戳列,所有的查詢都是以時間為中心
維度列數據的維度列,用於過濾數據
指標列數據的聚合列,支持包括 sum、count、mix 和 max 等計算
聚合數據按照時間戳列、維度列、聚合列和聚合粒度進行歸併的過程
聚合粒度接收到多長時間的數據歸併為一條

image

最佳實踐#

貼合 Druid 的特點避免進行效率比較差的操作導致查詢緩慢甚至超時積壓等情況:

  • 提升預聚合比例
    • 聚合粒度設置為分鐘
    • 刪掉不需要的字段,同時儘量不要包含明細字段
    • 在上一條的基礎上如果一個數據源無法滿足所有查詢可以拆分成多個數據源,對應使用不同的維度列
    • 需要 count distinct 的字段設置成 hyperUnique 指標
  • 不要在 SQL 中做行級別的複雜運算,儘可能利用預先計算好的字段
  • 不要在 group by 高基數字段的同時 count distinct
    • 首先避免 group by 高基數字段(超過幾萬個值的字段)
    • group bycount distinct 都會使用 heap 存儲中間結構,疊加容易造成查詢超時或資源超過限制,更嚴重會導致 Druid 發生完全的垃圾回收操作影響整個集群
    • Druid 也會將成功的查詢生成中間緩存,後續類似的 SQL(時間範圍略有不同,其餘查詢條件完全相同)可以命中中間緩存
  • where 過濾條件放越外層越好
  • 使用正確的類型進行查詢,推薦使用 =in 把範圍過濾轉為等值過濾
  • 儘量避免使用 like 或正則匹配提取大文本,推薦上游產出數據時就提取到獨立字段中,減少存儲和查詢成本
  • 使用 group by Floor(__time to DAY) 替換 group by __time,即指定具體的時間粒度,兩者效率差別很大
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。