hbase实践之写流程拾遗
keyvalue
KeyValue中包含了豐富的自我描述信息:
KeyValue是支撐”稀疏矩陣”設計的一個關鍵點:一些Key相同的任意數量的獨立KeyValue就可以構成一行數據。但這種設計帶來的一個顯而易見的缺點:每一個KeyValue所攜帶的自我描述信息,會帶來顯著的數據膨脹。
為什么rowkey不能太長?columnfamily、qualifiter盡量短?
行級事務模型
寫寫并發控制
包括單行、批量多行。
- 單行:行鎖
- 多行:兩階段鎖協議,即:
(1) 獲取所有待寫入(更新)行記錄的行鎖
(2) 開始執行寫入(更新)操作
(3) 寫入完成之后再統一釋放所有行記錄的行鎖
讀寫并發控制:MVCC
Mutil Version Concurrent Control。HBase中MVCC機制實現主要分為兩步:
(1) 為每一個寫(更新)事務分配一個Region級別自增的序列號
(2) 為每一個讀請求分配一個已完成的最大寫事務序列號
MVCC的精髓是寫入的時候分配遞增版本信息(SequenceId),讀取的時候分配唯一的版本用于讀取可見,比之大的版本不可見。這里需要注意版本必須遞增,而且版本遞增的范圍一定程度上決定了事務是什么事務,比如HBase是Region級別的遞增版本,那么事務就是region級別事務。
非必須情況,不要使用行鎖。
sequenceId
為什么要有sequenceId?
本質問題:mestore、Hlog中的數據是同一份,他們需要同一個標識。
- HLog文件的基本結構
<logseq#-for-entire-txn>:<-1, 3, , , >
The -1 marker is just a special way of being backward compatible with an old HLog which would have contained a single . -1只是一個標志, 是為了對舊版本兼容.
問題一:HLog在什么時候可以過期回收?HLog在什么時候可以過期回收?
RegionServer會為每個Region維護了一個變量oldestUnflushedSequenceId(實際上是為每個Store,為了方便講解,此處暫且認為是Region,不影響原理),表示這個Region最早的還未落盤的seqid ,即這個seqid之前的所有數據都已經落盤。
下圖是flush過程中oldestUnflushedSequenceId變量變化的示意圖,初始時為null,假設在某一時刻階段二RegionA(紅色方框)要執行flush,中間HLog中sequenceId為1~4對應的數據將會落盤,在執行flush之前,HBase會append一個空的Entry到HLog,僅為獲取下一個sequenceId(5),并將這個sequenceId賦給OldestUnflushedSequenceId-RegionA。如圖中第三階段OldestUnflushedSequenceId-RegionA指向sequenceId為5的Entry。
場景一中右側HLog還有未落盤的數據(sequenceid=5還未落盤),因此不能刪除;而場景二中右側HLog的所有數據都已經落盤,所以這個HLog理論上就已經可以被刪除回收。
問題二:HLog數量超過閾值(maxlogs)之后刪除最早HLog,應該強制刷新哪些Region?
HLog日志文件超過閾值,會刪除最老的,根據OldestUnflushedSequenceId,如果該日志中有數據未寫磁盤,則強制刷寫磁盤,然后將該日志文件刪除。
問題三:RegionServer宕機恢復replay日志時哪些WALEntry需要被回放,哪些會被skip?
理論上來說只需要回放Memstore中沒有落地的數據對應的WALEntry,已經落地數據對應的WALEntry可以skip。可問題是RegionServer已經宕機了,<region, oldestUnflushedSequenceId> 對應信息肯定沒有了,如何是好?想辦法持久化唄,上文分析oldestUnflushedSequenceId變量是flush時產生的一個變量,這個變量完全可以以flush的時候以元數據的形式寫到HFile中(代碼見下圖):
到目前為止,上面所有分析都基于一個事實:hbase中flush操作是region級別操作,即每次執行flush都需要整個region中的所有store全都執行flush。
Per-CF Flush
map<region, map<store, oldestUnflushedSequenceId>>
RS宕機與恢復
由HMaster來管理并切分日志==>RegionServer切分日志(小文件多)==>RegionServer切分日志后,直接在Region-Buffer中回放。
Region 切分
Region切分觸發策略
在大集群條件下對于很多大表來說表現很優秀,但并不完美,這種策略下很多小表會在大集群中產生大量小region,分散在整個集群中。而且在發生region遷移時也可能會觸發region分裂。
切分本質
雖然產生2個子Region,但還是指向原來的HFile文件。只有major compaction時,父region的數據才會遷移到子region目錄。
參考文獻
- HBase原理-要弄懂的sequenceId
- HBase原理-RegionServer宕機數據恢復
- HBase原理 – 所有Region切分的細節都在這里了
- HBase行級事務模型
轉載于:https://www.cnblogs.com/small-k/p/9911606.html
總結
以上是生活随笔為你收集整理的hbase实践之写流程拾遗的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring框架中的9种设计模式汇总
- 下一篇: 麻省理工学院研究人员设计出针对幽灵党和熔