【4.分佈式計算】hadoop-hbase/druid

hbase海量實時存儲(百萬/秒,數據庫千/秒),druid(萬億/秒)。hbase經常使用於海量數據直接存儲或分析後數據實時查詢等,druid常做爲流數據計算後實時查詢。本文將介紹兩者的架構/分佈式部署,存儲結構/格式,對比等。html

hbase

官方: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

架構

clipboard.png
CF——region(只有一個CF)s——多個stores——一個memstore+多個HFILEweb

  • HBase Master
    用於協調多個 Region Server,偵測各個 Region Server 之間的狀態,並平衡 Region Server 之間的負載。HBase Master 還有一個職責就是負責分配 Region 給 Region Server。
  • zk
    除了master的管理,元數據路由也放在zk中保證該HA,client先和zk通訊。
  • Region Server
    每個 Region Server 管理着不少個 Region。對於 HBase 來講,Region 是 HBase 並行化的基本單元。所以,數據也都存儲在 Region 中。
  • Region 分區(m_p基本單元)
    所能存儲的數據大小是有上限的,當達到該上限時(Threshold),Region 會進行分裂,數據也會分裂到多個 Region 中,這樣即可以提升數據的並行化,以及提升數據的容量。每一個server的region數量不易過多,緣由分區佔內存,每次滿每次都會刷新,map_reduce時數據量(100比較合適)見:http://hbase.apache.org/book....
  • Store/MemStore
    每一個 Region 包含着多個 Store 對象。每一個store是一個CF數據,每一個 Store 包含一個 MemStore,和一個或多個 HFile。
    MemStore 即是數據在內存中的實體,而且通常都是有序的。當數據向 Region 寫入的時候,會先寫入 MemStore。當 MemStore 中的數據須要向底層文件系統傾倒(Dump)時(例如 MemStore 中的數據體積到達 MemStore 配置的最大值),Store 便會建立 StoreFile.
  • 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)

高可用

  • master
    多副本,zk自動故障轉移
  • 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從新分配過程:數據庫

    clipboard.png

    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)並刪除編輯文件。
  • hfile
    hdfs的三副本等實現。

數據格式

基於列存儲
HBase 中建立表格時,就須要指定表格的 CF、Row-key 以及 Qulifier
Row-key 加上 CF 加上 Qulifier 再加上一個時間戳才能夠定位到一個單元格數據(Hbase 中每一個單元格默認有 3 個時間戳的版本數據)
列與行之間的轉化如圖:
clipboard.png
http://cloudepr.blogspot.com/...緩存

HFILE

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)服務器

  • HFile壓縮
    Gzip,LZO(低壓縮率高解壓速度)snappy(代替lzo),LZ4
    long keys(比數據長)/列多:前綴編碼FAST_DIFF
    值大:塊壓縮
    冷數據:GZIP,壓縮率高
    熱數據:snappy/lzo
  • hfile合併(指的minor合併,合併部分小的相鄰的,Major是同一個store中的合併成一個)
    ExploringCompaction:合併小文件到大文件
    DateTieredCompactionPolicy:時間戳分層,1.3後
    StripeCompactionPolicy:相似leveldb的兩層,Major Compaction只到level0。minor包含兩步:level0到level1的合併,level1按照ExploringCompaction合併
    https://juejin.im/post/5bfe97...

事務

  • 一個region中

  • 對行(一行或多行)加鎖,屏蔽對相同行的併發寫;
    獲取當前的 WriteNumber;
    提交修改到 WAL;
    提交修改到 Memstore(用前面獲取的 WriteNumber 標記修改的 KeyValues);
    提交事務,也就是把 ReadPoint 更新爲當前獲取的 WriteNumber;
    釋放行(一行或多行)鎖。
  • scan:
    打開 scanner;
    獲取當前的 ReadPoint;
    用獲取的 ReadPoint 過濾全部掃描到的 KeyValues(KeyValues 的 memstore timestamp > ReadPoint,只看 ReadPoint 以前的);(防止compact,delete讀不完整行)。
    關閉 scanner(scanner 由客戶端初始化)。
  • 順序保證:一個事務的提交會被推遲,直到先前的事務提交
  • 持久:刷內存或盤盤

與RDBMS對比

只用於數據量大的,HDFS 默認會將每個 Block 數據備份 3 分,硬件仍是比較多數據結構

clipboard.png

druid

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,查詢速度應該會受到影響。架構

架構:

clipboard.png

  • Coordinator web (ui管理羣集,下發元數據給zk,不直接交互)。
  • Overlord 控制數據提取工做負載的分配(middlermanage-overload-具體middlemanager),協調任務建立鎖。
  • broker 處理來自外部客戶端的查詢,從zk和獲取路由,段緩存,合併結果,歷史會在zk中註冊本身的段。
  • router 可選的,能夠將請求路由到Broker,Coordinator和Overlords。
  • 歷史
    存儲可查詢數據,coordinator經過在zk的load queue目錄下建立實例分配新的段給歷史,當歷史發現,先查本地緩存配置信息,沒有從zk下載元數據,包含deep storage調的位置和解壓方式,完成後通知zk修改段信息供查詢。下載數據放入內存
  • MiddleManager 運行任務。

外部依賴

  • Mysql(metadata storage)
    存儲Druid中的各類metadata(裏面的數據都是Druid自身建立和插入的),包含3張表:」druid_config」(一般是空的), 「druid_rules」(coordinator nodes使用的一些規則信息,好比哪一個segment從哪一個node去load)和「druid_segments」(存儲每一個segment的metadata信息);
  • Deep storage
    存儲segments,Druid目前已經支持本地磁盤,NFS掛載磁盤,HDFS,S3等。Deep Storage的數據有2個來源,一個是batch Ingestion, 另外一個是real-time nodes;
  • ZooKeeper
    被Druid用於管理當前cluster的狀態,好比記錄哪些segments從Real-time nodes移到了Historical nodes;

數據組織

datasources->chunck(按時間分區)->segment

clipboard.png

segment的數據生成過程

  • MiddleManager
  1. MiddleManager上建立
    若是是append模式,overload分配partition添加到現有段,覆蓋模式鎖定(時間間隔,chunck的範圍)建立一個新版本段。
    實時任務,可當即查詢該段,但未發佈
    在讀取過程當中會:
    轉爲列
    建立位圖索引
    壓縮
  2. 讀完寫入deep storage(多副本) =>發佈:寫入metadata stroage( schema of the segment, its size, and its location on deep storage)
    若是實時任務,等待歷史進程加載該段,不然當即退出
  • 對於core/historical的過程:
    協調器按期輪詢元數據存儲(默認狀況下,每1分鐘一次),用於新發布的段。
    當協調器找到已發佈和使用但不可用的段時,它會選擇歷史進程來加載該段並指示歷史記錄執行此操做。
    歷史記錄加載段並開始提供它。
    若是任務正在等待切換(發佈由his提供服務),則它將退出。

不支持單鍵更新
歷史數據根據時間分層,冷/熱
段能夠繼續分片和合並

查詢過程

1.broker識別數據再哪些Historicals和MiddleManagers,發送子查詢。
其中爲了減小查詢:
1).broker的purge修剪:找段
2).每段用索引,行過濾器找行(bitmap)
3).查詢所需列時,能夠在行之間跳過。見特性
2.處理後broker合併

特性

clipboard.png

  • Rollup會將採用其設定的聚合器進行聚合
  • 列三種類型:時間,列,統計
    1.時間戳和統計:變長整數編碼+LZ4壓縮的整數或浮點
    2.列:字典+列字典值+倒排索引
    1)將值(老是被視爲字符串)映射到整數ID的字典,
    2)列的值列表,使用1中的字典編碼,和
    3)對於列中的每一個不一樣值,一個位圖指示哪些行包含該值。倒排索引:posting list採用壓縮的bitmap位圖索引,BitMap支持Consice和Roaring兩種壓縮編碼方式

    clipboard.png
    圖中標識第一列的索引

  • 布爾查詢

    clipboard.png

    以這個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.

相關文章
相關標籤/搜索