日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HBase查询优化

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HBase查询优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.概述

HBase是一個實時的非關系型數據庫,用來存儲海量數據。但是,在實際使用場景中,在使用HBase API查詢HBase中的數據時,有時會發現數據查詢會很慢。本篇博客將從客戶端優化和服務端優化兩個方面來介紹,如何提高查詢HBase的效率。

2.內容

這里,我們先給大家介紹如何從客戶端優化查詢速度。

2.1 客戶端優化

客戶端查詢HBase,均通過HBase API的來獲取數據,如果在實現代碼邏輯時使用API不當,也會造成讀取耗時嚴重的情況。

2.1.1 Scan優化

在使用HBase的Scan接口時,一次Scan會返回大量數據??蛻舳讼騂Base發送一次Scan請求,實際上并不會將所有數據加載到本地,而是通過多次RPC請求進行加載。這樣設計的好處在于避免大量數據請求會導致網絡帶寬負載過高影響其他業務使用HBase,另外從客戶端的角度來說可以避免數據量太大,從而本地機器發送OOM(內存溢出)。

默認情況下,HBase每次Scan會緩存100條,可以通過屬性hbase.client.scanner.caching來設置。另外,最大值默認為-1,表示沒有限制,具體實現見源代碼:

/*** @return the maximum result size in bytes. See {@link #setMaxResultSize(long)}*/public long getMaxResultSize() {return maxResultSize;}/*** Set the maximum result size. The default is -1; this means that no specific* maximum result size will be set for this scan, and the global configured* value will be used instead. (Defaults to unlimited).** @param maxResultSize The maximum result size in bytes.*/public Scan setMaxResultSize(long maxResultSize) {this.maxResultSize = maxResultSize;return this;}

一般情況下,默認緩存100就可以滿足,如果數據量過大,可以適當增大緩存值,來減少RPC次數,從而降低Scan的總體耗時。另外,在做報表呈現時,建議使用HBase分頁來返回Scan的數據。

2.1.2 Get優化

HBase系統提供了單條get數據和批量get數據,單條get通常是通過請求表名+rowkey,批量get通常是通過請求表名+rowkey集合來實現。客戶端在讀取HBase的數據時,實際是與RegionServer進行數據交互。在使用批量get時可以有效的較少客戶端到各個RegionServer之間RPC連接數,從而來間接的提高讀取性能。批量get實現代碼見org.apache.hadoop.hbase.client.HTable類:

public Result[] get(List<Get> gets) throws IOException {if (gets.size() == 1) {return new Result[]{get(gets.get(0))};}try {Object[] r1 = new Object[gets.size()];batch((List<? extends Row>)gets, r1, readRpcTimeoutMs);// Translate.Result [] results = new Result[r1.length];int i = 0;for (Object obj: r1) {// Batch ensures if there is a failure we get an exception insteadresults[i++] = (Result)obj;}return results;} catch (InterruptedException e) {throw (InterruptedIOException)new InterruptedIOException().initCause(e);}}

從實現的源代碼分析可知,批量get請求的結果,要么全部返回,要么拋出異常。

2.1.3 列簇和列優化

通常情況下,HBase表設計我們一個指定一個列簇就可以滿足需求,但也不排除特殊情況,需要指定多個列簇(官方建議最多不超過3個),其實官方這樣建議也是有原因的,HBase是基于列簇的非關系型數據庫,意味著相同的列簇數據會存放在一起,而不同的列簇的數據會分開存儲在不同的目錄下。如果一個表設計多個列簇,在使用rowkey查詢而不限制列簇,這樣在檢索不同列簇的數據時,需要獨立進行檢索,查詢效率固然是比指定列簇查詢要低的,列簇越多,這樣影響越大。

而同一列簇下,可能涉及到多個列,在實際查詢數據時,如果一個表的列簇有上1000+的列,這樣一個大表,如果不指定列,這樣查詢效率也是會很低。通常情況下,在查詢的時候,可以查詢指定我們需要返回結果的列,對于不需要的列,可以不需要指定,這樣能夠有效地的提高查詢效率,降低延時。

2.1.4 禁止緩存優化

批量讀取數據時會全表掃描一次業務表,這種提現在Scan操作場景。在Scan時,客戶端與RegionServer進行數據交互(RegionServer的實際數據時存儲在HDFS上),將數據加載到緩存,如果加載很大的數據到緩存時,會對緩存中的實時業務熱數據有影響,由于緩存大小有限,加載的數據量過大,會將這些熱數據“擠壓”出去,這樣當其他業務從緩存請求這些數據時,會從HDFS上重新加載數據,導致耗時嚴重。

在批量讀取(T+1)場景時,建議客戶端在請求是,在業務代碼中調用setCacheBlocks(false)函數來禁止緩存,默認情況下,HBase是開啟這部分緩存的。源代碼實現為:

/*** Set whether blocks should be cached for this Get.* <p>* This is true by default. When true, default settings of the table and* family are used (this will never override caching blocks if the block* cache is disabled for that family or entirely).** @param cacheBlocks if false, default settings are overridden and blocks* will not be cached*/public Get setCacheBlocks(boolean cacheBlocks) {this.cacheBlocks = cacheBlocks;return this;}/*** Get whether blocks should be cached for this Get.* @return true if default caching should be used, false if blocks should not* be cached*/public boolean getCacheBlocks() {return cacheBlocks;}

2.2 服務端優化

HBase服務端配置或集群有問題,也會導致客戶端讀取耗時較大,集群出現問題,影響的是整個集群的業務應用。

2.2.1 負載均衡優化

客戶端的請求實際上是與HBase集群的每個RegionServer進行數據交互,在細分一下,就是與每個RegionServer上的某些Region進行數據交互,每個RegionServer上的Region個數上的情況下,可能這種耗時情況影響不大,體現不夠明顯。但是,如果每個RegionServer上的Region個數較大的話,這種影響就會很嚴重。筆者這里做過統計的數據統計,當每個RegionServer上的Region個數超過800+,如果發生負載不均衡,這樣的影響就會很嚴重。

可能有同學會有疑問,為什么會發送負載不均衡?負載不均衡為什么會造成這樣耗時嚴重的影響?

1.為什么會發生負載不均衡?

負載不均衡的影響通常由以下幾個因素造成:

  • 沒有開啟自動負載均衡
  • 集群維護,擴容或者縮減RegionServer節點
  • 集群有RegionServer節點發生宕機或者進程停止,隨后守護進程又自動拉起宕機的RegionServer進程

針對這些因素,可以通過以下解決方案來解決:

  • 開啟自動負載均衡,執行命令:echo "balance_switch true" | hbase shell
  • 在維護集群,或者守護進程拉起停止的RegionServer進程時,定時調度執行負載均衡命令:echo "balancer" | hbase shell

2.負載不均衡為什么會造成這樣耗時嚴重的影響?

這里筆者用一個例子來說,集群每個RegionServer包含由800+的Region數,但是,由于集群維護,有幾臺RegionServer節點的Region全部集中到一臺RegionServer,分布如下圖所示:

這樣之前請求在RegionServer2和RegionServer3上的,都會集中到RegionServer1上去請求。這樣就不能發揮整個集群的并發處理能力,另外,RegionServer1上的資源使用將會翻倍(比如網絡、磁盤IO、HBase RPC的Handle數等)。而原先其他正常業務到RegionServer1的請求也會因此受到很大的影響。因此,讀取請求不均衡不僅會造成本身業務性能很長,還會嚴重影響其他正常業務的查詢。同理,寫請求不均衡,也會造成類似的影響。故HBase負載均衡是HBase集群性能的重要體現。

2.2.2 BlockCache優化

BlockCache作為讀緩存,合理設置對于提高讀性能非常重要。默認情況下,BlockCache和Memstore的配置各站40%,可以通過在hbase-site.xml配置以下屬性來實現:

  • hfile.block.cache.size,默認0.4,用來提高讀性能
  • hbase.regionserver.global.memstore.size,默認0.4,用來提高寫性能

本篇博客主要介紹提高讀性能,這里我們可以將BlockCache的占比設置大一些,Memstore的占比設置小一些(總占比保持在0.8即可)。另外,BlockCache的策略選擇也是很重要的,不同的策略對于讀性能來說影響不大,但是對于GC的影響卻比較明顯,在設置hbase.bucketcache.ioengine屬性為offheap時,GC表現的很優秀。緩存結構如下圖所示:

設置BlockCache可以在hbase-site.xml文件中,配置如下屬性:

<!-- 分配的內存大小盡可能的多些,前提是不能超過 (機器實際物理內存-JVM內存) --> <property> <name>hbase.bucketcache.size</name> <value>16384</value> </property> <property><name>hbase.bucketcache.ioengine</name><value>offheap</value> </property>

設置塊內存大小,可以參考入下表格:

標號描述計算公式或值結果
A物理內存選擇:on-heap(JVM)+off-heap(Direct)單臺物理節點內存值,單位MB262144
BHBASE_HEAPSIZE('-Xmx)單位MB20480
C-XX:MaxDirectMemorySize,off-heap允許的最大內存值A-B241664
Dphfile.block.cache.size和hbase.regionserver.global.memstore.size總和不要超過0.8讀取比例占比*0.80.5*0.8=0.4
DmJVM Heap允許的最大BlockCache(MB)B*Dp20480*0.4=8192
Ephbase.regionserver.global.memstore.size設置的最大JVM值0.8-Dp0.8-0.4=0.4
F用于其他用途的off-heap內存,例如DFSClient推薦1024到20482048
GBucketCache允許的off-heap內存C-F241664-2048=239616

另外,BlockCache策略,能夠有效的提高緩存命中率,這樣能夠間接的提高熱數據覆蓋率,從而提升讀取性能。

2.2.3 HFile優化

HBase讀取數據時會先從BlockCache中進行檢索(熱數據),如果查詢不到,才會到HDFS上去檢索。而HBase存儲在HDFS上的數據以HFile的形式存在的,文件如果越多,檢索所花費的IO次數也就必然增加,對應的讀取耗時也就增加了。文件數量取決于Compaction的執行策略,有以下2個屬性有關系:

  • hbase.hstore.compactionThreshold,默認為3,表示store中文件數超過3個就開始進行合并操作
  • hbase.hstore.compaction.max.size,默認為9223372036854775807,合并的文件最大閥值,超過這個閥值的文件不能進行合并

?另外,hbase.hstore.compaction.max.size值可以通過實際的Region總數來計算,公式如下:

hbase.hstore.compaction.max.size = RegionTotal / hbase.hstore.compactionThreshold

2.2.4 Compaction優化

Compaction操作是將小文件合并為大文件,提高后續業務隨機讀取的性能,但是在執行Compaction操作期間,節點IO、網絡帶寬等資源會占用較多,那么什么時候執行Compaction才最好?什么時候需要執行Compaction操作?

1.什么時候執行Compaction才最好?

實際應用場景中,會關閉Compaction自動執行策略,通過屬性hbase.hregion.majorcompaction來控制,將hbase.hregion.majorcompaction=0,就可以禁止HBase自動執行Compaction操作。一般情況下,選擇集群負載較低,資源空閑的時間段來定時調度執行Compaction。

如果合并的文件較多,可以通過設置如下屬性來提生Compaction的執行速度,配置如下:

<property><name>hbase.regionserver.thread.compaction.large</name><value>8</value><description></description> </property> <property><name>hbase.regionserver.thread.compaction.small</name><value>5</value><description></description> </property>

2.什么時候需要執行Compaction操作?

一般維護HBase集群后,由于集群發生過重啟,HBase數據本地性較低,通過HBase頁面可以觀察,此時如果不執行Compaction操作,那么客戶端查詢的時候,需要跨副本節點去查詢,這樣來回需要經過網絡帶寬,對比正常情況下,從本地節點讀取數據,耗時是比較大的。在執行Compaction操作后,HBase數據本地性為1,這樣能夠有效的提高查詢效率。

3.總結

本篇博客HBase查詢優化從客戶端和服務端角度,列舉一些常見有效地優化手段。當然,優化還需要從自己實際應用場景出發,例如代碼實現邏輯、物理機的實際配置等方面來設置相關參數。大家可以根據實際情況來參考本篇博客進行優化。

4.結束語

這篇博客就和大家分享到這里,如果大家在研究學習的過程當中有什么問題,可以加群進行討論或發送郵件給我,我會盡我所能為您解答,與君共勉!

另外,博主出書了《Hadoop大數據挖掘從入門到進階實戰》,喜歡的朋友或同學,?可以在公告欄那里點擊購買鏈接購買博主的書進行學習,在此感謝大家的支持。

轉載于:https://www.cnblogs.com/smartloli/p/9425343.html

總結

以上是生活随笔為你收集整理的HBase查询优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。