HBase塊緩存

2018-05-23 14:18 更新

塊緩存

HBase提供了兩種不同的BlockCache實現(xiàn),來緩存從HDFS中讀取的數(shù)據(jù):默認的on-heap LruBlockCache和BucketCache(通常是off-heap)。本節(jié)討論每個實現(xiàn)的優(yōu)點和缺點、如何選擇適當?shù)倪x項以及每種配置選項。

緩存選擇

LruBlockCache是原始實現(xiàn),完全在Java堆內(nèi)。 BucketCache是可選的,主要用于保持塊緩存數(shù)據(jù)脫離堆,盡管BucketCache也可以是文件支持的緩存。

當您啟用BucketCache時,您將啟用兩層緩存系統(tǒng)。我們曾經(jīng)將層描述為“L1”和“L2”,但是已經(jīng)不贊成使用hbase-2.0.0的這個術(shù)語?!癓1”緩存引用了LruBlockCache的一個實例,并且將“L2”引用到了堆外的BucketCache。相反,當啟用BucketCache時,所有DATA塊都保存在BucketCache層中,元塊(INDEX和BLOOM塊)在LruBlockCache堆中。這兩個層次的管理以及控制它們之間的塊移動的策略是由 CombinedBlockCache 完成的。

常規(guī)緩存配置

除了緩存實現(xiàn)本身之外,您可以設(shè)置一些常規(guī)配置選項來控制緩存的執(zhí)行方式。請參閱CacheConfig。設(shè)置了其中任何選項后,重新啟動或滾動重新啟動群集以使配置生效。檢查日志以查找錯誤或意外行為。

LruBlockCache設(shè)計

LruBlockCache是??一個LRU緩存,它包含三個塊級別的優(yōu)先級以允許掃描電阻和內(nèi)存中的ColumnFamilies:

  • 單一訪問優(yōu)先級:從HDFS首次加載塊時,它通常具有此優(yōu)先級,它將成為驅(qū)逐期間要考慮的第一個組的一部分。其優(yōu)點是,掃描塊比獲得更多用量的塊更有可能被驅(qū)逐。
  • 多重訪問優(yōu)先級:如果先前優(yōu)先級組中的塊再次被訪問,則會升級到此優(yōu)先級。因此它是在驅(qū)逐期間考慮的第二組的一部分。
  • 內(nèi)存訪問優(yōu)先級:如果該塊的系列配置為“內(nèi)存中(in-memory)”,則無論訪問次數(shù)如何,都將成為此優(yōu)先級的一部分。目錄表是這樣配置的。這個小組是在驅(qū)逐過程中考慮的最后一個小組。要將列族標記為內(nèi)存中,請調(diào)用:
    HColumnDescriptor.setInMemory(true);

如果從java創(chuàng)建表,或者在shell中創(chuàng)建或更改表時設(shè)置IN_MEMORY ? true,例如:

hbase(main):003:0> create  't', {NAME => 'f', IN_MEMORY => 'true'}

LruBlockCache用法

所有用戶表默認啟用塊緩存,這意味著任何讀取操作都會加載LRU緩存。這對于大量的用例可能是有益的,但通常需要進一步的調(diào)整才能獲得更好的性能。一個重要的概念是工作集大小或WSS,即:“計算問題答案所需的內(nèi)存量”。對于一個網(wǎng)站,這將是在短時間內(nèi)回答查詢所需的數(shù)據(jù)。

計算緩存中HBase有多少內(nèi)存的方法是:

number of region servers * heap size * hfile.block.cache.size * 0.99

塊緩存的默認值為0.4,表示可用堆的40%。最后一個值(99%)是在驅(qū)逐開始之后LRU緩存中的默認可接受加載因子。它被包含在這個等式中的原因是,說可以使用100%的可用內(nèi)存是不現(xiàn)實的,因為這會使得該過程從加載新塊的位置阻塞。下面是一些示例:

  • 一個區(qū)域服務器的堆大小設(shè)置為1 GB,默認塊高速緩存大小將具有405 MB的塊高速緩存可用。
  • 20個區(qū)域服務器的堆大小設(shè)置為8 GB,并且默認塊高速緩存大小將具有63.3個塊高速緩存。
  • 堆大小設(shè)置為24 GB并且塊緩存大小為0.5的100個區(qū)域服務器將擁有大約1.16 TB的塊緩存。

您的數(shù)據(jù)不是塊緩存的唯一常駐者。以下是您可能必須考慮的其他問題:

目錄表

hbase:meta表被強制進入塊緩存并具有內(nèi)存優(yōu)先級,這意味著它們更難以驅(qū)逐。(根據(jù)區(qū)域的數(shù)量,hbase:meta表格可以占用幾個MB。)

HFiles索引

一個HFILE是HBase的使用將數(shù)據(jù)存儲在HDFS文件格式。它包含一個多層索引,它允許HBase在不必讀取整個文件的情況下查找數(shù)據(jù)。這些索引的大小是塊大小(默認為64KB),密鑰大小和存儲的數(shù)據(jù)量的一個因素。對于大數(shù)據(jù)集,每個區(qū)域服務器的數(shù)字大約為1GB并不罕見,但并不是所有的數(shù)據(jù)都會被緩存,因為LRU會逐出未使用的索引。

按鍵

存儲的值僅為圖片的一半,因為每個值都與其鍵一起存儲(行鍵,族限定符和時間戳)。

Bloom過濾器

就像HFile索引一樣,這些數(shù)據(jù)結(jié)構(gòu)(啟用時)都存儲在LRU中。

目前,衡量HFile索引和bloom過濾器大小的推薦方法是查看區(qū)域服務器Web UI并檢查相關(guān)度量標準。對于密鑰,可以使用HFile命令行工具完成采樣并查找平均密鑰大小度量。從HBase 0.98.3開始,您可以在用戶界面的特殊Block Cache部分查看有關(guān)BlockCache統(tǒng)計信息和指標的詳細信息。

當WSS不適合內(nèi)存時,使用塊緩存通常是不好的。例如,在所有區(qū)域服務器的塊高速緩存中都有40GB可用的情況,但您需要處理1TB的數(shù)據(jù)。其中一個原因是由驅(qū)逐產(chǎn)生的流失會不必要地觸發(fā)更多的垃圾收集。這里有兩個用例:

  • 完全隨機讀取模式:這種情況下,幾乎不會在短時間內(nèi)訪問同一行兩次,從而使得緩存塊的命中率接近于0。在這樣的表上設(shè)置塊緩存會浪費內(nèi)存和CPU周期,更多的是它會產(chǎn)生更多的垃圾來由JVM提取。
  • 映射表:在典型的MapReduce作業(yè)中,每個行都只能讀取一次,因此不需要將它們放入塊緩存。Scan對象可以通過setCaching方法將其關(guān)閉(將其設(shè)置為false)。如果您需要快速隨機讀取訪問,您仍然可以在此表上保持塊緩存打開狀態(tài)。一個例子就是統(tǒng)計表中提供實時流量的行數(shù),緩存該表的每個塊都會產(chǎn)生大量流失,并且肯定會驅(qū)逐當前正在使用的數(shù)據(jù)。
僅高速緩存META塊(fscache中的數(shù)據(jù)塊)

一個有趣的設(shè)置是我們只緩存META塊,并在每個訪問中讀取DATA塊。如果DATA塊適用于fscache,則當訪問在非常大的數(shù)據(jù)集中完全隨機時,此替代方法可能有意義。要啟用此設(shè)置,請更改您的表格和每個列族集:BLOCKCACHE ? 'false'。您只對此列族 "禁用" BlockCache。您永遠不能禁用META塊的緩存。由于HBASE-4683總是緩存索引和bloom塊,所以即使BlockCache被禁用,我們也會緩存META塊。

堆外塊緩存

如何啟用BucketCache

BucketCache的通常部署是通過一個管理類來設(shè)置兩個緩存層:由LruBlockCache實現(xiàn)的堆緩存和使用BucketCache實現(xiàn)的第二個緩存。管理類默認為CombinedBlockCache。上一個鏈接描述了CombinedBlockCache實現(xiàn)的緩存“策略”。簡而言之,它的工作方式是將元塊(INDEX和BLOOM)保留在堆上的LruBlockCache層中,并將DATA塊保存在BucketCache層中。

Pre-hbase-2.0.0版本

與原生堆內(nèi)LruBlockCache相比,從hbase-2.0.0之前的BucketCache中獲取數(shù)據(jù)時,抓取總是比較慢。但是,隨著時間的推移,延遲趨于不那么不穩(wěn)定,因為使用BucketCache時垃圾收集較少,因為它正在管理BlockCache分配,而不是GC。如果BucketCache部署在堆外模式下,則該內(nèi)存根本不由GC管理。這就是為什么你會在2.0.0之前使用BucketCache,所以你的延遲不那么不穩(wěn)定,為了減少GC和堆碎片,所以你可以安全地使用更多的內(nèi)存。

在2.0.0之前版本中,可以配置BucketCache,以便接收LruBlockCache驅(qū)逐的victim。所有數(shù)據(jù)和索引塊首先緩存在L1中。當驅(qū)逐發(fā)生在 L1,塊(或victims)將移至L2。設(shè)置cacheDataInL1通過(HColumnDescriptor.setCacheDataInL1(true)或shell,設(shè)置CACHE_DATA_IN_L1為true:來創(chuàng)建或修改列族,如:

hbase(main):003:0> create 't', {NAME => 't', CONFIGURATION => {CACHE_DATA_IN_L1 => 'true'}}                
hbase-2.0.0 +版本

HBASE-11425更改了HBase讀取路徑,以便它可以將讀取數(shù)據(jù)從堆中保留,避免將緩存數(shù)據(jù)復制到java堆上。在hbase-2.0.0中,堆外延遲接近堆緩存延遲時間,并且不會引發(fā)GC。

從HBase 2.0.0開始,L1和L2的概念已被棄用。當BucketCache打開時,DATA塊將總是進入BucketCache,而INDEX/BLOOM塊將進入堆LRUBlockCache。cacheDataInL1支持已被刪除。

BucketCache塊緩存可以部署為堆外(off-heap)、文件(file)或mmaped文件模式。

您可以通過hbase.bucketcache.ioengine設(shè)置來進行設(shè)置。將它設(shè)置為offheap使BucketCache將其分配置于堆外,并且file:PATH_TO_FILE的ioengine設(shè)置將指示BucketCache使用文件緩存(特別是在您將某些快速I/O附加到SSD等盒子時有用)。從2.0.0開始,可以有多個文件支持BucketCache。當緩存大小要求很高時,這非常有用。對于多個備份文件,將ioengine配置為files:PATH_TO_FILE1,PATH_TO_FILE2,PATH_TO_FILE3。BucketCache也可以配置為使用mmapped文件。將 ioengine 配置為 mmap: PATH_TO_FILE。

可以在我們繞過CombinedBlockCache策略的情況下部署分層設(shè)置,并將BucketCache作為嚴格的L2緩存工作到L1 LruBlockCache。對于這樣的設(shè)置,設(shè)置hbase.bucketcache.combinedcache.enabled為false。在這種模式下,從L1中逐出時,塊將轉(zhuǎn)到L2。當一個塊被緩存時,它會先在L1中緩存。當我們?nèi)ふ揖彺鎵K時,我們先看看L1,如果找不到,那么搜索L2。我們稱這種部署格式為Raw L1 + L2。注意:這個L1 + L2模式從2.0.0中刪除。當使用BucketCache時,它將嚴格地是DATA緩存,并且LruBlockCache將緩存INDEX/META塊。

其他BucketCache配置包括:指定要在重新啟動時保持緩存的位置、使用多少線程來編寫緩存等。

要檢查它是否啟用,請查找描述緩存設(shè)置的日志行,它將詳細介紹BucketCache的部署方式。另請參閱UI。它將詳細介紹緩存分層及其配置。

BucketCache示例配置

此示例為具有1 GB堆緩存的4 GB脫離堆BucketCache提供配置。

在RegionServer上執(zhí)行配置。

設(shè)置hbase.bucketcache.ioengine和hbase.bucketcache.size> 0啟用CombinedBlockCache。讓我們假設(shè)RegionServer已經(jīng)設(shè)置為以5G堆運行:即HBASE_HEAPSIZE=5g。

  1. 首先,編輯RegionServer的hbase-env.sh,并將HBASE_OFFHEAPSIZE設(shè)置為大于所需的堆外大小的值,在本例中為4 GB(表示為4G)。我們將其設(shè)置為5G。對于我們的堆外緩存,這將是4G,對于任何其他堆外內(nèi)存使用(除了BlockCache以外,還有其他堆外存儲器的用戶,例如RegionServer中的DFSClient可以使用堆外存儲器)。
    HBASE_OFFHEAPSIZE=5G
  2. 接下來,將以下配置添加到RegionServer的hbase-site.xml。
    <property>
      <name>hbase.bucketcache.ioengine</name>
      <value>offheap</value>
    </property>
    <property>
      <name>hfile.block.cache.size</name>
      <value>0.2</value>
    </property>
    <property>
      <name>hbase.bucketcache.size</name>
      <value>4196</value>
    </property>
  3. 重新啟動或滾動重新啟動群集,并檢查日志是否有任何問題。

在上面,我們將BucketCache設(shè)置為4G。我們將堆上的LruBlockCache配置為RegionServer堆大小的20%(0.2)(0.2 * 5G = 1G)。換句話說,像通常一樣配置L1 LruBlockCache(就好像沒有L2高速緩存一樣)。

HBase-10641引入了為HBase 0.98和更高版本的BucketCache的bucket配置多種大小的功能。要配置多個存儲區(qū)大小,請將新屬性hfile.block.cache.sizes(而不是hfile.block.cache.size)配置為以逗號分隔的塊大小列表(從最小到最大排列),并且不含空格。目標是根據(jù)您的數(shù)據(jù)訪問模式優(yōu)化存儲bucket大小。以下示例配置大小為4096和8192的存儲bucket。

<property>
  <name>hfile.block.cache.sizes</name>
  <value>4096,8192</value>
</property>

HBase中的直接內(nèi)存使用情況

默認的最大直接內(nèi)存因JVM而異。傳統(tǒng)上它是64M或某一關(guān)系到被分配的堆大?。?Xmx)或根本沒有限制(JDK7)。HBase服務器使用直接內(nèi)存,特別是短路讀取,承載的DFSClient將分配直接內(nèi)存緩沖區(qū)。DFSClient使用的數(shù)量不容易量化;它是打開的HFiles*hbase.dfs.client.read.shortcircuit.buffer.size的數(shù)目,其中hbase.dfs.client.read.shortcircuit.buffer.size設(shè)置為128k。如果你使用堆外緩存,你將會使用直接內(nèi)存。RPCServer使用ByteBuffer池。從2.0.0開始,這些緩沖區(qū)是堆外ByteBuffers。啟動您的JVM,在conf/hbase-env.sh中確保-XX:MaxDirectMemorySize設(shè)置,考慮堆外塊緩存(hbase.bucketcache.size)、DFSClient使用,RPC端ByteBufferPool最大大小。這必須比堆外BlockCache大小和最大ByteBufferPool大小的總和要高一點。為最大直接內(nèi)存大小分配額外的1-2 GB在測試中起作用。直接內(nèi)存是Java進程堆的一部分,與-Xmx分配的對象堆是分開的。MaxDirectMemorySize分配的值不得超過物理RAM,并且由于其他內(nèi)存要求和系統(tǒng)限制,可能會少于總可用RAM。

您可以通過查看UI 中的“服務器度量標準:內(nèi)存(Server Metrics: Memory)”選項卡,查看RegionServer配置為使用多少內(nèi)存和堆外/直接內(nèi)存以及以及每次使用的時間。它也可以通過JMX獲取。特別是可以在java.nio.type=BufferPool,name=directbean 上找到服務器當前使用的直接內(nèi)存。Terracotta在Java中使用非堆內(nèi)存有一個很好的記錄。這是為了他們的產(chǎn)品BigMemory,但是很多問題都提到了對任何試圖外堆的嘗試,檢查出來。

hbase.bucketcache.percentage.in.combinedcache

這是一個HBase 1.0之前的配置,因為它很混亂。這是一個浮點數(shù),你會設(shè)置0.0到1.0之間的某個值,它的默認值是0.9。如果部署使用CombinedBlockCache,則LruBlockCache L1大小計算為:(1 - hbase.bucketcache.percentage.in.combinedcache) * size-of-bucketcache ,BucketCache大小為:hbase.bucketcache.percentage.in.combinedcache * size-of-bucket-cache。如果size-of-bucket-cache指定為Megabytes,則它EITHER配置hbase.bucketcache.size的值;如果hbase.bucketcache.size在0到1.0之間,則hbase.bucketcache.size * -XX:MaxDirectMemorySize

在1.0中,它應該更直接。Onheap LruBlockCache大小設(shè)置為使用hfile.block.cache.size設(shè)置(并非最佳)的java堆的一小部分,并且BucketCache在絕對兆字節(jié)中設(shè)置為上述值。

壓縮BlockCache

HBASE- 11331引入了懶惰的BlockCache解壓縮,更簡單地稱為壓縮BlockCache。當啟用壓縮BlockCache時,數(shù)據(jù)和編碼數(shù)據(jù)塊將以磁盤格式緩存在BlockCache中,而不是在緩存之前解壓縮和解密。

對于承載更多數(shù)據(jù)而不適合緩存的RegionServer,通過SNAPPY壓縮啟用此功能可以使吞吐量增加50%,平均延遲增加30%,同時將垃圾收集增加80%,并增加整體CPU負載2%。有關(guān)如何衡量和實現(xiàn)性能的更多詳細信息,請參閱HBASE-11331。對于容納適合緩存的數(shù)據(jù)的RegionServer,或者如果您的工作負載對額外的CPU或垃圾收集負載敏感,則可能會收到較少的收益。

壓縮的BlockCache默認是禁用的。要啟用它,請在所有RegionServers的hbase-site.xml中設(shè)置hbase.block.data.cachecompressed為true。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號