HBase 系列 - HBase 讀寫流程#
內容整理自:
寫數據流程#
客戶端寫流程#
-
使用者提交 put 請求後,HBase 客戶端會根據設定
autoflush=true/false(默認為true)
判斷是否直接提交給伺服器進行處理,如果為false
則會將請求添加到本地buffer
,超過一定閾值(默認為 2M,可以通過配置文件配置)之後才會提交。這樣可以提高寫入性能,但會存在因為客戶端崩潰導致請求丟失的情況。 -
在提交之前,HBase 會在
元數據表.meta.
中根據 rowkey 找到它們歸屬的 region server,這個定位的過程是通過HConnection的locateRegion
方法獲得的。如果是批量請求的話還會把這些 rowkey 按照HRegionLocation
分組,每個分組可以對應一次 RPC 請求。 -
HBase 會為每個 HRegionLocation 構造一個遠程 RPC 請求
MultiServerCallable<Row>
,然後通過rpcCallerFactory.<MultiResponse> newCaller()
執行調用,忽略掉失敗重新提交和錯誤處理,客戶端的提交操作到此結束。
伺服器端寫流程#
伺服器端 Region Server 接收到客戶端的寫入請求後,首先會反序列化為Put對象
,然後檢查region是否是只讀
、memstore大小是否超過blockingMemstoreSize
等檢查操作,然後執行以下核心操作:
-
獲取行鎖、Region更新共享鎖
: HBase 中使用行鎖保證對同一行數據的更新都是互斥操作,用以保證更新的原子性,要麼更新成功,要麼失敗。 -
開始寫事務
:獲取 write number,用於實現 MVCC,實現數據的非鎖定讀,在保證讀寫一致性的前提下提高讀取性能。 -
寫緩存memstore
:HBase 中每列族都會對應一個 store,用來存儲該列數據。每個 store 都會有個寫緩存 memstore,用於緩存寫入數據。HBase 並不會直接將數據落盤,而是先寫入緩存,等緩存滿足一定大小之後再一起落盤。 -
Append HLog
:HBase使用 WAL 機制保證數據可靠性,即首先寫日誌再寫緩存,即使發生宕機,也可以通過恢復 HLog 還原出原始數據。該步驟就是將數據構造為 WALEdit 對象,然後順序寫入 HLog 中,此時不需要執行 sync 操作。0.98 版本採用了新的寫線程模式實現 HLog 日誌的寫入,可以使得整個數據更新性能得到極大提升。 -
釋放行鎖以及共享鎖
-
Sync HLog
:HLog 真正 sync 到 HDFS,在釋放行鎖之後執行 sync 操作是為了儘量減少持鎖時間,提升寫性能。如果 Sync 失敗,執行回滾操作將 memstore 中已經寫入的數據移除。 -
結束寫事務
:此時該線程的更新操作才會對其他讀請求可見,更新才實際生效。 -
flush memstore
:當寫緩存滿 64M 之後,會啟動 flush 線程將數據刷新到硬碟。當 HBase 中的 memstore 數據 flush 到磁碟的時候,就會形成一個 storefile,當 storefile 的數量達到一定程度的時候,就需要將 storefile 文件進行compaction操作
,Compact 作用:合併文件、清除過期,多餘版本數據、提高讀寫效率。
WAL 持久化等級#
SKIP_WAL
: 只寫緩存,不寫 HLog,因為只用內存,性能很好,但容易丟失數據,不推薦。ASYNC_WAL
: 異步將數據寫入 HLog 日誌中。SYNC_WAL
: 同步將數據寫入日誌文件中,需要注意的是數據只是被寫入文件系統中,並沒有真正落盤。FSYNC_WAL
: 同步將數據寫入日誌文件並強制落盤。最嚴格的日誌寫入等級,可以保證數據不會丟失,但是性能相對比較差。USER_DEFALUT
: 默認如果使用者沒有指定持久化等級,HBase 使用 SYNC_WAL 等級持久化數據。
使用者可以通過客戶端設置 WAL 持久化等級,代碼:put.setDurability(Durability. SYNC_WAL );
讀流程#
客戶端首次讀寫 HBase 上數據的流程:
- 客戶端從 Zookeeper 獲取
META
表所在的 Region Server; - 客戶端訪問
META
表所在的 Region Server,從META
表中查詢到訪問行鍵所在的 Region Server,之後客戶端將緩存這些信息以及META
表的位置; - 客戶端從行鍵所在的 Region Server 上獲取數據。
如果再次讀取,客戶端將從緩存中獲取行鍵所在的 Region Server。這樣客戶端就不需要再次查詢 META
表,除非 Region 移動導致緩存失效,這樣的話,則將會重新查詢並更新緩存。
注:META
表是 HBase 中一張特殊的表,它保存了所有 Region 的位置信息,META 表自己的位置信息則存儲在 ZooKeeper 上。
更為詳細讀取數據流程參考:
HBase 查詢方式#
-
全表查詢:
scan tableName
-
基於 rowkey 的單行查詢:
get tableName,'1'
-
基於 rowkey 的範圍掃描:
scan tableName, {STARTROW=>'1',STOPROW=>'2'}
setCache () 和 setBatch () 方法
Cache 設置了伺服器一次返回的行數,而 Batch 設置了伺服器一次返回的列數。