hbase海量實時存儲(百萬/秒,數據庫千/秒),druid(萬億/秒)。hbase經常使用於海量數據直接存儲或分析後數據實時查詢等,druid常做爲流數據計算後實時查詢。本文將介紹兩者的架構/分佈式部署,存儲結構/格式,對比等。html
官方:Apache HBase™ is the Hadoop database, a distributed, scalable, big data store.
Use Apache HBase™ when you need random,realtime
read/write access to your Big Data. 硬件成本不高狀況下託管數十億行*百萬列。開發思路基於bigtable。文件系統基於hdfs(這部分分佈式相關的一致性可用性再也不說了)node
CF——region(只有一個CF)s——多個stores——一個memstore+多個HFILEweb
StoreFile/Hfile
而 StoreFile 就是對 HFile 一層封裝。因此 MemStore 中的數據會最終寫入到 HFile 中,也就是磁盤 IO。因爲 HBase 底層依靠 HDFS,所以 HFile 都存儲在 HDFS 之中。sql
Table (HBase table) Region (Regions for the table) Store (Store per ColumnFamily for each Region for the table)
region
通常的region server不可用,須要zk的發現-從新分配-恢復,期間該分區不可用,對於不能容忍的新版實現:region server多副本:https://hbase.apache.org/book...
region自動分片和region server自動故障轉移(master檢測後,從新分配region,更新zk的meta),WAL 保存在HDFS 的 /hbase/.logs/ 裏面,每一個region一個文件。
region server會在mem flush時把hfile壓縮爲更少,更大的文件,檢測該區域的hfile文件過大會自動拆分,
region從新分配過程:數據庫
1.RegionServer在本地決定拆分區域,並準備拆分。獲取共享讀鎖,以防止在拆分過程當中修改模式。zookeeper下建立一個znode /hbase/region-in-transition/region-name,並將znode的狀態設置爲SPLITTING。 2.Master watcher獲取 3.RegionServer建立一個在HDFS中.splits父region目錄下命名的子目錄。 4.RegionServer關閉父區域,並在其本地數據結構中將該區域標記爲脫機。該region離線。此時,將發送到父區域的客戶端請求NotServingRegionException。客戶端將重試。 5.RegionServer在目錄下.splits爲子區域A和B建立區域目錄,並建立必要的數據結構。而後分割存儲文件,建立兩個引用到父區域 6.RegionServer在HDFS中建立實際的區域目錄,並移動每一個子項的引用。 7.RegionServer向表發送Put請求.META.,將父級設置爲脫機,並添加有關子區域的信息。成功以後纔有單獨的條目,不然清理回滾 8.RegionServer並行打開A和B. 9.RegionServer將女兒A和B .META.以及它託管區域的信息添加到其中。分裂地區(帶有父母參考的孩子)如今在線。在此以後,客戶能夠發現新區域並向其發出請求。客戶端在.META.本地緩存條目,可是當它們向RegionServer發出請求時.META.,它們的緩存將失效,而且它們將從中瞭解新區域.META.。 10.RegionServer將/hbase/region-in-transition/region-nameZooKeeper中的znode更新爲state SPLIT,以便master能夠了解它。若有必要,平衡器能夠自由地將子區域從新分配給其餘區域服務器。分裂交易現已完成。 11.拆分後,.META.HDFS仍將包含對父區域的引用。當子區域中的壓縮重寫數據文件時,將刪除這些引用。主服務器中的垃圾收集任務會按期檢查子區域是否仍然引用父區域的文件。若是不是,則將刪除父區域。
WAL
一個region server一個WAL(串行寫入HDFS瓶頸,multiwal在底層HDFS中使用多個管道並行寫入,按區域劃分你傳入,不研究了)
打開某個區域時,須要重播屬於該區域的WAL文件中的編輯。所以,WAL文件中的編輯必須按區域分組,以即可以重放特定的集合以從新生成特定區域中的數據。按區域對WAL編輯進行分組的過程稱爲日誌分割。
舊的日誌切割任務由hmaster完成並由zk協調,region server多時壓力大=》改成每一個region server執行apache
1.重命名WAL / HBase的/ WALS / <主機>,<端口>,<起始碼> -splittin 2.日誌分割器一次一個讀取日誌文件,放入region緩存中,啓動多個寫線程,每一個讀region緩存到臨時文件/hbase/<table_name>/<region_id>/recovered.edits/.temp。分割後.temp文件重命名爲sequennce id做爲第一個。 3.日誌拆分完成後,每一個受影響的區域都將分配給RegionServer。 當區域被打開,recovered.edits文件夾中檢查恢復的編輯文件。若是存在任何此類文件,則經過閱讀編輯並將其保存到MemStore來重放它們。重放全部編輯文件後,MemStore的內容將寫入磁盤(HFile)並刪除編輯文件。
基於列存儲
HBase 中建立表格時,就須要指定表格的 CF、Row-key 以及 Qulifier
Row-key 加上 CF 加上 Qulifier 再加上一個時間戳才能夠定位到一個單元格數據(Hbase 中每一個單元格默認有 3 個時間戳的版本數據)
列與行之間的轉化如圖:
http://cloudepr.blogspot.com/...緩存
HFILE相似Google’s SSTable,不分層
內存佔用:key不宜過大(全部index放內存key長度*n),1G佔用1.2M(15600 (1GB/64KB)*(64+))
The trailer, file-info and total data block indexes (optionally, may add meta block indexes)服務器
只用於數據量大的,HDFS 默認會將每個 Block 數據備份 3 分,硬件仍是比較多數據結構
Druid的重點是極低延遲查詢,Druid徹底索引全部數據。
高性能,亞秒響應的交互式查詢(萬億行數據集上執行 query,響應時間小於1秒);可擴展性,採用分佈式shared-nothing的架構,能夠擴展到PB級;支持聚合函數,count和sum,近似查詢的Aggregator。只支持流失插入,不支持流失更新,不支持大表join。適用於插入高更新少,有時間,列式聚合和報告等。較低的成本(比ES在聚合的成本低)
關鍵點:列存儲,倒排索引,Roll UP,roaring 或者concise bitmap位圖索引以及高效的壓縮支撐了Druid的高效查詢
常做用與spark之上。
官方:http://druid.io/docs/latest/d...
爲每一個定向類別(包括日期)建立一個單獨的column family,Hbase受限於rowkey設計,不能很好地解決多維分析。另外Hbase自己沒有爲column family建立bitmap indexing,查詢速度應該會受到影響。架構
外部依賴
datasources->chunck(按時間分區)->segment
segment的數據生成過程
不支持單鍵更新
歷史數據根據時間分層,冷/熱
段能夠繼續分片和合並
1.broker識別數據再哪些Historicals和MiddleManagers,發送子查詢。
其中爲了減小查詢:
1).broker的purge修剪:找段
2).每段用索引,行過濾器找行(bitmap)
3).查詢所需列時,能夠在行之間跳過。見特性
2.處理後broker合併
圖中標識第一列的索引
以這個SQL查詢爲例,select sum(click) from table where time between 2016-05-24T11 and 2016-05-24T12 and廣告=C2 and 地域=P1;首先根據時間段定位到Segment,而後根據廣告=C2和地域=P1,獲得 他們各自的字典編碼,C2=1,P1=0,而後根據字典編碼獲得BitMap的Offet,從而獲得Bitmap,C2=1 index爲1的bitmap爲0110,同理獲得P1的bitmap爲1100,0110和1100進行And與運算是0100,獲得的offset是1,說明咱們須要在click中讀取offset=1的值是4.