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. HMaster
對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
一.Hbase 架構的組件
- Region Server:提供數據的讀寫服務,當客戶端訪問數據時,直接和Region Server通信。
- HBase Master:Region的分配,.DDL操作(創建表,刪除表)
- Zookeeper:是HDFS的一部分,維護一個活躍的集群狀態
Hadoop DataNode存儲着Region Server 管理的數據,所有的Hbase數據存儲在HDFS文件系統中,Region Servers在HDFS DataNode中是可配置的,並使數據存儲靠近在它所需要的地方,就近服務,當王HBASE寫數據時時Local的,但是當一個region 被移動之后,Hbase的數據就不是Local的,除非做了壓縮(compaction)操作。NameNode維護物理數據塊的元數據信息。

二.Regions
HBase Tables 通過行健的范圍(row key range)被水平切分成多個Region, 一個Region包含了所有的,在Region開始鍵和結束之內的行,Regions被分配到集群的節點上,成為 Region Servers,提供數據的讀寫服務,一個region server可以服務1000 個Region。

三.HBase HMaster
分配Region,DDL操作(創建表, 刪除表)
協調各個Reion Server :
-在啟動時分配Region、在恢復或是負載均衡時重新分配Region。
-監控所有集群當中的Region Server實例,從ZooKeeper中監聽通知。
管理功能:
-提供創建、刪除、更新表的接口。

四.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 的首次讀與寫
有一個特殊的Hbase 目錄表叫做Meta表,它擁有Region 在集群中的位置信息,ZooKeeper存儲着Meta表的位置。
如下就是客戶端首次讀寫Hbase 所發生的事情:
1.客戶端從Zookeeper的Meta表中獲取Region Server。
2.客戶端將查詢 .META.服務器,獲取它想訪問的相對應的Region Server的行健。客戶端將緩存這些信息以及META 表的位置。
3.護額端將從相應的Region Server獲取行。
如果再次讀取,客戶端將使用緩存來獲取META 的位置及之前的行健。這樣時間久了,客戶端不需要查詢META表,除非Region 移動所導致的丟失,這樣的話,則將會重新查詢更新緩存。

七 Hbase META表
META 表集群中所有Region的列表
.META. 表像是一個B樹
.META. 表結構為:
- Key: region start key,region id
- Values: RegionServer

八 Region Server 的組件
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
MemStore 存儲以鍵值對的方式更新內存,和存儲在HFile是一樣的。每一個列族就有一個MemStore ,以每個列族順序的更新。

HBase Region 刷新(Flush)
當MemStore 積累到足夠的數據,則整個排序后的集合被寫到HDFS的新的HFile中,每個列族使用多個HFiles,列族包含真實的單元格,或者是鍵值對的實例,隨着KeyValue鍵值對在MemStores中編輯排序后,作為文件刷新到磁盤上。
注意列族是有數量限制的,每一個列族有一個MemStore,當MemStore滿了,則進行刷新。它也會保持最后一次寫的序列號,這讓系統知道直到現在都有什么已經被持久化了。
最高的序列號作為一個meta field 存儲在HFile中,來顯示持久化在哪里結束,在哪里繼續。當一個region 啟動后,讀取序列號,最高的則作為新編輯的序列號。

HBase HFile
數據存儲在HFile,HFile 存儲鍵值,當MemStore 積累到足夠的數據,整個排序的鍵值集合會寫入到HDFS中新的HFile 中。這是一個順序的寫,非常快,能避免移動磁頭。

HFile 的結構
HFile 包含一個多層的索引,這樣不必讀取整個文件就能查找到數據,多層索引像一個B+樹。
- 鍵值對以升序存儲
- 在64K的塊中,索引通過行健指向鍵值對的數據。
- 每個塊有自己的葉子索引
- 每個塊的最后的鍵被放入到一個中間索引中。
- 根索引指向中間索引。
trailer (追蹤器)指向 meta的塊,並在持久化到文件的最后時被寫入。trailer 擁有 bloom過濾器的信息以及時間范圍(time range)的信息。Bloom 過濾器幫助跳過那些不含行健的文件,時間范圍(time range)則跳過那些不包含在時間范圍內的文件。

HFile Index
索引是在HFile 打開並放入內存中時被加載的,這允許在單個磁盤上執行查找。

HBase 讀合並
一個行的鍵值單元格可以被存儲在很多地方,行單元格已經被存儲到HFile中、在MemStore最近被更新的單元格、在Block cache最佳被讀取的單元格,所以當你讀取一行數據時,系統怎么能把相對應的單元格內容返回呢?一次讀把block cache, MemStore, and HFiles中的鍵值合並的步驟如下:
- 首先,掃描器(scanner )在讀緩存的Block cache尋找行單元格,最近讀取的鍵值緩存在Block cache中,當內存需要時剛使用過的(Least Recently Used )將會被丟棄。
- 接下來,掃描器(scanner)將在MemStore中查找,以及在內存中最近被寫入的寫緩存。
- 如果掃描器(scanner)在MemStore 和Block Cache沒有找到所有的數據,則HBase 將使用 Block Cache的索引以及bloom過濾器把含有目標的行單元格所在的HFiles 加載到內存中。

每個MemStore有許多HFiles 文件,這樣對一個讀取操作來說,多個文件將不得不被多次檢查,勢必會影響性能,這種現象叫做讀放大(read amplification)。

HBase 輔壓縮(minor compaction)
HBase將會自動把小HFiles 文件重寫為大的HFiles 文件,這個過程叫做minor compaction。
輔助壓縮減少文件的數量,並執行合並排序。

HBase 主壓縮(Major Compaction)
主壓縮將會合並和重寫一個region 的所有HFile 文件,根據每個列族寫一個HFile 文件,並在這個過程中,刪除deleted 和expired 的單元格,這將提高讀性能。
然而因為主壓縮重寫了所有的文件,這個過程中將會導致大量的磁盤IO操作以及網絡擁堵。我們把這個過程叫做寫放大(write amplification)。

Region = 臨近的鍵
- 一個表將被水平分割為一個或多個Region,一個Region包含相鄰的起始鍵和結束鍵之間的行的排序后的區域。
- 每個region默認1GB
- 一個region的表通過Region Server 向客戶端提供服務
- 一個region server可以服務1000 個region

Region 分裂
初始時一個table在一個region 中,當一個region 變大之后,將會被分裂為2個子region,每個子Region 代表一半的原始Region,在一個相同的 Region server中並行打開。
然后把分裂報告給HMaster。因為需要負載均衡的緣故,HMaster 可能會調度新的Region移動到其他的Server上。

讀負載均衡(Read Load Balancing)
分裂一開始發生在相同的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中。

九 HBase架構的優點
強一致模型:當寫操作返回時,所有的讀將看到一樣的結果
自動擴展:Regions 隨着數據變大將分裂;使用HDFS傳播和復制數據
內建的恢復機制:使用WAL
和Hadoop的集成:直接使用mapreduce
十 HBase架構的缺點
WAL回放較慢
故障恢復較慢
主壓縮導致IO瓶頸。
