Druid入門---時序資料庫
1.什麼是Druid?
Druid是一個高效的資料查詢系統,主要解決的是對於大量的基於時序的資料進行聚合查詢。資料可以實時攝入,進入到Druid後立即可查,同時資料是幾乎是不可變。通常是基於時序的事實事件,事實發生後進入Druid,外部系統就可以對該事實進行查詢。 Druid採用的架構: shared-nothing架構與lambda架構 Druid設計三個原則: 1.快速查詢(Fast Query) : 部分資料聚合(Partial Aggregate) + 記憶體華(In-Memory) + 索引(Index) 2.水平拓展能力(Horizontal Scalability):分散式資料(Distributed data)+並行化查詢(Parallelizable Query) 3.實時分析(Realtime Analytics):Immutable Past , Append-Only Future
2.Druid的技術特點
資料吞吐量大 支援流式資料攝入和實時 查詢靈活且快速
3.Druid基本概念:
Druid在資料攝入之前,首先要定義一個數據源(DataSource,類似於資料庫中表的概念) Druid是一個分散式資料分析平臺,也是一個時序資料庫 1.資料格式 資料集合(時間列,維度列,指標列) 資料結構: 基於DataSource與Segment的資料結構,DataSource相當於關係型資料庫中的表。 DataSource包含: 時間列(TimeStamp):標識每行資料的時間值 維度列(Dimension):標識資料行的各個類別資訊 指標列(Metric):用於聚合和計算的列
2.資料攝入 實時資料攝入 批處理資料攝入
3.資料查詢 原生查詢,採用JSON格式,通過http傳送
4.時序資料庫
1.OpenTSDB 開源的時序資料庫,支援數千億的資料點,並提供精確的資料查詢功能 採用java編寫,通過基於Hbase的儲存實現橫向拓展 設計思路:利用Hbase的key儲存一些tag資訊,將同一小時的資料放在一行儲存,提高了查詢速度 架構示意圖: 2.Pinot 接近Druid的系統 Pinot也採用了Lambda架構,將實時流和批處理資料分開處理 Realtime Node處理實時資料查詢 Historical Node處理歷史資料 技術特點:
叢集還依賴三類外部依賴 元資料庫(Metastore):儲存Druid叢集的原資料資訊,比如Segment的相關資訊,一般用MySql或PostgreSQL 分散式協調服務(Coordination):為Druid叢集提供一致性協調服務的元件,通常為Zookeeper 資料檔案儲存系統(DeepStorage):存放生成的Segment檔案,並供歷史節點下載。對於單節點叢集可以是本地磁碟,而對於分散式叢集一般是HDFS或NFS
實時節點資料塊的生成示意圖:
資料塊的流向: Realtime Node 實時節點: 1.通過Firehose來消費實時資料,Firehose是Druid中消費實時資料的模型 2.實時節點會通過一個用於生成Segment資料檔案的模組Plumber(具體實現有RealtimePlumber等)按照指定的週期,按時將本週起生產的所有資料塊合併成一個大的Segment檔案
Historical Node歷史節點 歷史節點在啟動的時候 : 1、會去檢查自己本地快取中已經存在的Segment資料檔案 2、從DeepStorege中下載屬於自己但是目前不在自己本地磁碟上的Segment資料檔案 無論何種查詢,歷史節點會首先將相關Segment資料檔案從磁碟載入到記憶體,然後在提供查詢
Broker Node節點: Druid提供兩類介質作為Cache以供選擇 外部Cache,比如Memcached 本地Cache,比如查詢節點或歷史節點的記憶體作為cache
高可用性: 通過Nginx來負載均衡查詢節點(Broker Node)
協調節點: 協調節點(Coordinator Node)負責歷史節點的資料負載均衡,以及通過規則管理資料的生命週期
4.索引服務 1.其中主節點:overlord 兩種執行模式: 本地模式(Local Mode):預設模式,主節點負責叢集的任務協調分配工作,也能夠負責啟動一些苦工(Peon)來完成一部分具體任務 遠端模式(Remote):該模式下,主節點與從節點執行在不同的節點上,它僅負責叢集的任務協調分配工作,不負責完成具體的任務,主節點提供RESTful的訪問方法,因此客戶端可以通過HTTP POST 請求向主節點提交任務。 命令格式如下: http://<ioverlord_ip>:port/druid/indexer/v1/task 刪除任務:http://<ioverlord_ip>:port/druid/indexer/v1/task/{taskId}/shutdown 控制檯:http://<ioverlord_ip>:port/console.html
2.從節點:Middle Manager 索引服務的工作節點,負責接收主節點的分配的任務,然後啟動相關的苦工即獨立的JVM來完成具體的任務 這樣的架構與Hadoop YARN相似 主節點相當於Yarn的ResourceManager,負責叢集資源管理,與任務分配 從節點相當於Yarn的NodeManager,負責管理獨立節點的資源並接受任務 Peon(苦工)相當於Yarn的Container,啟動在具體節點上負責具體任務的執行
問題:
由於老版本的Druid使用pull方式消費kafka資料,使用kafka consumer group來共同消費一個kafka topic的資料,各個節點會負責獨立消費一個或多個該topic所包含的Partition資料,並保證同一個Partition不會被多於一個的實時節點消費。每當一個實時節點完成部分資料的消費後,會主動將消費進度(kafka topic offset)提交到Zookeeper叢集。 當節點不可用時,該kafka consumer group 會立即在組內對所有可用的節點進行partition重新分配,接著所有節點將會根據記錄在zk叢集中每一個partition的offset來繼續消費未曾消費的資料,從而保證所有資料在任何時候都會被Druid叢集至少消費一次。 這樣雖然能保證不可用節點未消費的partition會被其餘工作的節點消費掉,但是不可用節點上已經消費的資料,尚未被傳送到DeepStoreage上且未被歷史節點下載的Segment資料卻會被叢集遺漏,這是基於kafka-eight Firehose消費方式的一種缺陷。 解決方案: 1.讓不可用節點恢復重新回到叢集成為可用節點,重啟後會將之前已經生成但未上傳的Segment資料檔案統統載入回來,並最終合併傳送到DeepStoreage,保證資料完整性 2.使用Tranquility與Indexing Service,對kafka的資料進行精確的消費與備份。 由於Tranquility可以通過push的方式將指定資料推向Druid叢集,因此它可以同時對同一個partition製造多個副本。所以當某個資料消費失敗時候,系統依然可以準確的選擇使用另外一個相同的任務所建立的Segment資料庫