目錄: write Compaction splite read Write: 當客戶端發起一個Put請求時,首先根據RowKey定址,從hbase:meta表中查出該Put數據最終需要去的HRegionServer 客戶端將Put請求發送給相應的HRegionServer,在HRegionServ ...
目錄:
- write
- Compaction
- splite
- read
Write:
- 當客戶端發起一個Put請求時,首先根據RowKey定址,從hbase:meta表中查出該Put數據最終需要去的HRegionServer
- 客戶端將Put請求發送給相應的HRegionServer,在HRegionServer中它首先會將該Put操作寫入WAL日誌文件中(Flush到磁碟中),如下圖:
- 寫完WAL日誌文件後,HRegionServer根據Put中的TableName和RowKey找到對應的HRegion,並根據Column Family找到對應的HStore
- 將Put數據寫入到該HStore的MemStore中。此時寫成功,並返回通知客戶端
- 上一節介紹過,MemStore是一個In Memory Sorted Buffer,在每個HStore中都有一個MemStore,即它是一個HRegion的一個Column Family對應一個實例。
- 它的排列順序以RowKey、Column Family、Column的順序以及Timestamp的倒序,如下示意圖:
- 每一次Put請求都是先寫入到MemStore中,當MemStore滿後會Flush成一個新的StoreFile(底層實現是HFile),即一個HStore(Column Family)可以有0個或多個StoreFile(HFile)
- 註意:MemStore的最小Flush單元是HRegion而不是單個MemStore, 這就是建議使用單列族的原因,太多的Column Family一起Flush會引起性能問題
- MemStore觸發Flush動作的時機:
- 當一個MemStore的大小超過了hbase.hregion.memstore.flush.size的大小,此時當前的HRegion中所有的MemStore會Flush到HDFS中
- 當全局MemStore的大小超過了hbase.regionserver.global.memstore.upperLimit的大小,預設40%的記憶體使用量。此時當前HRegionServer中所有HRegion中的MemStore都會Flush到HDFS中,Flush順序是MemStore大小的倒序,直到總體的MemStore使用量低於hbase.regionserver.global.memstore.lowerLimit,預設38%的記憶體使用量
- 待確認:一個HRegion中所有MemStore總和作為該HRegion的MemStore的大小還是選取最大的MemStore作為參考?
- 當前HRegionServer中WAL的大小超過了hbase.regionserver.hlog.blocksize * hbase.regionserver.max.logs的數量,當前HRegionServer中所有HRegion中的MemStore都會Flush到HDFS中,Flush使用時間順序,最早的MemStore先Flush直到WAL的數量少於hbase.regionserver.hlog.blocksize * hbase.regionserver.max.logs
- 註意:因為這個大小超過限制引起的Flush不是一件好事,可能引起長時間的延遲
- 在MemStore Flush過程中,還會在尾部追加一些meta數據,其中就包括Flush時最大的WAL sequence值,以告訴HBase這個StoreFile寫入的最新數據的序列,那麼在Recover時就直到從哪裡開始。在HRegion啟動時,這個sequence會被讀取,並取最大的作為下一次更新時的起始sequence,如下圖:
Compaction:
- MemStore每次Flush會創建新的HFile,而過多的HFile會引起讀的性能問題,HBase採用Compaction機制來解決這個問題
- HBase中Compaction分為兩種:Minor Compaction和Major Compaction
- Minor Compaction: 是指選取一些小的、相鄰的StoreFile將他們合併成一個更大的StoreFile,在這個過程中不會處理已經Deleted或Expired的Cell。一次Minor Compaction的結果是更少並且更大的StoreFile, 如下圖:
- Major Compaction: 是指將所有的StoreFile合併成一個StoreFile,在這個過程中,標記為Deleted的Cell會被刪除,而那些已經Expired的Cell會被丟棄,那些已經超過最多版本數的Cell會被丟棄。一次Major Compaction的結果是一個HStore只有一個StoreFile存在
- Major Compaction可以手動或自動觸發,然而由於它會引起很多的IO操作而引起性能問題,因而它一般會被安排在周末、凌晨等集群比較閑的時間, 如下示意圖:
- 修改Hbase配置文件可以控制compaction行為
- hbase.hstore.compaction.min :預設值為 3,(老版本是:hbase.hstore.compactionThreshold),即store下麵的storeFiles數量 減去 正在compaction的數量 >=3是,需要做compaction
- hbase.hstore.compaction.max 預設值為10,表示一次minor compaction中最多選取10個store file
- hbase.hstore.compaction.min.size 表示文件大小小於該值的store file 一定會加入到minor compaction的store file中
- hbase.hstore.compaction.max.size 表示文件大小大於該值的store file 一定會被minor compaction排除
splite:
- 最初,一個Table只有一個HRegion,隨著數據寫入增加,如果一個HRegion到達一定的大小,就需要Split成兩個HRegion,這個大小由hbase.hregion.max.filesize指定
- split時,兩個新的HRegion會在同一個HRegionServer中創建,它們各自包含父HRegion一半的數據,當Split完成後,父HRegion會下線,而新的兩個子HRegion會向HMaster註冊上線
- 處於負載均衡的考慮,這兩個新的HRegion可能會被HMaster分配到其他的HRegionServer,示意圖如下:
- 在zookeeper上創建ephemeral的znode指示parent region正在splitting
- HMaster監控父Regerion的region-in-transition znode
- 在parent region的文件夾中創建臨時split目錄
- 關閉parent region(會flush 所有memory store(memory file),等待active compaction結束),從現在開始parent region 不可服務。同時從本地server上offline parent region,每個region server都維護了一個valid region的list,該步將parent region從該list中移除
- Split所有的store file,這一步為每個文件做一個reference file,reference file由兩部分組成
- 第一部分是源文件的路徑,第二部分是新的reference file引用源文件split key以及引用上半截還是下半截
- 舉個例子:源文件是Table1/storefile.11,split point 是key1, 則split 成兩個子文件可能可能是Table1/storefile.11.bottom.key1,Table1/storefile.11.up.key1,表示從key1切開storefile.11後,兩個引用文件分別引用源文件的下半部分和上半部分
- 創建child region
- 設置各種屬性,比如將parent region的訪問指標平分給child region,每人一半
- 將上面在parent 文件夾中生成的臨時文件夾(裡面包含對parent region的文件reference)move到表目錄下,現在在目錄層次上,child region已經跟parent region平起平坐了
- 向系統meta server中寫入parent region split完畢的信息,並將child region的名字一併寫入(split狀態在meta層面持久化)
- 分別Open 兩個child region,主要包含以下幾個步驟:
- 將child region信息寫入meta server
- Load 所有store file,並replay log等
- 如果包含reference文件,則做一次compaction(類似merge),直到將所有的reference文件compact完畢,這裡可以看到parent region的文件是會被拆開寫入各個child regions的
- 將parent region的狀態由SPLITTING轉為SPLIT,zookeeper會負責通知master開始處理split事件,master開始offline parent region,並online child regions
- Worker等待master處理完畢之後,確認child regions都已經online,split結束
read:
- 根據Rowkey定址(詳情見上一節定址部分),如下圖:
- 獲取數據順序規則,如下圖:
參考資料:
- http://hortonworks.com/blog/apache-hbase-region-splitting-and-merging/
- https://www.mapr.com/blog/in-depth-look-hbase-architecture#.VdNSN6Yp3qx