dd by zhj: 最近的工做須要跟HBase打交道,因此花時間把《HBase權威指南》粗略看了一遍,感受不過癮,又從網上找了幾篇經典文章。數據庫
下面這篇就是很經典的文章,對HBase的架構進行了比較詳細的描述。我本身也進行了簡單的總結,簡單的說,HBase使用的是LSM(緩存
Log-Structured Merge tree)--日誌結構的合併樹作爲存儲方式,這種存儲方式是不少NoSQL數據庫都在使用的,它的主要特色是:安全
1. 寫:徹底的內存操做,速度很是快。具體來講,是寫入WAL(write ahead log)日誌和MemStore內存,完成後給客戶端響應。服務器
WAL至關於MySQL的binlog。當MemStore達到必定大小後,將其flush到磁盤。網絡
2. 讀:將磁盤中的數據與MemStore中的數據進行合併後架構
與B+樹相比,LSM提升了寫入性能,並且讀取性能並無減低多少負載均衡
HBase由三個部分,以下分佈式
1. HMasteroop
對Region進行負載均衡,分配到合適的HRegionServer性能
2. ZooKeeper
選舉HMaster,對HMaster,HRegionServer進行心跳檢測(貌似是這些機器節點向ZooKeeper上報心跳)
3. HRegionServer
數據庫的分片,HRegionServer上的組成部分以下
Region:HBase中的數據都是按row-key進行排序的,對這些按row-key排序的數據進行水平切分,每一片稱爲一個Region,它有startkey和endkey,Region的大小能夠配置,一臺RegionServer中能夠放多個Region
CF:列族。一個列族中的全部列存儲在相同的HFile文件中
HFile:HFile就是Hadoop磁盤文件,一個列族中的數據保存在一個或多個HFile中,這些HFile是對列族的數據進行水平切分後獲得的。
MemStore:HFile在內存中的體現。當咱們update/delete/create時,會先寫MemStore,寫完後就給客戶端response了,當Memstore達到必定大
小後,會將其寫入磁盤,保存爲一個新的HFile。HBase後臺會對多個HFile文件進行merge,合併成一個大的HFile
英文:https://mapr.com/blog/in-depth-look-hbase-architecture/#.VdMxvWSqqko
譯文:https://my.oschina.net/u/1416978/blog/716926
Hadoop DataNode存儲着Region Server 管理的數據,全部的Hbase數據存儲在HDFS文件系統中,Region Servers在HDFS DataNode中是可配置的,並使數據存儲靠近在它所須要的地方,就近服務,當王HBASE寫數據時時Local的,可是當一個region 被移動以後,Hbase的數據就不是Local的,除非作了壓縮(compaction)操做。NameNode維護物理數據塊的元數據信息。
HBase Tables 經過行健的範圍(row key range)被水平切分紅多個Region, 一個Region包含了全部的,在Region開始鍵和結束以內的行,Regions被分配到集羣的節點上,成爲 Region Servers,提供數據的讀寫服務,一個region server能夠服務1000 個Region。
分配Region,DDL操做(建立表, 刪除表)
協調各個Reion Server :
-在啓動時分配Region、在恢復或是負載均衡時從新分配Region。
-監控全部集羣當中的Region Server實例,從ZooKeeper中監聽通知。
管理功能:
-提供建立、刪除、更新表的接口。
Hbase使用Zookeeper做爲分佈式協調服務,來維護集羣中的Server狀態,ZooKeeper維護着哪些Server是活躍或是可用的。提供Server 失敗時的通知。Zookeeper使用一致性機制來保證公共的共享狀態,注意,須要使用奇數的三臺或是五臺機器,保證一致。
Zookeeper通常在分佈式系統中的成員之間協調共享的狀態信息,Region Server和活躍的HMaster經過會話鏈接到Zookeeper,ZooKeeper維護短暫的階段,經過心跳機制用於活躍的會話。
每一個Region Server建立一個短暫的節點,HMaster監控這些節點發現可用的Region Server,同時HMaster 也監控這些節點的服務器故障。HMaster 經過撞見一個臨時的節點,Zookeeper決定其中一個HMaster做爲活躍的。活躍的HMaster 給ZooKeeper發送心跳信息,不活躍的HMaster在活躍的HMaster出現故障時,接受通知。
若是一個Region Server或是一個活躍的HMaster在發送心跳信息時失敗或是出現了故障,則會話過時,相應的臨時節點將被刪除,監聽器將因這些刪除的節點更新通知信息,活躍的HMaster將監聽Region Server,而且將會恢復出現故障的Region Server,不活躍的HMaster 監聽活躍的HMaster故障,若是一個活躍的HMaster出現故障,則不活躍的HMaster將會變得活躍。
有一個特殊的Hbase 目錄表叫作Meta表,它擁有Region 在集羣中的位置信息,ZooKeeper存儲着Meta表的位置。
以下就是客戶端首次讀寫Hbase 所發生的事情:
1.客戶端從Zookeeper的Meta表中獲取Region Server。
2.客戶端將查詢 .META.服務器,獲取它想訪問的相對應的Region Server的行健。客戶端將緩存這些信息以及META 表的位置。
3.護額端將從相應的Region Server獲取行。
若是再次讀取,客戶端將使用緩存來獲取META 的位置及以前的行健。這樣時間久了,客戶端不須要查詢META表,除非Region 移動所致使的丟失,這樣的話,則將會從新查詢更新緩存。
META 表集羣中全部Region的列表
.META. 表像是一個B樹
.META. 表結構爲:
- Key: region start key,region id
- Values: RegionServer
Region Server 運行在HDFS DataNode上,並有以下組件:
WAL:Write Ahead Log 提早寫日誌是一個分佈式文件系統上的文件,WAL存儲沒有持久化的新數據,用於故障恢復,相似Oracle 的Redo Log。
BlockCache:讀緩存,它把頻繁讀取的數據放入內存中,採用LRU
MemStore:寫緩存,存儲來沒有來得及寫入磁盤的新數據,每個region的每個列族有一個MemStore
Hfiles :存儲行,做爲鍵值對,在硬盤上。
Hbase 寫步驟1:
當客戶端提交一個Put 請求,第一步是把數據寫入WAL:
-編輯到在磁盤上的WAL的文件,添加到WAL文件的末尾
-WAL用於宕機恢復
Hbase 寫步驟2
一旦數據寫入WAL,將會把它放到MemStore裏,而後將返回一個ACk給客戶端
MemStore 存儲以鍵值對的方式更新內存,和存儲在HFile是同樣的。每個列族就有一個MemStore ,以每一個列族順序的更新。
當MemStore 積累到足夠的數據,則整個排序後的集合被寫到HDFS的新的HFile中,每一個列族使用多個HFiles,列族包含真實的單元格,或者是鍵值對的實例,隨着KeyValue鍵值對在MemStores中編輯排序後,做爲文件刷新到磁盤上。
注意列族是有數量限制的,每個列族有一個MemStore,當MemStore滿了,則進行刷新。它也會保持最後一次寫的序列號,這讓系統知道直到如今都有什麼已經被持久化了。
最高的序列號做爲一個meta field 存儲在HFile中,來顯示持久化在哪裏結束,在哪裏繼續。當一個region 啓動後,讀取序列號,最高的則做爲新編輯的序列號。
數據存儲在HFile,HFile 存儲鍵值,當MemStore 積累到足夠的數據,整個排序的鍵值集合會寫入到HDFS中新的HFile 中。這是一個順序的寫,很是快,能避免移動磁頭。
HFile 包含一個多層的索引,這樣沒必要讀取整個文件就能查找到數據,多層索引像一個B+樹。
trailer (追蹤器)指向 meta的塊,並在持久化到文件的最後時被寫入。trailer 擁有 bloom過濾器的信息以及時間範圍(time range)的信息。Bloom 過濾器幫助跳過那些不含行健的文件,時間範圍(time range)則跳過那些不包含在時間範圍內的文件。
索引是在HFile 打開並放入內存中時被加載的,這容許在單個磁盤上執行查找。
一個行的鍵值單元格能夠被存儲在不少地方,行單元格已經被存儲到HFile中、在MemStore最近被更新的單元格、在Block cache最佳被讀取的單元格,因此當你讀取一行數據時,系統怎麼能把相對應的單元格內容返回呢?一次讀把block cache, MemStore, and HFiles中的鍵值合併的步驟以下:
每一個MemStore有許多HFiles 文件,這樣對一個讀取操做來講,多個文件將不得不被屢次檢查,勢必會影響性能,這種現象叫作讀放大(read amplification)。
HBase將會自動把小HFiles 文件重寫爲大的HFiles 文件,這個過程叫作minor compaction。
輔助壓縮減小文件的數量,並執行合併排序。
主壓縮將會合並和重寫一個region 的全部HFile 文件,根據每一個列族寫一個HFile 文件,並在這個過程當中,刪除deleted 和expired 的單元格,這將提升讀性能。
然而由於主壓縮重寫了全部的文件,這個過程當中將會致使大量的磁盤IO操做以及網絡擁堵。咱們把這個過程叫作寫放大(write amplification)。
初始時一個table在一個region 中,當一個region 變大以後,將會被分裂爲2個子region,每一個子Region 表明一半的原始Region,在一個相同的 Region server中並行打開。
而後把分裂報告給HMaster。由於須要負載均衡的緣故,HMaster 可能會調度新的Region移動到其餘的Server上。
分裂一開始發生在相同的region server上,可是因爲負載均衡的緣由。HMaster 可能會調度新的Region被移動到其餘的服務器上。
致使的結果是新的Region Server 提供數據的服務須要讀取遠端的HDFS 節點。直到主壓縮把數據文件移動到Regions server本地節點上,Hbase數據當寫入時是本地的,
可是當一個region 移動(諸如負載均衡或是恢復操做等),它將不會是本地的,直到作了主壓縮的操做(major compaction.)
HDFS數據複製
全部的讀寫操做發生在主節點上,HDFS 複製WAL和HFile 塊,HFile複製是自動發生的,HBase 依賴HDFS提供數據的安全,
當數據寫入HDFS,本地化地寫入一個拷貝,而後複製到第二個節點,而後複製到第三個節點。
WAL 文件和 HFile文件經過磁盤和複製進行持久化,那麼HBase怎麼恢復還沒來得及進行持久化到HFile中的MemStore更新呢?
HBase 故障恢復
當一個RegionServer 掛掉了,壞掉的Region 不可用直到發現和恢復的步驟發生。Zookeeper 決定節點的失敗,而後失去region server的心跳。
而後HMaster 將會被通知Region Server已經掛掉了。
當HMaster檢查到region server已經掛掉後,HMaster 將會把故障Server上的Region重寫分配到活躍的Region servers上。
爲了恢復宕掉的region server,memstore 將不會刷新到磁盤上,HMaster 分裂屬於region server 的WAL 到單獨的文件,
而後存儲到新的region servers的數據節點上,每一個Region Server從單獨的分裂的WAL回放WAL。來重建壞掉的Region的MemStore。
數據恢復
WAL 文件包含編輯列表,一個編輯表明一個單獨的put 、delete.Edits 是按時間的先後順序排列地寫入,爲了持久化,增長的文件將會Append到WAL 文件的末尾。
當數據在內存中而沒有持久化到磁盤上時失敗了將會發生什麼?經過讀取WAL將WAL 文件回放,
添加和排序包含的edits到當前的MemStore,最後MemStore 刷新將改變寫入到HFile中。
強一致模型:當寫操做返回時,全部的讀將看到同樣的結果
自動擴展:Regions 隨着數據變大將分裂;使用HDFS傳播和複製數據
內建的恢復機制:使用WAL
和Hadoop的集成:直接使用mapreduce
WAL回放較慢
故障恢復較慢
主壓縮致使IO瓶頸。