HBase最佳化實戰
轉載自:https://mp.weixin.qq.com/s/3AAy2LIQPxWivfFVrk4iew
背景
Datastream一直以來在使用HBase分流日誌,每天的資料量很大,日均大概在80億條,10TB的資料。對於像Datastream這種資料量巨大、對寫入要求非常高,並且沒有複雜查詢需求的日誌系統來說,選用HBase作為其資料儲存平臺,無疑是一個非常不錯的選擇。
HBase是一個相對較複雜的分散式系統,併發寫入的效能非常高。然而,分散式系統從結構上來講,也相對較複雜,模組繁多,各個模組之間也很容易出現一些問題,所以對像HBase這樣的大型分散式系統來說,最佳化系統執行,及時解決系統執行過程中出現的問題也變得至關重要。正所謂:“你”若安好,便是晴天;“你”若有恙,我便沒有星期天。
歷史現狀
HBase交接到我們團隊手上時,已經線上上執行有一大段時間了,期間也偶爾聽到過系統不穩定的、時常會出現一些問題的言論,但我們認為:一個能被大型網際網路公司廣泛採用的系統(包括Facebook,twitter,淘寶,小米等),其在效能和可用性上是毋庸置疑的,何況像Facebook這種公司,是在經過嚴格選型後,放棄了自己開發的Cassandra系統,用HBase取而代之。既然這樣,那麼,HBase的不穩定、經常出問題一定有些其他的原因,我們所要做的,就是找出這些HBase的不穩定因素,還HBase一個“清白”。“查案”之前,先來簡單回顧一下我們接手HBase時的現狀(我們運維著好幾個HBase叢集,這裡主要介紹問題最多那個叢集的調優):
名稱 |
數量 |
備註 |
伺服器數量 |
17 |
配置不同,HBase、HDFS都部署在這些機器上 |
表數量 |
30+ |
只有部分表的資料量比較大,其他基本沒多少資料 |
Region數量 |
600+ |
基本上都是資料量較大的表劃分的region較多 |
請求量 |
50000+ |
伺服器請求分佈極其不均勻 |
應用反應經常會過段時間出現資料寫入緩慢,導致應用端資料堆積現象,是否可以透過增加機器數量來解決?
其實,那個時候,我們本身對HBase也不是很熟悉,對HBase的瞭解,也僅僅在做過一些測試,瞭解一些效能,對內部結構,實現原理之類的基本上都不怎麼清楚。於是剛開始幾天,各種問題,每天晚上拉著一男一起摸索,順利的時候,晚上8,9點就可以暫時搞定線上問題,更多的時候基本要到22點甚至更晚(可能那個時候流量也下去了),透過不斷的摸索,慢慢了解HBase在使用上的一些限制,也就能逐漸解決這一系列過程中發現的問題。後面挑幾個相對比較重要,效果較為明顯的改進點,做下簡單介紹。
調優
首先根據目前17臺機器,50000+的QPS,並且觀察磁碟的I/O利用率和CPU利用率都相當低來判斷:當前的請求數量根本沒有達到系統的效能瓶頸,不需要新增機器來提高效能。如果不是硬體資源問題,那麼效能的瓶頸究竟是什麼?
Rowkey設計問題
現象
開啟HBase的Web端,發現HBase下面各個RegionServer的請求數量非常不均勻,第一個想到的就是HBase的熱點問題,具體到某個具體表上的請求分佈如下:
HBase表請求分佈
上面是HBase下某張表的region請求分佈情況,從中我們明顯可以看到,部分region的請求數量為0,而部分的請求數量可以上百萬,這是一個典型的熱點問題。
原因
HBase出現熱點問題的主要原因無非就是rowkey設計的合理性,像上面這種問題,如果rowkey設計得不好,很容易出現,比如:用時間戳生成rowkey,由於時間戳在一段時間內都是連續的,導致在不同的時間段,訪問都集中在幾個RegionServer上,從而造成熱點問題。
解決
知道了問題的原因,對症下藥即可,聯絡應用修改rowkey規則,使rowkey資料隨機均勻分佈,效果如下:
Rowkey重定義後請求分佈
建議
對於HBase來說,rowkey的範圍劃定RegionServer,每一段rowkey區間對應一個RegionServer,我們要 保證每段時間內的rowkey訪問都是均勻的 ,所以我們在設計的時候, 儘量要以hash或者md5等開頭來組織rowkey 。
Region重分佈
現象
HBase的叢集是在不斷擴充套件的,分散式系統的最大好處除了效能外,不停服橫向擴充套件也是其中之一,擴充套件過程中有一個問題:每次擴充套件的機器的配置是不一樣的,一般,後面新加入的機器效能會比老的機器好,但是後面加入的機器經常被分配很少的region,這樣就造成了資源分佈不均勻,隨之而來的就是效能上的損失,如下:
HBase各個RegionServer請求
上圖中我們可以看到,每臺RegionServer上的請求極為不均勻,多的好幾千,少的只有幾十。
原因
資源分配不均勻,造成部分機器壓力較大,部分機器負載較低,並且部分Region過大過熱,導致請求相對較集中。
解決
遷移部分老的RegionServer上的region到新加入的機器上,使每個RegionServer的負載均勻。透過split切分部分較大region,均勻分佈熱點region到各個RegionServer上。
HBase Region請求分佈
對比前後兩張截圖我們可以看到,Region總數量從1336增加到了1426,而增加的這90個region就是透過split切分大的region得到的。而對region重新分佈後,整個HBase的效能有了大幅度提高。
建議
Region遷移的時候不能簡單開啟自動balance ,因為balance主要的問題是不會根據表來進行balance,HBase的自動balance只會根據每個RegionServer上的Region數量來進行balance,所以自動balance可能會造成同張表的region會被集中遷移到同一個臺RegionServer上,這樣就達不到分散式的效果。
基本上,新增RegionServer後的region調整,可以手工進行,儘量使表的Region都平均分配到各個RegionServer上,另外一點,新增的RegionServer機器,配置最好與前面的一致,否則資源無法更好利用。
對於過大,過熱的region,可以透過切分的方法生成多個小region後均勻分佈(注意:region切分會觸發major compact操作,會帶來較大的I/O請求,請務必在業務低峰期進行)。
HDFS寫入超時
現象
HBase寫入緩慢,檢視HBase日誌,經常有慢日誌如下:
WARN org.apache.hadoop.ipc.HBaseServer- (responseTooSlow): {
"processingtimems"
:
36096
,
"call"
:
"multi(org.apache.hadoop.hbase.client.MultiAction@7884377e), rpc version=1, client version=29, methodsFingerPrint=1891768260"
,
"client"
:
"xxxx.xxx.xxx.xxxx:44367"
,
"starttimems"
:
1440239670790
,
"queuetimems"
:
42081
,
"class"
:
"HRegionServer"
,
"responsesize"
:
,
"method"
:
"multi"
}
並且伴有HDFS建立block異常如下:
INFO org.apache.hadoop.hdfs.DFSClient - Exception
in
createBlockOutputStream
org.apache.hadoop.hdfs.protocol.HdfsProtoUtil.vintPrefixed(HdfsProtoUtil.java:171)
org.apache.hadoop.hdfs.DFSOutputStream
$DataStreamer
.createBlockOutputStream(DFSOutputStream.java:1105)
org.apache.hadoop.hdfs.DFSOutputStream
$DataStreamer
.nextBlockOutputStream(DFSOutputStream.java:1039)
org.apache.hadoop.hdfs.DFSOutputStream
$DataStreamer
.run(DFSOutputStream.java:487)
一般地,HBase客戶端的寫入到RegionServer下某個region的memstore後就返回,除了網路外,其他都是記憶體操作,應該不會有長達30多秒的延遲,外加HDFS層丟擲的異常,我們懷疑很可能跟底層資料儲存有關。
原因
定位到可能是HDFS層出現了問題,那就先從底層開始排查,發現該臺機器上10塊盤的空間利用率都已經達到100%。按理說,作為一個成熟的分散式檔案系統,對於部分資料盤滿的情況,應該有其應對措施。的確,HDFS本身可以設定資料盤預留空間,如果部分資料盤的預留空間小於該值時,HDFS會自動把資料寫入到另外的空盤上面,那麼我們這個又是什麼情況?
最終透過多方面的溝通確認,發現了主要原因:我們這批機器,在上線前SA已經經過處理,每塊盤預設預留100G空間,所以當透過df命令檢視盤使用率為100%時,其實盤還有100G的預留空間,而HDFS層面我們配置的預留空間是50G,那麼問題就來了:HDFS認為盤還有100G空間,並且多於50G的預留,所以資料可以寫入本地盤,但是系統層面卻禁止了該寫入操作,從而導致資料寫入異常。
解決
解決的方法可以讓SA釋放些空間出來便於資料寫入。當然,最直接有效的就是把HDFS的預留空間調整至100G以上,我們也正是這樣做的,透過調整後,異常不再出現,HBase層面的slow log也沒有再出現。同時我們也開啟了HDFS層面的balance,使資料自動在各個伺服器之間保持平衡。
建議
磁碟滿了導致的問題很難預料,HDFS可能會導致部分資料寫入異常,MySQL可能會出現直接當機等等,所以最好的辦法就是: 不要使盤的利用率達到100% 。
網路拓撲
現象
透過rowkey調整,HDFS資料balance等操作後,HBase的確穩定了許多,在很長一段時間都沒有出現寫入緩慢問題,整體的效能也上漲了很多。但時常會隔一段時間出現些slow log,雖然對整體的效能影響不大,但效能上的抖動還是很明顯。
原因
由於該問題不經常出現,對系統的診斷帶來不小的麻煩,排查了HBase層和HDFS層,幾乎一無所獲,因為在大多數情況下,系統的吞吐量都是正常的。透過指令碼收集RegionServer所在伺服器的系統資源資訊,也看不出問題所在,最後懷疑到系統的物理拓撲上,HBase叢集的最大特點是資料量巨大,在做一些操作時,很容易把物理機的千兆網路卡都吃滿,這樣如果網路拓撲結構存在問題,HBase的所有機器沒有部署在同一個交換機上,上層交換機的進出口流量也有可能存在瓶頸。網路測試還是挺簡單的,直接ping就可以,我們得到以下結果:共17臺機器,只有其中一臺的延遲存在問題,如下:
網路延遲測試:Ping結果
同一個區域網內的機器,延遲達到了毫秒級別,這個延遲是比較致命的,因為分散式儲存系統HDFS本身對網路有要求,HDFS預設3副本存在不同的機器上,如果其中某臺機器的網路存在問題,這樣就會影響到該機器上儲存副本的寫入,拖慢整個HDFS的寫入速度。
解決
網路問題,聯絡機房解決,機房的反饋也驗證了我們的想法:由於HBase的機器後面進行了擴充套件,後面加入的機器有一臺跟其他機器不在同一個交換機下,而這臺機器正是我們找出的有較大ping延時這臺,整個HBase物理結構如下:
HBase物理拓撲結構
跟機房協調,調整機器位置,使所有的HBase機器都位於同一個交換機下,問題迎刃而解。
建議
對於分散式大流量的系統,除了系統本身,物理機的部署和流量規劃也相當重要,儘量使叢集中所有的機器位於相同的交換機下(有容災需求的應用除外),叢集較大,需要跨交換機部署時,也要充分考慮交換機的出口流量是否夠用,網路硬體上的瓶頸診斷起來相對更為困難。
JVM引數調整
解決了網路上面的不穩定因素,HBase的效能又得到進一步的提高,隨之也帶來另外的問題。
現象
根據應用反應,HBase會階段性出現效能下降,導致應用資料寫入緩慢,造成應用端的資料堆積,這又是怎麼回事?經過一系列改善後HBase的系統較之以前有了大幅度增長,怎麼還會出現資料堆積的問題?為什麼會階段性出現?
從上圖看,HBase平均流量QPS基本能達到12w,但是每過一段時間,流量就會下降到接近零點,同時這段時間,應用會反應資料堆積。
原因
這個問題定位相對還是比較簡單,結合HBase的日誌,很容易找到問題所在:
org.apache.hadoop.hbase.util.Sleeper - We slept
41662
ms instead
of
3000
ms, this
is
likely due
to
a
long
garbage collecting pause
and
it
's usually bad
透過上述日誌,基本上可以判定是HBase的某臺RegionServer出現GC問題,導致了服務在很長一段時間內禁止訪問。
HBase透過一系列的調整後,整個系統的吞吐量增加了好幾倍,然而JVM的堆大小沒有進行相應的調整,整個系統的記憶體需求變大,而虛擬機器又來不及回收,最終導致出現Full GC。
解決
GC問題導致HBase整個系統的請求下降,透過適當調整JVM引數的方式,解決HBase RegionServer的GC問題。
建議
對於HBase來說,本身不存在單點故障,即使宕掉1,2臺RegionServer,也只是使剩下幾臺的壓力有所增加,不會導致整個叢集服務能力下降很多。但是,如果其中某臺RegionServer出現Full GC問題,那麼這臺機器上所有的訪問都會被掛起,客戶端請求一般都是batch傳送的,rowkey的隨機分佈導致部分請求會落到該臺RegionServer上,這樣該客戶端的請求就會被阻塞,導致客戶端無法正常寫資料到HBase。所以,對於HBase來說,當機並不可怕,但長時間的Full GC是比較致命的,配置JVM引數的時候,儘量要考慮避免Full GC的出現。
後記
經過前面一系列的最佳化,目前Datastream的這套HBase線上環境已經相當穩定,連續執行幾個月都沒有任何HBase層面由於系統效能不穩定導致的報警,平均效能在各個時間段都比較穩定,沒有出現過大幅度的波動或者服務不可用等現象。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31511218/viewspace-2213356/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- HBase2實戰:HBase Flink和Kafka整合Kafka
- HBase BulkLoad批量寫入資料實戰
- redis實戰最佳化二Redis
- 線上最佳化之案例實戰
- HBase 在統一內容平臺業務的最佳化實踐
- Spark+Hbase 億級流量分析實戰( PV/UV )Spark
- Hadoop大資料實戰系列文章之HBaseHadoop大資料
- 線上業務最佳化之案例實戰
- 如何正確管理HBase的連線,從原理到實戰
- Spark+Hbase 億級流量分析實戰( 留存計算)Spark
- HBase實操:HBase-Spark-Read-Demo 分享Spark
- 如何使用HBase?大資料儲存的兩個實戰場景大資料
- 網站人工最佳化實戰:專業、高效的網站最佳化!網站
- DataLeap資料資產實戰:如何實現儲存最佳化?
- Spark+Hbase 億級流量分析實戰(日誌儲存設計)Spark
- 智慧配送系統的運籌最佳化實戰
- 介面最佳化的常見方案實戰總結
- Hadoop2.7實戰v1.0之HBase1.1.5 HA分散式搭建Hadoop分散式
- nginx基礎版本專案實戰包含最佳化(六)Nginx
- 高併發快取架構實戰和最佳化快取架構
- Rust 中的 HashMap 實戰指南:理解與最佳化技巧RustHashMap
- Django效能之道:快取應用與最佳化實戰Django快取
- 「從零單排HBase 10」HBase叢集多租戶實踐
- 阿里HBase高可用8年“抗戰”回憶錄阿里
- Apache HBase MTTR 優化實踐Apache優化
- 實戰Nginx與PHP(FastCGI)的安裝、配置與最佳化NginxPHPAST
- Elasticsearch 億級資料檢索效能最佳化案例實戰!Elasticsearch
- Hbase(二)Hbase常用操作
- HBase Memstore專屬JVM策略MSLAB機制深入剖析-OLAP商業環境實戰JVM
- HBase 核心元件協調及RegionServer JVM引數調優-OLAP商業環境實戰元件ServerJVM
- HBase實戰:記一次Safepoint導致長時間STW的踩坑之旅
- 【Spark實戰】Spark操作HBase問題:java.io.IOException: Non-increasing Bloom keysSparkJavaExceptionOOM
- Springboot實戰——黑馬點評之秒殺最佳化Spring Boot
- HBase 教程:什麼是 HBase?
- HBase篇--HBase常用優化優化
- hbase - [04] java訪問hbaseJava
- HBase
- HBase篇--HBase操作Api和Java操作Hbase相關ApiAPIJava