其實HBase還是比較靈活的,關鍵看你是否使用得當,以下主要列舉一些讀的最佳化。HBase在生產中往往會遇到Full GC、進程OOM、RIT問題、讀取延遲較大等一些問題,使用更好的硬體往往可以解決一部分問題,但是還是需要使用的方式。
我們把最佳化分為:
用戶端最佳化、服務端最佳化、平台最佳化(ApsaraDB for HBase)
用戶端最佳化
get請求是否可以使用批量請求
這樣可以成倍減小用戶端與服務端的rpc次數,顯著提高輸送量。
Result[] re= table.get(List<Get> gets)
大scan緩衝是否設定合理
scan一次性需求從服務端返回大量的資料,用戶端發起一次請求,服務端會分多批次返回用戶端,這樣的設計是避免一次性傳輸較多的資料給服務端及用戶端有較大的壓力。目前資料會載入到本地的緩衝中,預設100條資料大小。一些大scan需要擷取大量的資料,傳輸數百次甚至數萬的rpc請求。我們建議可以適當放開緩衝的大小。
scan.setCaching(int caching) //大scan可以設定為1000
請求指定列族或者列名
HBase是列族資料庫,同一個列族的資料存放區在一塊,不同列族是分開的,為了減小IO,建議指定列族或者列名。
離線計算訪問Hbase建議禁止緩衝
當離線訪問HBase時,往往就是一次性的讀取,此時讀取的資料沒有必要存放在blockcache中,建議在讀取時禁止緩衝。
scan.setBlockCache(false)
服務端最佳化
請求是否均衡
讀取的壓力是否都在一台或者幾台之中,在業務高峰期間可以查看下,可以到HBase管控平台查看HBase的UI。如果有明顯的熱點,一勞永逸的做法是重新設計rowkey,短期是把熱點地區嘗試拆分。
BlockCache是否合理
BlockCache作為讀緩衝,對於讀的效能比較重要,如果讀比較多,建議記憶體使用量1:4的機器,比如:8cpu32g或者16pu64g的機器。當前可以調高BlockCache的數值,降低Memstore的數值。
在ApsaraDB for HBase控制台可以完成:hfile.block.cache.size改為0.5 ; hbase.regionserver.global.memstore.size 改為0.3;再重啟。
HFile檔案數目
因為讀取需要頻繁開啟HFile,如果檔案越多,IO次數就越多,讀取的延遲就越高,此時需要定時做major compaction,如果晚上的業務壓力不大,可以在晚上做major compaction。
Compaction是否消耗較多的系統資源
compaction主要是將HFile的小檔案合并成大檔案,提高後續業務的讀效能,但是也會帶來較大的資源消耗。Minor Compaction一般情況下不會帶來大量的系統資源消耗,除非因為配置不合理。切勿在高峰期間做 major compaction。建議在業務低峰期做major compaction。
Bloomfilter設定是否合理
Bloomfilter主要用來在查詢時,過濾HFile的,避免不需要的IO操作。Bloomfilter能提高讀取的效能,一般情況下建立表,都會預設設定為:BLOOMFILTER =>‘ROW’
平台端最佳化
資料本地率是否太低?(平台已經最佳化)
Hbase 的HFile,在本地是否有檔案,如果有檔案可以用Short-Circuit Local Read,目前平台在重啟、磁碟擴容時,都會自動拉回移動出去的地區,不降低資料本地率;另外定期做major compaction也有益於提高本地化率。
Short-Circuit Local Read (已經預設開啟)
當前HDFS讀取資料需要經過DataNode,開啟Short-Circuit Local Read後,用戶端可以直接讀取本機資料。
Hedged Read (已經預設開啟)
優先會通過Short-Circuit Local Read功能嘗試本地讀。但是在某些特殊情況下,有可能會出現因為磁碟問題或者網路問題引起的短時間本地讀取失敗,為了應對這類問題,開發出了Hedged Read。該機制基本工作原理為:用戶端發起一個本地讀,一旦一段時間之後還沒有返回,用戶端將會向其他DataNode發送相同資料的請求。哪一個請求先返回,另一個就會被丟棄。
關閉swap區(已經預設關閉)
swap是當實體記憶體不足時,拿出部分的硬碟空間當做swap使用,解決記憶體不足的情況。但是會有較大的延遲的問題,所以我們HBase平台預設關閉。 但是關閉swap導致anon-rss很高,page reclaim沒辦法reclaim足夠的page,可能導致核心掛住,平台已經採取相關隔離措施避免此情況。