存儲
HBase架構圖如下:
從圖中可以看到HBase主要處理兩種文件,WAL和實際的數據文件。這兩種文件最終都存在HDFS中。
首次請求所需的步驟如下:
- 從zk中取得
hbase:meta
表所在的節點,路徑爲/hbase/meta-region-server
。 - 從
hbase:meta
表中讀取元數據,根據元數據推測出數據所在的節點。 - 連接實際的數據節點取得數據。
其中步驟2的元數據會在客戶端進行緩存,下次不用查meta表。下面介紹meta表的結構。
meta表中的key格式爲[table],[region start key],[region id]
。筆者從實際運行的HBase實例中取了meta表中的一行數據,其key爲test,,1496321078922.cd9c09dcebc92b7f3c3d26008bee32a3.
,從這個key中可以知道table
是test
,region start key
是空白,region id
是1496321078922.cd9c09dcebc92b7f3c3d26008bee32a3.
。
meta表中的value格式有三個列:
info:regioninfo
:存放序列化的HRegionInfo
對象。筆者實際拿到一條數據內容爲:timestamp=1498052321524, value={ENCODED => cd9c09dcebc92b7f3c3d26008bee32a3, NAME => 'test,,1496321078922.cd9c09dcebc92b7f3c3d26008bee32a3.', STARTKEY => '', ENDKEY => ''}
從中可以看到STARTKEY
和ENDKEY
分別表示行鍵開始和結束的時間。info:server
:存放服務器地址和端口信息。筆者實際拿到一條數據內容爲:timestamp=1498052321524, value=cpc1:34979
。從中可以得出服務器主機名爲cpc1
,端口是34979。info:serverstartcode
:region所在的節點啓動時間,筆者拿到一條實際數據內容爲:timestamp=1498052321524, value=1498052313334
寫數據流程如下:
HRegionServer
收到來自客戶端的Put
請求HRegionServer
決定是否需要將數據寫到HLog
預寫日誌裏面。預寫日誌使用了標準的Hadoop Sequence File
,其中儲存了若干HLogKey
實例。每個HLogKey
中包含了序列號和實際數據。用於故障恢復。HRegionServer
將請求轉交給HRegion
,數據放到MemStore
中。如果檢查到MemStore
數據滿了,就觸發一次刷寫。刷寫由另外一個線程負責,刷寫的結果是將MemStore
中的內容放到新的HFile
中。並保存最後寫入的序列號。序列號用於故障恢復,可以給系統判斷從哪開始恢復。
另外關閉節點之前時也會觸發刷寫,刷寫的範圍是目前體積超過配置hbase.hregion.preclose.flush.size
的所有MemStore
。這樣設計是爲了提升可用性,因爲預刷寫時,服務仍然可用。預刷寫之後再阻塞所有請求,再進行一次刷寫,最後關閉region。
現在介紹文件儲存結構。默認配置下,HBase將文件儲存在HDFS中的/hbase
目錄中,可以通過配置修改儲存目錄。我們將/hbase
稱之爲HBase的根目錄,這個文件夾裏主要有如下文件:
.logs
目錄:用於存放WAL日誌。每個HRegionServer
都有一個對應的子目錄。目錄名字是實例編號,格式爲<host>,<port>,<timestamp>
。新版本中已經改名爲WALs
。.logs/<HRegionServer實例編號>
目錄:給單個節點存放HLog
文件。因爲日誌滾動,可能會有多個HLog
。.oldlogs
目錄:日誌文件用於意外停機恢復使用的,當WAL中的數據已經全部持久化到硬盤之後,日誌文件不再有用。從而移動到.oldlogs
文件夾中。最新版本中此名字已經改成oldWALs
。這裏的文件默認10分鐘後刪除。可以通過配置hbase.master.cleaner.interval
調整。hbase.id
:集羣的唯一IDhbase.version
:集羣的版本<表名>/.tableinfo
:存放序列化後的HTableDescriptor
對象<表名>/<region名MD5>/.regioninfo
:儲存序列化後的HRegionInfo
對象<表名>/<region名MD5>/.tmp
:儲存臨時文件<表名>/<region名MD5>/recovered.edits
:WAL拆分成功得到的文件放在這個目錄<表名>/<region名MD5>/recovered.edits/.temp
:WAL拆分過程中產生的臨時文件放在這個目錄