Druid的常見應用領域:
作為壹家SaaS公司,有贊有很多業務場景,有很多實時和線下的數據。在德魯伊被使用之前,分析和開發壹些OLAP場景的學生都使用火花流或風暴。使用這種方案不僅需要編寫實時任務,還需要仔細設計查詢的存儲。存在的問題有:開發周期長;初始存儲設計難以滿足需求的叠代開發;不可擴展。
使用Druid後,開發者只需要填寫壹個數據攝入配置,指定維度和指標,就可以完成數據攝入;從上面描述的Druid的特點我們知道,Druid支持SQL,應用app可以像普通JDBC壹樣查詢數據。在Zan自研OLAP平臺的幫助下,數據攝入配置變得更加簡單方便,創建壹個實時任務只需要10分鐘,大大提高了開發效率。
德魯伊的架構是Lambda架構,分為實時層(Overmaster,MiddleManager)和批處理層(Broker,Historical)。主要節點包括(PS: Druid的所有功能都在同壹個軟件包中,由不同的命令啟動):
4.1贊OLAP平臺的主要目標:
4.2贊OLAP平臺架構
贊贊OLAP平臺是用來管理德魯伊和周圍的組件管理系統。OLAP平臺的主要功能是:
OLAP平臺采用的數據導入方式是寧靜工具,根據流量大小給每個數據源分配不同的寧靜實例。DataSource的配置將被推送到Agent-Master,它將收集每個服務器的資源使用情況,並選擇壹個資源豐富的機器來啟動寧靜實例。目前只需要考慮服務器的內存資源。同時,OLAP平臺還支持寧靜實例的啟動和停止、擴容和縮容功能。
流數據處理框架總是有壹個時間窗口,晚於該時間窗口的數據將被丟棄。如何保證後期數據可以內置到段中,避免實時任務窗口長時間關閉?我們開發了Druid數據補償功能,並在OLAP平臺上配置了流式ETL來存儲HDFS上的原始數據。基於Flume的流式ETL可以根據事件發生的時間保證同壹時刻的數據在同壹文件路徑中。然後通過OLAP平臺手動或自動觸發Hadoop-Batch任務,並離線構建該段。
基於Flume的ETL采用HDFS Sink同步數據,實現了時間戳的攔截器,根據事件的時間戳字段創建文件(每小時創建壹個文件夾),延遲的數據可以正確地歸檔到相應小時的文件中。
隨著訪問服務的增加和長期運行時間的增加,數據規模越來越大。歷史節點加載了大量的分段數據,發現大部分查詢都集中在最近幾天。也就是說,最近幾天的熱點數據很容易被查詢到,所以將冷熱數據分開,提高查詢效率非常重要。Druid提供了歷史層分組機制和數據加載規則機制,通過配置可以很好的將數據從冰冷中分離出來。
首先,對歷史組進行分組。默認分組是“_default_tier”。規劃了少量歷史節點,使用了SATA磁盤。將大量歷史節點規劃到“熱”組中,並使用SSD磁盤。然後為每個數據源配置加載規則:
增加“熱”分組集群的druid.server.priority值(默認值為0),熱數據的查詢將歸入“熱”分組。
Druid架構中的每個組件都有很好的容錯性,集群在出現單點故障的情況下仍然可以向外界提供服務:協調器和霸王由HA保障;分段以多份副本保存在HDFS/S3;同時,Peon節點攝取的歷史加載段和實時部分數據可以建立多個副本提供服務。同時,為了在節點/集群進入不良狀態或達到容量極限時盡快發送警報消息。和其他大數據框架壹樣,我們也為德魯伊做了詳細的監控和告警項,分為兩個層次:
歷史集群的部署對應於第4.4節中描述的冷熱數據的分離。SSD集群用於存儲最近n天(負載可調的天數)的熱數據,相對便宜的Sata型號用於存儲更長時間的歷史冷數據。同時,充分利用Sata的IO能力來加載不同磁盤的分段負載。有贊有很多收費服務,我們在硬件層面進行隔離,保證這些服務在查詢端有足夠的資源;在接入層使用路由器作為路由,避免了Broker的單點問題,也可以很大程度上集群查詢吞吐量。在MiddleManager集群中,除了索引任務(基於內存的任務),我們還部署了壹些高流量的寧靜任務(基於CPU的任務),提高了MiddleManager集群的資源利用率。
Zan業務的查詢方式壹般是經紀人/路由器上的SQL。我們發現,壹旦出現壹些緩慢的查詢,客戶端將不會響應查詢,連接將變得越來越難獲得。登錄Broker的服務器後,發現可用連接數急劇減少到枯竭,同時出現大量TCP Close_Wait。用jStack工具排除故障後發現死鎖。請查看問題-6867,了解具體的堆棧。
檢查源代碼後發現,DruidConnection為每個語句都註冊了壹個回調。壹般情況下,語句結束後,執行回調函數,從DruidConnection的語句中去除自己的狀態;如果有慢速查詢(超過最長連接時間或者從客戶端Kill),連接將被強制關閉,同時關閉其下的所有語句。兩個線程(關閉連接的線程和正在退出語句的線程)各有壹個鎖,當另壹方釋放鎖時,就會發生死鎖,連接會立即耗盡。
在弄清楚問題之後,我們還向社區提出了PR-6868。目前已成功並入主分支,將發布0.14.0版本。如果讀者也遇到了這個問題,可以直接在自己的分支機構裏修復PR的櫻桃精。
目前常用的數據采集方案有KafkaIndex和寧靜。我們采用寧靜的計劃。目前,安寧支持Kafka和Http攝取數據,但攝取數據的方式並不多。寧靜也是MetaMarket的壹個開源項目。更新速度慢,很多功能缺失。最重要的是缺乏監控功能。我們無法監控實例的運行狀態、攝入率、積壓、損耗等信息。
目前支持啟動和停止寧靜的實例管理的操作,比如擴容和縮容,實現方法和Druid的MiddleManager管理Peon節點壹樣。通過將寧靜或自研的攝取工具轉化為Yarn應用或Docker應用,可以將資源調度和實例管理委托給更可靠的調度器。
Druid目前不支持連接查詢,所有聚合查詢都被限制在壹個數據源中。然而,在實際的使用場景中,我們經常需要幾個數據源來進行連接查詢,以獲得所需的結果。這是我們面臨的難題,也是德魯伊開發團隊的難題。
對於C端OLAP查詢場景,RT要求相對較高。因為Druid會在整點創建當前整點的索引任務,如果查詢恰好落在新創建的索引任務上,那麽查詢會很毛刺,如下圖所示:
我們做了壹些優化和調整。首先,我們調整了warmingPeriod參數,並在整點之前啟動了Druid索引任務。對於壹些TPS低但QPS高的數據源,調高SegmentGranularity,大部分查詢都是查詢最近24小時的數據,保證查詢的數據在內存中,減少了新索引任務的數量,大大改善了查詢毛刺。盡管如此,離我們的預期目標還有壹定的差距。接下來,我們來優化壹下源代碼。
目前大部分數據源的段粒度在小時量級,HDFS上存儲的段是每小時壹段。當查詢時間跨度較長時,會導致查詢緩慢,占用大量歷史資源,甚至會出現Broker OOM。如果創建了壹個Hadoop-Batch任務,那麽壹周前的數據(例如)將被向上滾動,索引將被重建,這對壓縮存儲和提高查詢性能應該有很好的效果。關於歷史數據匯總,我們已經處於實踐階段,稍後將在壹篇專門的博客文章中介紹。
最後做個小廣告。贊大大數據團隊的基礎設施團隊主要負責贊大數據平臺(DP)、實時計算(Storm、Spark Streaming、Flink)、離線計算(HDFS、YARN、HIVE、SPARK SQL)、在線存儲(HBase)、實時OLAP (Druid)等幾個技術產品。歡迎有興趣的朋友聯系zhaojiandong@youzan.com。