hbase region, store, storefile和列簇,的關系


先來一張大圖。

 

 

 Hbase上Regionserver的內存分為兩個部分,一部分作為Memstore,主要用來寫;另外一部分作為BlockCache,主要用於讀數據;這里主要介紹寫數據的部分,即Memstore。當RegionServer(RS)收到寫請求的時候(writerequest),RS會將請求轉至相應的Region。每一個Region都存儲着一些列(a set of rows)。根據其列族的不同,將這些列數據存儲在相應的列族中(Column Family,簡寫CF)。不同的CF中的數據存儲在各自的HStore中,HStore由一個Memstore及一系列HFile組成。Memstore位於RS的主內存中,而HFiles被寫入到HDFS中。當RS處理寫請求的時候,數據首先寫入到Memstore,然后當到達一定的閥值的時候,Memstore中的數據會被刷到HFile中。

  用到Memstore最主要的原因是:存儲在HDFS上的數據需要按照row key 排序。而HDFS本身被設計為順序讀寫(sequential reads/writes),不允許修改。這樣的話,HBase就不能夠高效的寫數據,因為要寫入到HBase的數據不會被排序,這也就意味着沒有為將來的檢索優化。為了解決這個問題,HBase將最近接收到的數據緩存在內存中(in Memstore),在持久化到HDFS之前完成排序,然后再快速的順序寫入HDFS。(這里參考:http://www.cnblogs.com/shitouer/archive/2013/02/05/configuring-hbase-memstore-what-you-should-know.html)

這里就留下個問題,MemStore何時刷寫成HFile?

個人總結如下:

1.Region級別的觸發刷寫。

(1)hbase.hregion.memstore.flush.size

  單個region內所有的memstore大小總和超過指定值時,flush該region的所有memstore。這里為什么是所有memsotre?因為一張表可能有多個CF,其對應的一個Region自然包含多個CF(即HStore),每個Store都有自己的memstore,這個配置值是所有的store的memstore的總和。當這個總和達到配置值時,即針對每個HSotre,都觸發其Memstore,刷寫成storefile(HFile的封裝)文件。

(2)hbase.hstore.blockingStoreFiles 默認值:7

  說明:在flush時,當一個region中的Store(Coulmn Family)內有超過7個storefile時,則block所有的寫請求進行compaction,以減少storefile數量。

  調優:block寫請求會嚴重影響當前regionServer的響應時間,但過多的storefile也會影響讀性能。從實際應用來看,為了獲取較平滑的響應時間,可將值設為無限大。如果能容忍響應時間出現較大的波峰波谷,那么默認或根據自身場景調整即可。這個值設置比較大,會增加客戶端的負載處理能力(即影響讀取性能),但是如果你的服務器一直處於一個高的水平,那說明你的機器已經達到性能瓶頸,需要其他方式解決。

(3)hbase.hregion.memstore.block.multiplier默認值:2

說明:當一個region里總的memstore占用內存大小超過hbase.hregion.memstore.flush.size兩倍的大小時,block該region的所有請求,進行flush,釋放內存。雖然我們設置了region所占用的memstores總內存大小,比如64M,但想象一下,在最后63.9M的時候,我Put了一個200M的數據,此時memstore的大小會瞬間暴漲到超過預期的hbase.hregion.memstore.flush.size的幾倍。這個參數的作用是當memstore的大小增至超過hbase.hregion.memstore.flush.size2倍時,block所有請求,遏制風險進一步擴大。

調優:這個參數的默認值還是比較靠譜的。如果你預估你的正常應用場景(不包括異常)不會出現突發寫或寫的量可控,那么保持默認值即可。如果正常情況下,你的寫請求量就會經常暴長到正常的幾倍,那么你應該調大這個倍數並調整其他參數值,比如hfile.block.cache.size和hbase.regionserver.global.memstore.upperLimit/lowerLimit,以預留更多內存,防止HBase server OOM。

 

2.RegionServer全局性的觸發刷寫。

(1)hbase.regionserver.global.memstore.upperLimit

當ReigonServer內所有region的memstores所占用內存總和達到heap的40%時,HBase會強制block所有的更新並flush這些region以釋放所有memstore占用的內存。

(2)hbase.regionserver.global.memstore.lowerLimit

同upperLimit,只不過lowerLimit在所有region的memstores所占用內存達到Heap的35%時,不flush所有的memstore。它會找一個memstore內存占用最大的region,做個別flush,此時寫更新還是會被block。lowerLimit算是一個在所有region強制flush導致性能降低前的補救措施。在日志中,表現為“** Flush thread woke up with memory above low water.”。

調優:這是一個Heap內存保護參數,默認值已經能適用大多數場景。

 

3. HLog (WAL)引起的regionserver全局性的觸發刷寫。

當數據被寫入時會默認先寫入Write-ahead Log(WAL)。WAL中包含了所有已經寫入Memstore但還未Flush到HFile的更改(edits)。在Memstore中數據還沒有持久化,當RegionSever宕掉的時候,可以使用WAL恢復數據。

若是關閉WAL,則在hbase-site.xml新增hbase.regionserver.hlog.enabled配置,設為false即可,不建議關閉。

當WAL(在HBase中成為HLog)變得很大的時候,在恢復的時候就需要很長的時間。因此,對WAL的大小也有一些限制,當達到這些限制的時候,就會觸發Memstore的flush。Memstore flush會使WAL減少,因為數據持久化之后(寫入到HFile),就沒有必要在WAL中再保存這些修改。有兩個屬性可以配置:

(1)hbase.regionserver.hlog.blocksize

(2)hbase.regionserver.maxlogs

WAL的最大值由hbase.regionserver.maxlogs*hbase.regionserver.hlog.blocksize (2GB by default)決定。一旦達到這個值,Memstore flush就會被觸發。所以,當你增加Memstore的大小以及調整其他的Memstore的設置項時,你也需要去調整HLog的配置項。否則,WAL的大小限制可能會首先被觸發,因而,你將利用不到其他專門為Memstore而設計的優化。拋開這些不說,通過WAL限制來觸發Memstore的flush並非最佳方式,這樣做可能會會一次flush很多Region,盡管“寫數據”是很好的分布於整個集群,進而很有可能會引發flush“大風暴”。

提示:最好將hbase.regionserver.hlog.blocksize* hbase.regionserver.maxlogs設置為稍微大於hbase.regionserver.global.memstore.lowerLimit* HBASE_HEAPSIZE.

(這里參考:http://www.cnblogs.com/shitouer/archive/2013/02/05/configuring-hbase-memstore-what-you-should-know.html)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM