本套系列博客從真實商業環境抽取案例進行總結和分享,並給出Spark商業應用實戰指導,請持續關注本套博客。版權聲明:本套Spark商業應用實戰歸做者(秦凱新)全部,禁止轉載,歡迎學習。shell
Hbase適合存儲PB級別的海量數據,在PB級別的數據以及採用廉價PC存儲的狀況下,能在幾十到百毫秒內返回數據。這與Hbase的極易擴展性息息相關。正由於Hbase良好的擴展性,才爲海量數據的存儲提供了便利。根據Google的Chang等人發表的論文數據庫
Bigtable:A Distributed Storage System for Strctured Data
複製代碼
來設計的。整體架構以下:架構
2010年5月,Hbase從Hadoop子項目升級成Apache頂級項目。簡而言之:HBase是一個經過大量廉價的機器解決海量數據的高速存儲和讀取的分佈式數據庫解決方案。一圖歸納以下所示:併發
MemStore 實際上是一種內存結構,一個Column Family 對應一個MemStore 分佈式
第1步:client請求ZK得到-ROOT-所在的RegionServer地址高併發
第2步:client請求-ROOT-所在的RS地址,獲取.META.表的地址,client會將-ROOT-的相關信息cache下來,以便下一次快速訪問oop
第3步:client請求 .META.表的RS地址,獲取訪問數據所在RegionServer的地址,client會將.META.的相關信息cache下來,以便下一次快速訪問post
第4步:client請求訪問數據所在RegionServer的地址,獲取對應的數據性能
第1步:Client請求ZK獲取.META.所在的RegionServer的地址。學習
第2步:Client請求.META.所在的RegionServer獲取訪問數據所在的RegionServer地址,client會將.META.的相關信息cache下來,以便下一次快速訪問。
第3步:Client請求數據所在的RegionServer,獲取所須要的數據。
其一:提升性能
其二:2層結構已經足以知足集羣的需求
Compaction會從一個region的一個store中選擇一些hfile文件進行合併。合併說來原理很簡單,先從這些待合併的數據文件中讀出KeyValues,再按照由小到大排列後寫入一個新的文件中。以後,這個新生成的文件就會取代以前待合併的全部文件對外提供服務。HBase根據合併規模將Compaction分爲了兩類:MinorCompaction和MajorCompaction
Minor Compaction是指選取一些小的、相鄰的StoreFile將他們合併成一個更大的StoreFile,在這個過程當中不會處理已經Deleted或Expired的Cell。一次Minor Compaction的結果是更少而且更大的StoreFile。
Major Compaction是指將全部的StoreFile合併成一個StoreFile,這個過程還會清理三類無心義數據:被刪除的數據、TTL過時數據、版本號超過設定版本號的數據。另外,通常狀況下,Major Compaction時間會持續比較長,整個過程會消耗大量系統資源,對上層業務有比較大的影響。所以線上業務都會將關閉自動觸發Major Compaction功能,改成手動在業務低峯期觸發。
下列三個條件可能會觸發compaction請求:
memstore flush以後觸發;
客戶端經過shell或者API觸發;
後臺線程CompactionChecker按期觸發,週期爲:
hbase.server.thread.wakefrequency*hbase.server.compactchecker.interval.multiplier。
複製代碼
對於MajorCompact,觸發了compaction請求後,真正的compaction操做可否執行,還要進行一系列的條件驗證, 即由hbase.hregion.majorcompaction和hbase.hregion.majorcompaction.jitter控制的一組條件。
對於MiniCompact當文件大小小於hbase.hstore.compaction.min.size 則會當即被添加到合併隊列,當storeFile數量超過hbase.hstore.compaction.min時,minor compaction纔會啓動。
hbase.hregion.memstore.flush.size:640M
hbase.hregion.max.filesize :100M 觸發split
hbase.hstore.compaction.min : 知足條件 3 minor compaction纔會啓動
hbase.hstore.compaction.ratio :默認爲1.2
hbase.hregion.majorcompaction : 0 關掉major compact
hbase.hstore.compaction.max : 默認值爲10,表示一次minor compaction中最多選取10個store file
hbase.hstore.compaction.min : 默認值爲 3
hbase.hstore.compaction.min.size :640M (未壓縮?爲memestoreFlushSize)
複製代碼
hbase.hstore.compaction.ratio :默認爲1.2 ,將store file 按照文件年齡排序(older to younger),minor compaction老是從older store file開始選擇,若是該文件的size 小於它後面hbase.hstore.compaction.max 個store file size 之和乘以 該ratio,則該store file 也將加入到minor compaction 中。
hbase.hstore.blockingStoreFiles:HStore的storeFile的文件數大於配置值,則在flush memstore前先進行split或者compact,除非超過hbase.hstore.blockingWaitTime配置的時間,默認爲7,可調大,好比:100,避免memstore不及時flush,當寫入量大時,觸發memstore的block,從而阻塞寫操做。
hbase.hregion.max.filesize :默認值是256M 當hbase.hregion.max.filesize比較小時,觸發split的機率更大,而split的時候會將region offline,所以在split結束的時間前,訪問該region的請求將被block住,客戶端自我block的時間默認爲1s。當大量的region同時發生split時,系統的總體訪問服務將大受影響。所以容易出現吞吐量及響應時間的不穩定現象
hbase.hregion.max.filesize : 當hbase.hregion.max.filesize比較大時,單個region中觸發split的機率較小,大量region同時觸發split的機率也較小,所以吞吐量較之小hfile尺寸更加穩定些。可是因爲長期得不到split,所以同一個region內發生屢次compaction的機會增長了。compaction的原理是將原有數據讀一遍並重寫一遍到hdfs上,而後再刪除原有數據。無疑這種行爲會下降以io爲瓶頸的系統的速度,所以平均吞吐量會受到一些影響而降低
hbase.hregion.max.filesize 這個值過大,讀寫hbase的速度會變慢,由於底層對hdfs的讀寫操做因爲文件數量少,很難作到高併發,高吞吐,太小會發生頻繁的文件split,split過程會使數據短暫離線,會對數據的訪問有必定影響,不太穩定,因此這個值不能過小也不能太大,100-200MB基本能知足需求
基於文件大小進行合併
hbase.hstore.compaction.min.size 表示文件大小小於該值的store file 必定會加入到minor compaction的store file中
hbase.hstore.compaction.max.size Long.MAX_VALUE 表示文件大小大於該值的store file 必定會被minor compaction排除
複製代碼
基於文件數量進行合併
hbase.hstore.compaction.min :默認值爲 3,表示至少須要三個知足條件的store file時,minor compaction纔會啓動
hbase.hstore.compaction.max :默認值爲10,表示一次minor compaction中最多選取10個store file
複製代碼
hbase.hstore.blockingWaitTime block的等待時間 線上配置:90000(90s) 默認配置:90000(90s)
hbase.regionserver.global.memstore.upperLimit,默認爲整個heap內存的40%。但這並不意味着全局內存觸發的刷盤操做會將全部的MemStore都進行輸盤,而是經過另一個參數hbase.regionserver.global.memstore.lowerLimit來控制,默認是整個heap內存的35%。當flush到全部memstore佔整個heap內存的比率爲35%的時候,就中止刷盤。這麼作主要是爲了減小刷盤對業務帶來的影響,實現平滑系統負載的目的。
hbase.hregion.memstore.flush.size:當MemStore的大小達到hbase.hregion.memstore.flush.size大小的時候會觸發刷盤,默認128M大小。
hase.regionserver.max.logs :前面說到Hlog爲了保證Hbase數據的一致性,那麼若是Hlog太多的話,會致使故障恢復的時間太長,所以Hbase會對Hlog的最大個數作限制。當達到Hlog的最大個數的時候,會強制刷盤。這個參數是hase.regionserver.max.logs,默認是32個。
爲了本文的主題,此處參考了一篇很是好的博客,僅限該小節:https://blog.csdn.net/u014297175/article/details/50456147
複製代碼
注意:後面會不斷判斷進行Older to younger 的合併,可是這個154M的文件會歸入合併隊列,由於當文件大小小於
hbase.hstore.compaction.min.size(爲memestoreFlushSize) 則會當即被添加到合併隊列。
複製代碼
MajorCompact 條件:
一個reion達到必定的大小,他會自動split稱兩個region。若是咱們的Hbase版本是0.94 ,那麼默認的有三種自動split的策略,ConstantSizeRegionSplitPolicy,IncreasingToUpperBoundRegionSplitPolicy還有 KeyPrefixRegionSplitPolicy.
目前Hbase僅支持行級事務,不支持跨行跨表事務要求。
提供一個基於行的獨佔鎖來保證對同一行寫的獨立性,因此寫的順序是:
兩階段鎖協議:不是一行一行的得到鎖,批量寫多行場景,防止死鎖場景 兩階段鎖協議,過程以下:
經過事務序列來控制順序: 事務只有提交了纔會出列,經過指針(Read Point)指到底部已提交事務號,指針之下的用戶才能可見:
還須要進一步完善Major Compact的腳本控制邏輯
秦凱新 於深圳