HBase原理解析(转)
生活随笔
收集整理的這篇文章主要介紹了
HBase原理解析(转)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文屬于轉載,原文鏈接:http://www.aboutyun.com/thread-7199-1-1.html 前提是大家至少了解HBase的基本需求和組件。
------------------------------------------------
|block? ?? ?? ?? ?? ?? ?? ?? ? |
|----------------------------------------------|
|block? ?? ?? ?? ?? ?? ?? ?? ? |
...
|??meta? ?? ?? ?? ?? ?? ?? ? |
|---------------------------------------------|
|block索引,以及一些key范圍信息|
|---------------------------------------------|
|布隆過濾? ?? ?? ?? ?? ?? ? |
----------------------------------------------- 可以粗略的認為 一個storefile的結構是這樣的,尾部的順序和細節記不太清楚了。一個block包括多個key value,key在文件內是有序的。一條key value記錄如下圖: <ignore_js_op>? ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 讀數據的時候我會發送一個get請求,在region server內部會轉為一個scan。他會到相關列族中去scan storefile。storefile的尾部包含block索引、布隆過濾器、更新時間等所以這可以加快需要scan的文件過濾。所以針對一個store file讀是這樣的:判斷get請求中的row key是否在文件保存的數據范圍內;判斷get請求中的row key是否能從布龍過濾器中找到(如果過濾器為row-col過濾器還可以判斷是否包括需要get的col);判斷get請求中的時間范圍 是否在文件保存的數據的時間范圍中;獲取對應的block index;把block加載到block cache中;然后scan block;從多個store file的結果中 get請求中需要包含的version個數,取前幾個從而滿足get請求中需要包含的version個數。get可以看做特殊的scan操作。
?
從大家最熟悉的客戶端發起請求開始講起吧,這樣大家能夠深有體會的逐步了解原理。比如我們發起了一條PUT請求,客戶端首先需要查找到需要響應請求的REGIONSERVER。 記錄region->regionserver映射是由HBASE系統表.META.記錄的。所以我們只要知道. META.表的位置就能知道每個region響應的key的范圍 和region所在機器。但是.META.表又保存在哪些機器上呢?這又是由-ROOT-表記錄的 master在分配完-ROOT-表后 會將-ROOT-表的位置放到ZOOKEEPER中。所以我們在配置客戶端的時候配置的是ZOOKEEPER的位置,而不是MASTER位置。?
為什么要分為-ROOT-和.META.呢?這是因為region信息本身很多 一個集群中可能會出現成千上萬的region 因此.META.表本身也無法在一個region中保存所有用戶region的信息,所以本身也會分裂。而.META.表的region數就比較有限了所以-ROOT-是不會分裂的.?
綜上,客戶端首次請求時,先拿-ROOT-然后通過請求范圍找對應的.META.,在.META.中找打具體的region server 然后發送請求。-ROOT-和.META.是可以緩存的。?
現在,我們解決了 客戶端應當把PUT發送到哪個rs的問題,接下來就要發送請求了。region server收到請求后會保存PUT數據。這就不得不說HBASE的數據模型了,HBASE使用的列式存儲,基本數據結構為LSMT log structure merge tree。簡略的思路描述是,將操作記錄在樹中的節點上然后適時的將節點合并從而使key的刪除修改能夠最終體現在一個節點上,讀取的時候會讀取帶有key相應操作的節點,返回最終key的值??梢钥吹絣smt是將隨機讀寫轉化為順序讀寫的數據結構,讀方面更適合掃庫那樣的順序讀取,不太適合隨機讀取。?
那么一個PUT請求時怎么和LSMT搭上關系的呢?首先region server接到請求時,先將操作(keyvalue 時間戳 操作類型)保存為HLog,然后在保存到memstore中,然后即可返回寫入成功的請求。其中memstore保存在內存中,寫滿后flush為hdfs文件。hlog是為了防止rs故障時,memstore數據必然丟失導致的數據丟失,在客戶端可以禁用hblog來加快寫入速度,但這是用數據不安全換來的。只要每次memstore刷入hdfs后,會判斷hdfs刷入的中最早的操作 然后由另外的線程根據此記錄刪除舊的HLog文件。?
接下來說說memstore寫滿時的處理。memstore寫滿(每個region的列族都有單獨的memstore對象但實際上共用一塊內存池)時,會將其中的操作分發到對應region的每個列族(store)做處理。然后store將這些操作序列保存為存儲文件(storefile)。?
從大體上粗略的看 region server這邊重要的實體結構是這樣:regionserver : region = 1 : n;region : store= 1 : n;store : storefile = 1 : n。對于每個列族的數據文件,實機上是一個LSMT的葉子節點,每個文件中保存的是最近的對于列族中key的操作。?
當一個列族中文件過多的時候,會觸發compact,也就是說的文件合并。HBase的compact分為兩種 minor和major:minor是小范圍內的合并文件,只合并部分。目的在于把小文件積累成大文件。因為沒有全量數據,所以對于一個key的刪除操作還是需要保留標記,無法物理刪除。majorcompact把列族中的所有文件合并為一個,目的在于使key的修改和刪除,最終在物理上生效。因為major compact操作的是此列族的全量數據,所以可以做物理刪除。但是也由于是全量數據,執行起來耗費時間也會比價長,所以hbase對major compact做了時間間隔限制。?
當store的store file集合中總文件長度太大時(超過配置的閾值),這個region會一分為二,也就是split。由于split是以region為單位的,所以有些列族因為其他列族過大也被連坐般的split。所以從這個流程粗略的看來 put會觸發flush,flush會觸發compact,compact會觸發split。當然這都是在多個線程中執行的,不會明顯的阻塞住客戶端請求。?
store file的大小和memstore大小有關系,一次flush會在一個列族里生成一個store file。所以memstore越大,產生大store file的機會也就越多。put不均勻時,有的列族里會有比較多的長度較小的store file,但是文件多了會觸發compact。小文件compact很快,所以不用擔心。 store file?------------------------------------------------
|block? ?? ?? ?? ?? ?? ?? ?? ? |
|----------------------------------------------|
|block? ?? ?? ?? ?? ?? ?? ?? ? |
...
|??meta? ?? ?? ?? ?? ?? ?? ? |
|---------------------------------------------|
|block索引,以及一些key范圍信息|
|---------------------------------------------|
|布隆過濾? ?? ?? ?? ?? ?? ? |
----------------------------------------------- 可以粗略的認為 一個storefile的結構是這樣的,尾部的順序和細節記不太清楚了。一個block包括多個key value,key在文件內是有序的。一條key value記錄如下圖: <ignore_js_op>? ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 讀數據的時候我會發送一個get請求,在region server內部會轉為一個scan。他會到相關列族中去scan storefile。storefile的尾部包含block索引、布隆過濾器、更新時間等所以這可以加快需要scan的文件過濾。所以針對一個store file讀是這樣的:判斷get請求中的row key是否在文件保存的數據范圍內;判斷get請求中的row key是否能從布龍過濾器中找到(如果過濾器為row-col過濾器還可以判斷是否包括需要get的col);判斷get請求中的時間范圍 是否在文件保存的數據的時間范圍中;獲取對應的block index;把block加載到block cache中;然后scan block;從多個store file的結果中 get請求中需要包含的version個數,取前幾個從而滿足get請求中需要包含的version個數。get可以看做特殊的scan操作。
?
總得blockcache大小是有限的,會有淘汰的.實際上blockcache對于scan來說更合適,因為scan一般是一個范圍的掃,block中的row key又是有序的,所以說順序讀會比隨機讀快。一般hbase比較難適應高并發的隨機讀,因為blockcache這個設計的本身,就不適合緩存隨機的row key:隨機讀的特點就是讀的key均勻散列,這樣會使讀操作,落在每個block上,導致讀的時候每個block先被加載到內存,然后很快因為其他的block持續加載進來而被淘汰出去,然后就這樣換來換去,反而更浪費時間。?
最后兩個比較重要的操作是open和close region。這兩個在容災和均衡中常用。?
先說close吧 正常close時會先flush memstore 然后通知master close結束。非正常關閉時,就來不及flush了。master會通過zk和region server之間的心跳這兩種途徑得知regionsever掛掉的情況。?
open 一般由master發起。master先找到包含region操作對應的HLog文件,然后挑選出region對應的操作放到region目錄中,然后命令某個region server open之。open時先重演HLog中記錄的操作,然后再加載region對應的store和store file。?
比較重要的原理就是這樣的了。原理清楚了的話,再分析起來代碼,就能有一個宏觀的了解了。轉載于:https://www.cnblogs.com/hubavyn/p/4617508.html
總結
以上是生活随笔為你收集整理的HBase原理解析(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【SSH三个框架】Hibernate第八
- 下一篇: 我要再接再力 学更多