hbase的讀寫過程:
hbase的架構:
Hbase真實數據
hbase真實數據存儲在hdfs上,通過配置文件的hbase.rootdir屬性可知,文件在/user/hbase/下
hdfs dfs -ls /user/hbase
Found 8 items
drwxr-xr-x - root supergroup 0 2019-05-30 10:05 /user/hbase/.tmp
drwxr-xr-x - root supergroup 0 2019-05-30 11:11 /user/hbase/MasterProcWALs
drwxr-xr-x - root supergroup 0 2019-05-30 10:05 /user/hbase/WALs
drwxr-xr-x - root supergroup 0 2019-05-27 18:49 /user/hbase/archive
drwxr-xr-x - root supergroup 0 2019-05-27 18:11 /user/hbase/data
-rw-r--r-- 3 root supergroup 42 2019-05-27 14:33 /user/hbase/hbase.id
-rw-r--r-- 3 root supergroup 7 2019-05-27 14:33 /user/hbase/hbase.version
drwxr-xr-x - root supergroup 0 2019-05-30 11:16 /user/hbase/oldWALs
.tmp
當對表做創建或者刪除操作的時候,會將表move 到該 tmp 目錄下,然后再去做處理操作。
MasterProcWALS
記錄創建表等DDL操作時的一些事務信息,用於處理如 HMaster 中斷導致的 DDL 無法執行、回滾等問題
WALS
屬於hbase的預寫日志(write-ahead-logs),記錄Hbase在數據寫入時候的數據信息。數據寫入過程中是先寫入到WAL中,再寫入到memstore。當發生 RegionServer 宕機重啟后,RS 會讀取 HDFS中的 WAL 進行 REPLAY 回放從而實現故障恢復。從數據安全的角度,建議開啟 WAL
archive
HBase 在做 Split或者 compact 操作完成之后,會將 HFile 先移到archive 目錄中,然后將之前的hfile刪除掉,該目錄由 HMaster 上的一個定時任務定期去清理。
data
真實數據文件HFile,HFile是通過memestore刷下來的.
hbase.id
序列化文件,標識hbase集群的唯一id號,是一個 uuid。
hbase.version
序列化文件,標識hbase集群的版本號。
oldWALs
存放舊的被回收的WAL文件
命名空間目錄
hdfs dfs -ls /user/hbase/data
Found 2 items
drwxr-xr-x - root supergroup 0 2019-05-30 11:43 /user/hbase/data/default
drwxr-xr-x - root supergroup 0 2019-05-27 14:33 /user/hbase/data/hbase
表級目錄
hdfs dfs -ls -R /user/hbase/data/default/t1
drwxr-xr-x /user/hbase/data/default/t1/.tabledesc
drwxr-xr-x /user/hbase/data/default/t1/.tmp
drwxr-xr-x /user/hbase/data/default/t1/68e61220e866d62a27d0cdeb0c1eed83 #HFile
HFile、WAL和Memstore
HFile
HBase實際的存儲文件功能是由HFile類實現的,它被專門創建以達到一個目的:有效的存儲HBase數據。
HFile數據都在前面的data里:
WAL
regionserver會將數據保存到menstore(內存)中,直到積攢足夠多的數據再將其刷寫到磁盤上,這樣可以避免創建很多小文件。但是存儲在內存中的數據是不穩定的。例如,在服務器斷電的情況下數據可能會丟失。
一個常見的解決方法是預寫日志(WAL):每次更新操作都會寫入日志,只有寫入成功才會通知客戶端操作成功,然后服務器可以按需自由的批量處理或聚合內存中的數據
優化手段:
hbase數據是先寫入到WAL然后寫入到memstore,所以有的優化,建議大家關閉WAL
但是,關閉WAL之后,寫入數據時如果發生宕機,那么數據肯定會丟失
而且,關閉WAL對於寫入性能的提升,其實不是很明顯.WAL其實就類似於hadoop中的edits文件
Hbase元數據:
# 列出hbase名字空間的表
hbase(main):023:0> list_namespace_tables 'hbase'
TABLE
meta
namespace
2 row(s) in 0.0140 seconds
Hbase數據定位過程:
Hbase在數據讀取的時候,需要先查詢hbase:meta表,通過這個表到指定的regionserver獲取region信息並進行數據的讀取。詳細過程如下:
1.client通過zookeeper獲取管理hbase:meta表的regionserver
2.zookeeper返回oldboy-node103
3.向oldboy-node103獲取hbase:meta表的的數據信息
4.查找到t1的row1所對應的region是被oldboy-node102所管理
5.將信息返回給客戶端
6.向oldboy-node102獲取對應region的數據
一旦知道區域(region)的位置,Hbase會緩存這次查詢信息。之后客戶端可以通過緩存信息定位所需的數據位置,而不用再次查找hbase:meta。
讀取過程:
區域(region)和列族(column family)是以文件夾形式存在於HDFS的,所以在讀取的時候:
如果確定了區域位置,就直接從指定的region目錄讀取數據。
如果一個列族文件夾中的文件有多個StoreFile,客戶端會通過布隆過濾器篩選出可能存在數據的塊,對這些塊進行數據的查找。
如果此行有多個列族的話,就會在所有的列族文件夾中同時進行以上操作
寫入過程:
從上圖可以看出,除了真實數據(StoreFile)外,Hbase還處理一種HLog文件,此文件稱為預寫日志(WAL)。用戶發起put請求時,也會先定位數據位置,然后:
第一步,決定數據是否需要寫到由HLog實現的預寫日志(WAL)中,預寫日志(WAL)存儲了序列號和實際數據,所以在服務器崩潰時可以回滾到還未持久化的數據。
一旦數據被寫入到WAL中,數據會被放到MemStore內存數據中。同時regionserver會檢查MemStore是否已經寫滿,如果滿了,就會被刷寫(flush)到磁盤中。會把數據寫成HDFS中的新StoreFile,同時也會保存最后寫入的序列號,系統就知道那些數據被持久化了。
當Storefile 越來越多,會觸發Compact 合並操作,把過多的 Storefile 合並成一個Storefile。
當Storefile 越來越大,Region 也會越來越大。達到閾值后,會觸發Split 切割region操作。