HBase最佳實踐-讀效能優化策略

hbase小能手發表於2018-12-28

任何系統都會有各種各樣的問題,有些是系統本身設計問題,有些卻是使用姿勢問題。HBase也一樣,在真實生產線上大家或多或少都會遇到很多問題,有些是HBase還需要完善的,有些是我們確實對它瞭解太少。總結起來,大家遇到的主要問題無非是Full GC異常導致當機問題、RIT問題、寫吞吐量太低以及讀延遲較大。

Full GC問題之前在一些文章裡面已經講過它的來龍去脈,主要的解決方案目前主要有兩方面需要注意,一方面需要檢視GC日誌確認是哪種Full GC,根據Full GC型別對JVM引數進行調優,另一方面需要確認是否開啟了BucketCache的offheap模式,建議使用LRUBlockCache的童鞋儘快轉移到BucketCache來。當然我們還是很期待官方2.0.0版本釋出的更多offheap模組。

RIT問題,我相信更多是因為我們對其不瞭解,具體原理可以戳這裡,解決方案目前有兩個,優先是使用官方提供的HBCK進行修復(HBCK本人一直想拿出來分享,但是目前案例還不多,等後面有更多案例的話再拿出來說),使用之後還是解決不了的話就需要手動修復檔案或者後設資料表。

而對於寫吞吐量太低以及讀延遲太大的優化問題,筆者也和很多朋友進行過探討,這篇文章就以讀延遲優化為核心內容展開,具體分析HBase進行讀延遲優化的那些套路,以及這些套路之後的具體原理。希望大家在看完之後能夠結合這些套路剖析自己的系統。

一般情況下,讀請求延遲較大通常存在三種場景,分別為:

1. 僅有某業務延遲較大,叢集其他業務都正常

2. 整個叢集所有業務都反映延遲較大

3. 某個業務起來之後叢集其他部分業務延遲較大

這三種場景是表象,通常某業務反應延遲異常,首先需要明確具體是哪種場景,然後針對性解決問題。下圖是對讀優化思路的一點總結,主要分為四個方面:客戶端優化、伺服器端優化、列族設計優化以及HDFS相關優化,下面每一個小點都會按照場景分類,文章最後進行歸納總結。下面分別進行詳細講解:



hbase1

HBase客戶端優化

和大多數系統一樣,客戶端作為業務讀寫的入口,姿勢使用不正確通常會導致本業務讀延遲較高實際上存在一些使用姿勢的推薦用法,這裡一般需要關注四個問題:

1. scan快取是否設定合理?

優化原理:在解釋這個問題之前,首先需要解釋什麼是scan快取,通常來講一次scan會返回大量資料,因此客戶端發起一次scan請求,實際並不會一次就將所有資料載入到本地,而是分成多次RPC請求進行載入,這樣設計一方面是因為大量資料請求可能會導致網路頻寬嚴重消耗進而影響其他業務,另一方面也有可能因為資料量太大導致本地客戶端發生OOM。在這樣的設計體系下使用者會首先載入一部分資料到本地,然後遍歷處理,再載入下一部分資料到本地處理,如此往復,直至所有資料都載入完成。資料載入到本地就存放在scan快取中,預設100條資料大小。

通常情況下,預設的scan快取設定就可以正常工作的。但是在一些大scan(一次scan可能需要查詢幾萬甚至幾十萬行資料)來說,每次請求100條資料意味著一次scan需要幾百甚至幾千次RPC請求,這種互動的代價無疑是很大的。因此可以考慮將scan快取設定增大,比如設為500或者1000就可能更加合適。筆者之前做過一次試驗,在一次scan掃描10w+條資料量的條件下,將scan快取從100增加到1000,可以有效降低scan請求的總體延遲,延遲基本降低了25%左右。

優化建議:大scan場景下將scan快取從100增大到500或者1000,用以減少RPC次數

2. get請求是否可以使用批量請求?

優化原理:HBase分別提供了單條get以及批量get的API介面,使用批量get介面可以減少客戶端到RegionServer之間的RPC連線數,提高讀取效能。另外需要注意的是,批量get請求要麼成功返回所有請求資料,要麼丟擲異常。

優化建議:使用批量get進行讀取請求

3. 請求是否可以顯示指定列族或者列?

優化原理:HBase是典型的列族資料庫,意味著同一列族的資料儲存在一起,不同列族的資料分開儲存在不同的目錄下。如果一個表有多個列族,只是根據Rowkey而不指定列族進行檢索的話不同列族的資料需要獨立進行檢索,效能必然會比指定列族的查詢差很多,很多情況下甚至會有2倍~3倍的效能損失。

優化建議:可以指定列族或者列進行精確查詢的儘量指定查詢

4. 離線批量讀取請求是否設定禁止快取?

優化原理:通常離線批量讀取資料會進行一次性全表掃描,一方面資料量很大,另一方面請求只會執行一次。這種場景下如果使用scan預設設定,就會將資料從HDFS載入出來之後放到快取。可想而知,大量資料進入快取必將其他實時業務熱點資料擠出,其他業務不得不從HDFS載入,進而會造成明顯的讀延遲毛刺

優化建議:離線批量讀取請求設定禁用快取,scan.setBlockCache(false)

HBase伺服器端優化

一般服務端端問題一旦導致業務讀請求延遲較大的話,通常是叢集級別的,即整個叢集的業務都會反映讀延遲較大。可以從4個方面入手:

5. 讀請求是否均衡?

優化原理:極端情況下假如所有的讀請求都落在一臺RegionServer的某幾個Region上,這一方面不能發揮整個叢集的併發處理能力,另一方面勢必造成此臺RegionServer資源嚴重消耗(比如IO耗盡、handler耗盡等),落在該臺RegionServer上的其他業務會因此受到很大的波及。可見,讀請求不均衡不僅會造成本身業務效能很差,還會嚴重影響其他業務。當然,寫請求不均衡也會造成類似的問題,可見負載不均衡是HBase的大忌。

觀察確認:觀察所有RegionServer的讀請求QPS曲線,確認是否存在讀請求不均衡現象

優化建議:RowKey必須進行雜湊化處理(比如MD5雜湊),同時建表必須進行預分割槽處理

6. BlockCache是否設定合理?

優化原理:BlockCache作為讀快取,對於讀效能來說至關重要。預設情況下BlockCache和Memstore的配置相對比較均衡(各佔40%),可以根據叢集業務進行修正,比如讀多寫少業務可以將BlockCache佔比調大。另一方面,BlockCache的策略選擇也很重要,不同策略對讀效能來說影響並不是很大,但是對GC的影響卻相當顯著,尤其BucketCache的offheap模式下GC表現很優越。另外,HBase 2.0對offheap的改造(HBASE-11425)將會使HBase的讀效能得到2~4倍的提升,同時GC表現會更好!

觀察確認:觀察所有RegionServer的快取未命中率、配置檔案相關配置項一級GC日誌,確認BlockCache是否可以優化

優化建議:JVM記憶體配置量 < 20G,BlockCache策略選擇LRUBlockCache;否則選擇BucketCache策略的offheap模式;期待HBase 2.0的到來!

7. HFile檔案是否太多?

優化原理:HBase讀取資料通常首先會到Memstore和BlockCache中檢索(讀取最近寫入資料&熱點資料),如果查詢不到就會到檔案中檢索。HBase的類LSM結構會導致每個store包含多數HFile檔案,檔案越多,檢索所需的IO次數必然越多,讀取延遲也就越高。檔案數量通常取決於Compaction的執行策略,一般和兩個配置引數有關:hbase.hstore.compactionThreshold和hbase.hstore.compaction.max.size,前者表示一個store中的檔案數超過多少就應該進行合併,後者表示引數合併的檔案大小最大是多少,超過此大小的檔案不能參與合併。這兩個引數不能設定太’鬆’(前者不能設定太大,後者不能設定太小),導致Compaction合併檔案的實際效果不明顯,進而很多檔案得不到合併。這樣就會導致HFile檔案數變多。

觀察確認:觀察RegionServer級別以及Region級別的storefile數,確認HFile檔案是否過多

優化建議:hbase.hstore.compactionThreshold設定不能太大,預設是3個;設定需要根據Region大小確定,通常可以簡單的認為hbase.hstore.compaction.max.size = RegionSize / hbase.hstore.compactionThreshold

8. Compaction是否消耗系統資源過多?

優化原理:Compaction是將小檔案合併為大檔案,提高後續業務隨機讀效能,但是也會帶來IO放大以及頻寬消耗問題(資料遠端讀取以及三副本寫入都會消耗系統頻寬)。正常配置情況下Minor Compaction並不會帶來很大的系統資源消耗,除非因為配置不合理導致Minor Compaction太過頻繁,或者Region設定太大情況下發生Major Compaction。

觀察確認:觀察系統IO資源以及頻寬資源使用情況,再觀察Compaction佇列長度,確認是否由於Compaction導致系統資源消耗過多

優化建議:

(1)Minor Compaction設定:hbase.hstore.compactionThreshold設定不能太小,又不能設定太大,因此建議設定為5~6;hbase.hstore.compaction.max.size = RegionSize / hbase.hstore.compactionThreshold

(2)Major Compaction設定:大Region讀延遲敏感業務( 100G以上)通常不建議開啟自動Major Compaction,手動低峰期觸發。小Region或者延遲不敏感業務可以開啟Major Compaction,但建議限制流量;

(3)期待更多的優秀Compaction策略,類似於stripe-compaction儘早提供穩定服務

HBase列族設計優化

HBase列族設計對讀效能影響也至關重要,其特點是隻影響單個業務,並不會對整個叢集產生太大影響。列族設計主要從兩個方面檢查:

9. Bloomfilter是否設定?是否設定合理?

優化原理:Bloomfilter主要用來過濾不存在待檢索RowKey或者Row-Col的HFile檔案,避免無用的IO操作。它會告訴你在這個HFile檔案中是否可能存在待檢索的KV,如果不存在,就可以不用消耗IO開啟檔案進行seek。很顯然,通過設定Bloomfilter可以提升隨機讀寫的效能。

Bloomfilter取值有兩個,row以及rowcol,需要根據業務來確定具體使用哪種。如果業務大多數隨機查詢僅僅使用row作為查詢條件,Bloomfilter一定要設定為row,否則如果大多數隨機查詢使用row+cf作為查詢條件,Bloomfilter需要設定為rowcol。如果不確定業務查詢型別,設定為row。

優化建議:任何業務都應該設定Bloomfilter,通常設定為row就可以,除非確認業務隨機查詢型別為row+cf,可以設定為rowcol

HDFS相關優化

HDFS作為HBase最終資料儲存系統,通常會使用三副本策略儲存HBase資料檔案以及日誌檔案。從HDFS的角度望上層看,HBase即是它的客戶端,HBase通過呼叫它的客戶端進行資料讀寫操作,因此HDFS的相關優化也會影響HBase的讀寫效能。這裡主要關注如下三個方面:

10. Short-Circuit Local Read功能是否開啟?

優化原理:當前HDFS讀取資料都需要經過DataNode,客戶端會向DataNode傳送讀取資料的請求,DataNode接受到請求之後從硬碟中將檔案讀出來,再通過TPC傳送給客戶端。Short Circuit策略允許客戶端繞過DataNode直接讀取本地資料。(具體原理參考此處

優化建議:開啟Short Circuit Local Read功能,具體配置戳這裡

11. Hedged Read功能是否開啟?

優化原理:HBase資料在HDFS中一般都會儲存三份,而且優先會通過Short-Circuit Local Read功能嘗試本地讀。但是在某些特殊情況下,有可能會出現因為磁碟問題或者網路問題引起的短時間本地讀取失敗,為了應對這類問題,社群開發者提出了補償重試機制 – Hedged Read。該機制基本工作原理為:客戶端發起一個本地讀,一旦一段時間之後還沒有返回,客戶端將會向其他DataNode傳送相同資料的請求。哪一個請求先返回,另一個就會被丟棄。 

優化建議:開啟Hedged Read功能,具體配置參考這裡

12. 資料本地率是否太低?

資料本地率:HDFS資料通常儲存三份,假如當前RegionA處於Node1上,資料a寫入的時候三副本為(Node1,Node2,Node3),資料b寫入三副本是(Node1,Node4,Node5),資料c寫入三副本(Node1,Node3,Node5),可以看出來所有資料寫入本地Node1肯定會寫一份,資料都在本地可以讀到,因此資料本地率是100%。現在假設RegionA被遷移到了Node2上,只有資料a在該節點上,其他資料(b和c)讀取只能遠端跨節點讀,本地率就為33%(假設a,b和c的資料大小相同)。

優化原理:資料本地率太低很顯然會產生大量的跨網路IO請求,必然會導致讀請求延遲較高,因此提高資料本地率可以有效優化隨機讀效能。資料本地率低的原因一般是因為Region遷移(自動balance開啟、RegionServer當機遷移、手動遷移等),因此一方面可以通過避免Region無故遷移來保持資料本地率,另一方面如果資料本地率很低,也可以通過執行major_compact提升資料本地率到100%。

優化建議:避免Region無故遷移,比如關閉自動balance、RS當機及時拉起並遷回飄走的Region等;在業務低峰期執行major_compact提升資料本地率

HBase讀效能優化歸納

在本文開始的時候提到讀延遲較大無非三種常見的表象,單個業務慢、叢集隨機讀慢以及某個業務隨機讀之後其他業務受到影響導致隨機讀延遲很大。瞭解完常見的可能導致讀延遲較大的一些問題之後,我們將這些問題進行如下歸類,讀者可以在看到現象之後在對應的問題列表中進行具體定位:

hbase2

hbase3

hbase4

HBase讀效能優化總結

效能優化是任何一個系統都會遇到的話題,每個系統也都有自己的優化方式。 HBase作為分散式KV資料庫,優化點又格外不同,更多得融入了分散式特性以及儲存系統優化特性。文中總結了讀優化的基本突破點,有什麼不對的地方還望指正,有補充的也可以一起探討交流!


相關文章