【問題1】HBase Shell:ERROR: org.apache.hadoop.hbase.IPc.ServerNotRunningYetException: Server is not running yet
原因:hadoop處於safe mode
hadoop dfsadmin -safemode get 查看hadoop當前啟動狀態是否為safe mode
hadoop dfsadmin -safemode leave 退出
【問題2】Rowkey設計問題
現象
打開HBase的Web端,發現HBase下面各個RegionServer的請求數量非常不均勻,第一個想到的就是HBase的熱點問題,上面是HBase下某張表的region請求分布情況,從中我們明顯可以看到,部分region的請求數量為0,而部分的請求數量可以上百萬,這是一個典型的熱點問題。
原因
HBase出現熱點問題的主要原因無非就是rowkey設計的合理性,像上面這種問題,如果rowkey設計得不好,很容易出現,比如:用時間戳生成rowkey,由於時間戳在一段時間內都是連續的,導致在不同的時間段,訪問都集中在幾個RegionServer上,從而造成熱點問題。
解決
知道了問題的原因,對症下葯即可,聯系應用修改rowkey規則,使rowkey數據隨機均勻分布
建議
對於HBase來說,rowkey的范圍划定了RegionServer,每一段rowkey區間對應一個RegionServer,我們要保證每段時間內的rowkey訪問都是均勻的,所以我們在設計的時候,盡量要以hash或者md5等開頭來組織rowkey
【問題3】Region重分布
現象
HBase的集群是在不斷擴展的,分布式系統的最大好處除了性能外,不停服橫向擴展也是其中之一,擴展過程中有一個問題:每次擴展的機器的配置是不一樣的,一般,后面新加入的機器性能會比老的機器好,但是后面加入的機器經常被分配很少的region,這樣就造成了資源分布不均勻,隨之而來的就是性能上的損失
每台RegionServer上的請求極為不均勻,多的好幾千,少的只有幾十
原因
資源分配不均勻,造成部分機器壓力較大,部分機器負載較低,並且部分Region過大過熱,導致請求相對較集中。
解決
遷移部分老的RegionServer上的region到新加入的機器上,使每個RegionServer的負載均勻。通過split切分部分較大region,均勻分布熱點region到各個RegionServer上。
對比前后兩張截圖我們可以看到,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請求,請務必在業務低峰期進行)
【問題4】JVM參數調整
GC問題導致HBase整個系統的請求下降,通過適當調整JVM參數的方式,解決HBase RegionServer的GC問題。
export HBASE_REGIONSERVER_OPT="-Xmx8g -Xms8g -Xmn128m -XX:+UseParNewGC -XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -verbose:gc -XX:+printGCDetails -XX:+PrintGCTimeStamps -Xloggc:${HBASE_HOME}/logs/gc-${hostname}-hbase.log
建議
對於HBase來說,本身不存在單點故障,即使宕掉1,2台RegionServer,也只是使剩下幾台的壓力有所增加,不會導致整個集群服務能力下降很多。但是,如果其中某台RegionServer出現Full GC問題,那么這台機器上所有的訪問都會被掛起,客戶端請求一般都是batch發送的,rowkey的隨機分布導致部分請求會落到該台RegionServer上,這樣該客戶端的請求就會被阻塞,導致客戶端無法正常寫數據到HBase。所以,對於HBase來說,宕機並不可怕,但長時間的Full GC是比較致命的,配置JVM參數的時候,盡量要考慮避免Full GC的出現。
【問題5】堆內存溢出的問題
java.lang.OutOfMemoryError
從錯誤本身可以發現是堆錯誤,很明顯是設置的值太小而導致這樣錯誤。
在hadoop開始配置的時候,在hadoop/etc/hadoop/目錄下的hadoop-env.sh文件中
export HADOOP_HEAPSIZE=
是被注釋掉的,查看上面的注釋,這個值默認為1000,單位為Mb
這里去掉注釋,修改為4000,需要注意的是這里要根據內存大小來選擇值
export HADOOP_HEAPSIZE=4000
export HBASE_HEAPSIZE=1024
【問題6】drop表
drop 表后,會現 hadoop.hbase.catalog.MetaReader - No serialized HRegionInfo in keyvalues的警告,通過命令修復:
【問題7】Region Server 意外退出
1.1 背景
報錯信息如下:
ERROR org.apache.hadoop.hbase.regionserver.HRegionServer: ZooKeeper session expired
之后, regionserver就退出了。
對於一個 reigonserver, 它需要將自己注冊到 Zookeeper 上 master 的 Znode 上。這樣的目的,是當master 宕機或者新的master啟動的時候,能及時收到通知。對於 regionserver來說,維持和 Zookeeper 的聯系是非常重要的。因為 regionserver 需要定期的將心跳包發給 master server。如果 regionserver 不能及時的知道 master 的改變,就會導致 regionserver 和 master 失去聯系,而成為一個僵死的進程。
於是,在默認情況下,regionserver 遇到這種情況,就選擇退出。
1.2 原因
為什么 regionserver 和Zookeeper的session expired? 可能的原因有
網絡不好
Java full GC, 這會 block 所有的線程。如果時間比較長,也會導致 session expired
1.3 解決辦法
將 Zookeeper 的 timeout 時間加長
<property>
<name>zookeeper.session.timeout</name>
<value>120000</value>
</property>
配置“hbase.regionserver.restart.on.zk.expire” 為true
這樣子,遇到 ZooKeeper session expired , regionserver 將選擇 restart 而不是 abort
為了避免 java full GC suspend thread 對Zookeeper heartbeat 的影響,我們還需要對 hbase-env.sh進行配置。
將
export HBASE_OPTS="$HBASE_OPTS -XX:+HeapDumpOnOutOfMemoryError \
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode"
修改成
export HBASE_OPTS="$HBASE_OPTS -XX:+HeapDumpOnOutOfMemoryError
-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-XX:+UseCMSInitiatingOccupancyOnly -XX:+UseParNewGC -Xmn256m"
【問題8】如何提高HBase客戶端的讀寫性能?請舉例說明。
①開啟bloomfilter過濾器,開啟bloomfilter比沒開啟要快3、4倍
②Hbase對於內存有特別的嗜好,在硬件允許的情況下配足夠多的內存給它
③通過修改hbase-env.sh中的
export HBASE_HEAPSIZE=3000 #這里默認為1000m
④增大RPC數量
通過修改hbase-site.xml中的
hbase.regionserver.handler.count屬性,可以適當的放大。默認值為10有點小
【問題9】斷電后regionserver丟失
故障原因
可能是虛擬主機突然斷電,hbase的所有節點都在這個虛擬機上,因此全部停機。啟動起來后,發現很多region丟失:is not online。
檢測HDFS文件是否損壞
使用hadoop命令: hadoop fsck / , 可以看到/ 目錄下fs是否是Healthy。
查看-ROOT-、.META.表的狀態
通過可視化界面查看-ROOT-、.META.表的狀態是否正常。
http://hmaster:60010/master-status
看到只有-ROOT-表,而沒有了.META.表,說明meta表損壞,而數據並未丟失。
通過scan ‘.META.’ 確定META表在Region Server2上,而Region Server 2在hbase啟動后,過一段時間后,IPC端口就不通了,master無法與region server通訊,無法stop,也無法執行修復命令。
所以需要在hbase服務啟動后,在正常狀態時,迅速執行修復命令。
zookeeper上存儲hbase 基本信息,可以刪除后,重新啟動,會重新自動創建。
[hbase@hmaster hb]$ hbase-0.94.27/bin/hbase zkcli
[zk: hslave1,hmaster,hslave2:2181(CONNECTED) 1] ls /hbase
[splitlog, online-snapshot, unassigned, root-region-server, table92, backup-masters, rs, table, draining, master, shutdown, hbaseid]
通過查看region信息,發現很多表的region都缺失了。
使用修復meta命令,發現問題依然存在,然后嘗試修復assignments,ok。
[hbase@hmaster hb]$ hbase-0.94.27/bin/hbase hbck -fixAssignments
- 再次確認所有的用戶表
通過可視化界面,可以看到所有的表的region信息,之前由於有些表的region信息丟失導致異常,通過http://hmaster:60010/master-status確認所有的表的regions全部恢復。
- hbase hbck 修復命令
問題分析的主要手段
1、監控系統:首先用於判斷系統各項指標是否正常,明確系統目前狀況
2、服務端日志:查看例如region移動軌跡,發生了什么動作,服務端接受處理了哪些客戶端請求。
3、gc日志:gc情況是否正常
4、操作系統日志和命令:操作系統層面、硬件是否故障,當前狀況如何
5、btrace:實時跟蹤目前服務端的請求和處理情況
6、運維工具:通過內置於系統中的功能,查看服務器實時處理狀況
其實以上手段,大部分系統都具備,不過各有各的用法,下面我會通過常見的問題來梳理這6大手段。
常見問題1:個別請求為什么很慢?
個別請求慢是用戶遇到最多的問題,首先需要明確是客戶端還是服務端原因,進而分析服務端狀況以及捕獲這些請求來明確定位。
1、通過客戶端日志來初步分析下慢請求的規律,嘗試在客戶端確定請求的rowkey和操作類型。
2、確定是不是一段時間內集中出現慢請求,如果是那么可以參考常見問題2來解決。
3、查看服務端監控,觀察響應時間是否平穩,maxResponseTime是否出現峰值。如果存在,那么可以初步確定是服務端問題。
4、客戶端分析無效,可以通過運維工具在服務端捕獲慢請求的rowkey和操作類型。
5、確定rowkey對應的region,初步查看是否存在數據表參數配置不合理(例如version設置過多、blockcache、bloomfilter類型不正確)、storefile過多、命中率過低等問題。
6、嘗試重試這些請求或者直接分析hfile來查看返回結果是否過大,請求是否耗費資源過多。
7、查看服務端關於hdfs的監控和日志,以及datanode日志,來分析是否存在hdfs塊讀取慢或者磁盤故障。
常見問題2:客戶端讀寫請求為什么大量出錯?
讀寫請求大量出錯的現象主要有兩類:1、大量出現服務端exception 2、大量超時。其中第一種有異常信息較好判斷問題所在。
1、大量服務端exception一般是region不在線導致的,可能是region在split但是時間很長超過預期,或是meta數據錯誤導致客戶端獲取region location錯誤。以上現象均可通過日志來定位。
2、遇到大量超時,首先應該排除服務端是否出現了fullgc或者ygc時間過長。前者可能由於內存碎片、cms gc速度來不及導致,后者一般是由於系統使用了swap內存。
3、通過系統命令和日志來查看是否有機器load過高,磁盤壓力過大,磁盤故障。
4、查看監控是否出現callqueue積壓,請求無法得到及時處理,進一步通過call查看工具或者jstack可以查看正在處理的call和進程堆棧信息。
5、通過datanode日志和hbase訪問dfs的時間,來判斷問題是否在hdfs層。
6、查看監控判斷是否出現blocking update,memstore是否已接近系統設置的上限。
常見問題3:系統為什么越來越慢了?
系統原來挺快的,為什么越來越慢?多數是不合理的服務端配置導致的,可以通過以下幾個方面來分析。
1、磁盤讀寫和系統load是不是比以前高了,初步判斷導致系統變慢的原因。
2、如果磁盤讀寫加劇,重點查看flush是否過小,compact是否過頻,尤其是major compact是否有必要,從測試結果來看compact產生的磁盤io對系統性能影響很大。
3、單個region的storefile個數是否有成倍提高
4、命中率是否有下降趨勢
5、regionserver是否存在region分配不均衡導致的讀寫集中,或者讀寫handler的競爭
6、datablock的本地化率是否出現下降
7、是否存在datanode運行不正常,可以通過監控查看是否有個別機器讀取block時間明顯偏高
常見問題4:數據為什么沒了,明明寫進去過?
數據丟失也是HBase的常見bug,分為臨時性和永久性兩類。臨時性的丟失往往是由於hbase本身的正確性問題導致瞬間讀取數據錯誤。永久性丟失一般是日志恢復bug或者region的二次分配。
1、首先可以通過hbck或者master日志排查丟失的數據所在region是否發生過二次分配
2、集群中的regionserver是否出現過abort,日志是否正確恢復。
3、掃描storefile確定目前數據情況
4、掃描logs或者oldlogs中的文件來確定是否寫入過這些數據,以及寫入數據的時間,配合rs的日志來確定當時server的行為
5、根據寫入數據的時間,確定regionserver是否正確完成了flush並且將數據寫入磁盤
常見問題5:為什么有服務器進程掛了?
regionserver發生abort的場景很多,除了系統bug引起的以外,線上遇到最多的就是fullgc引起的zk節點超時和文件系統異常。
1、查看regionserver日志查詢FATAL異常,確定異常類型
2、查看gc日志確定是否發生fullgc或者ygc時間過長
3、如果沒有征兆,日志突然中斷,首先需要考慮是否發生了OOM(0.94版本會直接kill -9)。
4、可以通過系統內存監控判斷是否出現被占滿的情況
5、查看datanode是否出現異常日志,regionserver可能由於roll log或者flush時的文件系統異常導致abort
6、排除人為調用stop的情況
HBase健康體檢
一個集群似乎否健康,大體可以從以下幾個方面來判斷
1、單region的storefile數量是否合理
2、memstore是否得到合理的利用,此項指標與hlog的數量和大小相關
3、compact和flush的流量比值是否合理,如果每天僅flush 1G卻要compact幾十上百G就是明顯的浪費
4、split似乎否過頻,能否采取pre-sharding的方式來預分配region
5、集群的region是否過多,zk在默認參數下無法支撐12w以上的region個數,並且region過多也會影響regionserver failover的時間
6、讀寫相應時間是否合理,datablock的讀取延時是否符合預期
7、flush隊列、callqueue長度、compact隊列是否符合預期。前兩者的積壓都會造成系統不穩定。
8、failedRequest和maxResponseTime
9、gc狀況,過長的ygc和過頻的cms都需要警惕
運維工具
HBase官方版本的可運維性的確很差,為了能最大限度的保證線上系統安全,快速定位故障原因,阿里做了很多建設性的工作。
1、建立了完整的監控體系,根據日常測試和線上運行經驗,加入了很多監控點。
2、監控的粒度達到region級別
3、call dump和線上慢請求追蹤功能
4、btrace腳本體系,出現問題直接運行查看程序內部信息
5、日志收集和報警
6、在線表維護工具和storefile、logs分析工具
