# Apache HBase 的故障排除和調試
## 128.一般準則
始終從主日志開始(TODO:哪些行?)。通常它只是一遍又一遍地打印相同的線條。如果沒有,那就有問題了。谷歌或 [search-hadoop.com](http://search-hadoop.com) 應該為你看到的那些例外返回一些點擊。
Apache HBase 中很少出現錯誤,通常當某些東西搞砸了,接下來可能會有數百個異常和來自各地的堆棧跟蹤。解決此類問題的最佳方法是將日志提升到所有開始的位置,例如,使用 RegionServers 的一個技巧是他們將在中止時打印一些指標,因此 _Dump_ 的灰心應該可以幫助您問題的開始。
RegionServer 自殺是“正常的”,因為這是他們在出現問題時所做的事情。例如,如果 ulimit 和 max 傳輸線程(兩個最重要的初始設置,參見 [[ulimit]](#ulimit) 和 [`dfs.datanode.max.transfer.threads`](#dfs.datanode.max.transfer.threads) )沒有改變,那么它將無法實現指向 DataNodes 創建新線程,從 HBase 的角度來看,HDTR 已經消失。想想如果您的 MySQL 數據庫突然無法訪問本地文件系統上的文件會發生什么,這與 HBase 和 HDFS 相同。看到 RegionServers 提交 seppuku 的另一個常見原因是當他們輸入持續時間超過默認 ZooKeeper 會話超時的延長垃圾收集暫停時。有關 GC 暫停的更多信息,請參閱上面的 [3 部分博客文章](https://blog.cloudera.com/blog/2011/02/avoiding-full-gcs-in-hbase-with-memstore-local-allocation-buffers-part-1/),Todd Lipcon 和 [Long GC 暫停](#gcpause)。
## 129.日志
關鍵過程日志如下...(將<user>替換為啟動服務的用戶,將<hostname>替換為機器名稱)</hostname></user>
NameNode:_ $ HADOOP _HOME / logs / hadoop- <user>-namenode- <hostname>.log</hostname></user>_
DataNode:_ $ HADOOP _HOME / logs / hadoop- <user>-datanode- <hostname>.log</hostname></user>_
JobTracker:_ $ HADOOP _HOME / logs / hadoop- <user>-jobtracker- <hostname>.log</hostname></user>_
TaskTracker:_ $ HADOOP _HOME / logs / hadoop- <user>-tasktracker- <hostname>.log</hostname></user>_
HMaster:_ $ HBASE _HOME / logs / hbase- <user>-master- <hostname>.log</hostname></user>_
RegionServer:_ $ HBASE _HOME / logs / hbase- <user>-regionserver- <hostname>.log</hostname></user>_
ZooKeeper: _TODO_
### 129.1。記錄位置
對于獨立部署,日志顯然將位于單個計算機上,但這只是一個開發配置。生產部署需要在群集上運行。
#### 129.1.1。的 NameNode
NameNode 日志位于 NameNode 服務器上。 HBase Master 通常在 NameNode 服務器上運行,也可以在 ZooKeeper 上運行。
對于較小的集群,JobTracker / ResourceManager 通常也在 NameNode 服務器上運行。
#### 129.1.2。數據管理部
每個 DataNode 服務器都有一個 HDFS 的 DataNode 日志,以及 HBase 的 RegionServer 日志。
此外,每個 DataNode 服務器還將具有用于 MapReduce 任務執行的 TaskTracker / NodeManager 日志。
### 129.2。日志級別
#### 129.2.1。啟用 RPC 級別日志記錄
在 RegionServer 上啟用 RPC 級別日志記錄通常可以深入了解服務器的計時。啟用后,記錄的日志量很大。建議您不要將此登錄時間保留超過短時間。要啟用 RPC 級別日志記錄,請瀏覽到 RegionServer UI 并單擊 _ 日志級別 _。將包`org.apache.hadoop.ipc`的日志級別設置為`DEBUG`(對于`hadoop.ipc`,NOT,`hbase.ipc`,這是正確的。然后尾隨 RegionServers 日志。分析。
要禁用,請將日志記錄級別設置回`INFO`級別。
### 129.3。 JVM 垃圾收集日志
| |
本節中的所有示例垃圾收集日志都基于 Java 8 輸出。在 Java 9 及更高版本中引入統一日志將導致看起來非常不同的日志。
|
HBase 是內存密集型的,使用默認的 GC 可以看到所有線程中的長暫停,包括 _Juliet Pause_ 又名“GC of Death”。為了幫助調試或確認這種情況發生,可以在 Java 虛擬機中打開 GC 日志記錄。
要在 _hbase-env.sh_ 中啟用,請取消注釋以下行之一:
```
# This enables basic gc logging to the .out file.
# export SERVER_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
# This enables basic gc logging to its own file.
# export SERVER_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:<FILE-PATH>"
# This enables basic GC logging to its own file with automatic log rolling. Only applies to jdk 1.6.0_34+ and 1.7.0_2+.
# export SERVER_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:<FILE-PATH> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=512M"
# If <FILE-PATH> is not replaced, the log file(.gc) would be generated in the HBASE_LOG_DIR.
```
此時你應該看到這樣的日志:
```
64898.952: [GC [1 CMS-initial-mark: 2811538K(3055704K)] 2812179K(3061272K), 0.0007360 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
64898.953: [CMS-concurrent-mark-start]
64898.971: [GC 64898.971: [ParNew: 5567K->576K(5568K), 0.0101110 secs] 2817105K->2812715K(3061272K), 0.0102200 secs] [Times: user=0.07 sys=0.00, real=0.01 secs]
```
在本節中,第一行表示 CMS 最初標記的 0.0007360 秒暫停。這將暫停整個 VM,該段時間內的所有線程。
第三行表示“次要 GC”,它暫停 VM 0.0101110 秒 - 也就是 10 毫秒。它將“ParNew”從大約 5.5 米減少到 576k。在本周期的后期,我們看到:
```
64901.445: [CMS-concurrent-mark: 1.542/2.492 secs] [Times: user=10.49 sys=0.33, real=2.49 secs]
64901.445: [CMS-concurrent-preclean-start]
64901.453: [GC 64901.453: [ParNew: 5505K->573K(5568K), 0.0062440 secs] 2868746K->2864292K(3061272K), 0.0063360 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
64901.476: [GC 64901.476: [ParNew: 5563K->575K(5568K), 0.0072510 secs] 2869283K->2864837K(3061272K), 0.0073320 secs] [Times: user=0.05 sys=0.01, real=0.01 secs]
64901.500: [GC 64901.500: [ParNew: 5517K->573K(5568K), 0.0120390 secs] 2869780K->2865267K(3061272K), 0.0121150 secs] [Times: user=0.09 sys=0.00, real=0.01 secs]
64901.529: [GC 64901.529: [ParNew: 5507K->569K(5568K), 0.0086240 secs] 2870200K->2865742K(3061272K), 0.0087180 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
64901.554: [GC 64901.555: [ParNew: 5516K->575K(5568K), 0.0107130 secs] 2870689K->2866291K(3061272K), 0.0107820 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
64901.578: [CMS-concurrent-preclean: 0.070/0.133 secs] [Times: user=0.48 sys=0.01, real=0.14 secs]
64901.578: [CMS-concurrent-abortable-preclean-start]
64901.584: [GC 64901.584: [ParNew: 5504K->571K(5568K), 0.0087270 secs] 2871220K->2866830K(3061272K), 0.0088220 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
64901.609: [GC 64901.609: [ParNew: 5512K->569K(5568K), 0.0063370 secs] 2871771K->2867322K(3061272K), 0.0064230 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
64901.615: [CMS-concurrent-abortable-preclean: 0.007/0.037 secs] [Times: user=0.13 sys=0.00, real=0.03 secs]
64901.616: [GC[YG occupancy: 645 K (5568 K)]64901.616: [Rescan (parallel) , 0.0020210 secs]64901.618: [weak refs processing, 0.0027950 secs] [1 CMS-remark: 2866753K(3055704K)] 2867399K(3061272K), 0.0049380 secs] [Times: user=0.00 sys=0.01, real=0.01 secs]
64901.621: [CMS-concurrent-sweep-start]
```
第一行表示 CMS 并發標記(查找垃圾)花費了 2.4 秒。但這是一個 _ 并發 _ 2.4 秒,Java 在任何時間點都沒有被暫停。
還有一些較小的 GC,然后在最后一行停頓:
```
64901.616: [GC[YG occupancy: 645 K (5568 K)]64901.616: [Rescan (parallel) , 0.0020210 secs]64901.618: [weak refs processing, 0.0027950 secs] [1 CMS-remark: 2866753K(3055704K)] 2867399K(3061272K), 0.0049380 secs] [Times: user=0.00 sys=0.01, real=0.01 secs]
```
這里的暫停是 0.0049380 秒(又名 4.9 毫秒)來“評論”堆。
此時掃描開始,您可以觀察堆大小下降:
```
64901.637: [GC 64901.637: [ParNew: 5501K->569K(5568K), 0.0097350 secs] 2871958K->2867441K(3061272K), 0.0098370 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
... lines removed ...
64904.936: [GC 64904.936: [ParNew: 5532K->568K(5568K), 0.0070720 secs] 1365024K->1360689K(3061272K), 0.0071930 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
64904.953: [CMS-concurrent-sweep: 2.030/3.332 secs] [Times: user=9.57 sys=0.26, real=3.33 secs]
```
此時,CMS 掃描需要 3.332 秒,堆從大約 2.8 GB 到大約 1.3 GB(近似值)。
這里的關鍵點是保持所有這些暫停低。 CMS 暫停總是很低,但如果您的 ParNew 開始增長,您可以看到較小的 GC 暫停接近 100 毫秒,超過 100 毫秒并達到 400 毫秒。
這可能是由于 ParNew 的大小,它應該相對較小。如果你的 ParNew 在運行 HBase 一段時間后非常大,在一個例子中 ParNew 大約是 150MB,那么你可能不得不約束 ParNew 的大小(它越大,集合采取的時間越長但是如果它太小,對象太快被提升為老一代)。在下面我們將新的基因大小限制在 64 米。
在 _hbase-env.sh_ 中添加以下行:
```
export SERVER_GC_OPTS="$SERVER_GC_OPTS -XX:NewSize=64m -XX:MaxNewSize=64m"
```
同樣,要為客戶端進程啟用 GC 日志記錄,請取消注釋 _hbase-env.sh_ 中的以下行之一:
```
# This enables basic gc logging to the .out file.
# export CLIENT_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
# This enables basic gc logging to its own file.
# export CLIENT_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:<FILE-PATH>"
# This enables basic GC logging to its own file with automatic log rolling. Only applies to jdk 1.6.0_34+ and 1.7.0_2+.
# export CLIENT_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:<FILE-PATH> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=512M"
# If <FILE-PATH> is not replaced, the log file(.gc) would be generated in the HBASE_LOG_DIR .
```
有關 GC 暫停的更多信息,請參閱 Todd Lipcon 的 [3 部分博客文章](https://blog.cloudera.com/blog/2011/02/avoiding-full-gcs-in-hbase-with-memstore-local-allocation-buffers-part-1/)和上面的 [Long GC 暫停](#gcpause)。
## 130.資源
### 130.1。 search-hadoop.com
[search-hadoop.com](http://search-hadoop.com) 索引所有郵件列表,非常適合歷史搜索。當你遇到問題時首先在這里搜索,因為很可能有人已經遇到了你的問題。
### 130.2。郵件列表
在 [Apache HBase 郵件列表](https://hbase.apache.org/mail-lists.html)上提問。 'dev'郵件列表針對實際構建 Apache HBase 的開發人員社區以及當前正在開發的功能,而'user'通常用于發布 Apache HBase 版本的問題。在進入郵件列表之前,請先通過搜索郵件列表存檔確保您的問題尚未得到解答。使用 [search-hadoop.com](#trouble.resources.searchhadoop) 。花一些時間來制作你的問題。有關制作好問題的想法,請參閱[獲取答案](http://www.mikeash.com/getting_answers.html)。質量問題包括作者試圖在手冊和列表中找到答案的所有背景和證據,更有可能得到迅速的回應。
### 130.3。松弛
請參閱 Slack 上的 [http://apache-hbase.slack.com](http://apache-hbase.slack.com) 頻道
### 130.4。 IRC
(您可能會在 Slack 頻道上獲得更快速的響應)
irc.freenode.net 上的#hbase
### 130.5。 JIRA
[JIRA](https://issues.apache.org/jira/browse/HBASE) 在查找 Hadoop / HBase 特定問題時也非常有用。
## 131.工具
### 131.1。內置工具
#### 131.1.1。主 Web 界面
Master 默認在端口 16010 上啟動 Web 界面。
Master Web UI 列出了創建的表及其定義(例如,ColumnFamilies,blocksize 等)。此外,還會列出群集中可用的 RegionServers 以及選定的高級度量標準(請求,區域數,usedHeap,maxHeap)。 Master Web UI 允許導航到每個 RegionServer 的 Web UI。
#### 131.1.2。 RegionServer Web 界面
默認情況下,RegionServers 在端口 16030 上啟動 Web 界面。
RegionServer Web UI 列出了在線區域及其開始/結束鍵,以及時間點 RegionServer 度量(請求,區域,storeFileIndexSize,compactionQueueSize 等)。
有關度量標準定義的更多信息,請參見 [HBase 度量標準](#hbase_metrics)。
#### 131.1.3。 zkcli
`zkcli`是一個非常有用的工具,用于調查與 ZooKeeper 相關的問題。要調用:
```
./hbase zkcli -server host:port <cmd> <args>
```
命令(和參數)是:
```
connect host:port
get path [watch]
ls path [watch]
set path data [version]
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path
```
#### 131.1.4。維護模式
如果群集在某種狀態下卡住并且標準技術沒有取得進展,則可以在“維護模式”下重新啟動群集。此模式具有顯著降低的功能和表面積,使得更容易實現非常低級別的更改,例如修復/恢復`hbase:meta`表。
要進入維護模式,請在`hbase-site.xml`中將`hbase.master.maintenance_mode`設置為`true`,或在啟動主過程(`-D…?=true`)時通過系統配置。進入和退出此模式需要重新啟動服務,但典型的用途是 HBase Master 已經面臨啟動困難。
啟用維護模式后,主服務器將托管所有系統表 - 確保它有足夠的內存來執行此操作。不會從用戶空間表中為 RegionServers 分配任何區域;事實上,在維護模式下,它們將完全未使用。此外,主服務器不會加載任何協處理器,不會運行任何規范化或合并/拆分操作,也不會強制執行配額。
### 131.2。外部工具
#### 131.2.1。尾巴
`tail`是命令行工具,可以讓您查看文件的結尾。添加`-f`選項,當新數據可用時,它將刷新。當你想知道發生了什么時,這很有用,例如,當一個集群需要很長時間才能關閉或啟動時,因為你可以觸發一個新的終端并拖尾主日志(可能還有一些 RegionServers)。
#### 131.2.2。最佳
`top`可能是首次嘗試查看計算機上運行的內容以及如何使用資源時最重要的工具之一。這是生產系統的一個例子:
```
top - 14:46:59 up 39 days, 11:55, 1 user, load average: 3.75, 3.57, 3.84
Tasks: 309 total, 1 running, 308 sleeping, 0 stopped, 0 zombie
Cpu(s): 4.5%us, 1.6%sy, 0.0%ni, 91.7%id, 1.4%wa, 0.1%hi, 0.6%si, 0.0%st
Mem: 24414432k total, 24296956k used, 117476k free, 7196k buffers
Swap: 16008732k total, 14348k used, 15994384k free, 11106908k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15558 hadoop 18 -2 3292m 2.4g 3556 S 79 10.4 6523:52 java
13268 hadoop 18 -2 8967m 8.2g 4104 S 21 35.1 5170:30 java
8895 hadoop 18 -2 1581m 497m 3420 S 11 2.1 4002:32 java
…
```
在這里我們可以看到最后五分鐘內的系統平均負載是 3.75,這大致意味著在這 5 分鐘內平均有 3.75 個線程在等待 CPU 時間。通常,_ 完美 _ 利用率等于核心數量,在該數量下機器未被利用并且機器被過度利用。這是一個重要的概念,請參閱本文以了解更多: [http://www.linuxjournal.com/article/9001](http://www.linuxjournal.com/article/9001) 。
除了加載之外,我們可以看到系統幾乎使用了所有可用的 RAM,但大部分用于 OS 緩存(這很好)。交換只有幾 KB,這是想要的,高數字表示交換活動,這是 Java 系統性能的克星。檢測交換的另一種方法是當負載平均值通過屋頂時(盡管這也可能是由死亡磁盤等引起的)。
默認情況下,進程列表并不是非常有用,我們所知道的是 3 個 java 進程正在使用大約 111%的 CPU。要知道哪個是哪個,只需輸入`c`并擴展每一行。鍵入`1`將為您提供每個 CPU 的使用方式的詳細信息,而不是所有 CPU 的平均值,如此處所示。
#### 131.2.3。 JPS
`jps`隨每個 JDK 一起提供,并為當前用戶提供 java 進程 ID(如果是 root,則為所有用戶提供 id)。例:
```
hadoop@sv4borg12:~$ jps
1322 TaskTracker
17789 HRegionServer
27862 Child
1158 DataNode
25115 HQuorumPeer
2950 Jps
19750 ThriftServer
18776 jmx
```
按順序,我們看到:
* Hadoop TaskTracker 管理當地的 Childs
* HBase RegionServer 服務于區域
* Child,它的 MapReduce 任務,無法確切地分辨出哪種類型
* Hadoop TaskTracker, manages the local Childs
* Hadoop DataNode 服務塊
* HQorumPeer,ZooKeeper 合奏成員
* Jps,嗯...這是當前的過程
* ThriftServer,它是一個特殊的將只在 thrift 啟動時運行
* jmx,這是一個本地進程,它是我們監控平臺的一部分(可能名字很差)。你可能沒有那個。
然后,您可以執行諸如檢出啟動該過程的完整命令行之類的操作:
```
hadoop@sv4borg12:~$ ps aux | grep HRegionServer
hadoop 17789 155 35.2 9067824 8604364 ? S<l Mar04 9855:48 /usr/java/jdk1.6.0_14/bin/java -Xmx8000m -XX:+DoEscapeAnalysis -XX:+AggressiveOpts -XX:+UseConcMarkSweepGC -XX:NewSize=64m -XX:MaxNewSize=64m -XX:CMSInitiatingOccupancyFraction=88 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/export1/hadoop/logs/gc-hbase.log -Dcom.sun.management.jmxremote.port=10102 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.password.file=/home/hadoop/hbase/conf/jmxremote.password -Dcom.sun.management.jmxremote -Dhbase.log.dir=/export1/hadoop/logs -Dhbase.log.file=hbase-hadoop-regionserver-sv4borg12.log -Dhbase.home.dir=/home/hadoop/hbase -Dhbase.id.str=hadoop -Dhbase.root.logger=INFO,DRFA -Djava.library.path=/home/hadoop/hbase/lib/native/Linux-amd64-64 -classpath /home/hadoop/hbase/bin/../conf:[many jars]:/home/hadoop/hadoop/conf org.apache.hadoop.hbase.regionserver.HRegionServer start
```
#### 131.2.4。 jstack
`jstack`是最重要的工具之一,試圖找出除了查看日志之外的 java 進程正在做什么。它必須與 jps 一起使用才能為其提供進程 ID。它顯示了一個線程列表,每個線程都有一個名稱,它們按照創建的順序出現(所以最頂層的線程是最新的線程)。以下是一些示例:
RegionServer 的主線程等待主服務器執行的操作:
```
"regionserver60020" prio=10 tid=0x0000000040ab4000 nid=0x45cf waiting on condition [0x00007f16b6a96000..0x00007f16b6a96a70]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00007f16cd5c2f30> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1963)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:395)
at org.apache.hadoop.hbase.regionserver.HRegionServer.run(HRegionServer.java:647)
at java.lang.Thread.run(Thread.java:619)
```
正在刷新到文件的 MemStore 刷新線程:
```
"regionserver60020.cacheFlusher" daemon prio=10 tid=0x0000000040f4e000 nid=0x45eb in Object.wait() [0x00007f16b5b86000..0x00007f16b5b87af0]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.apache.hadoop.ipc.Client.call(Client.java:803)
- locked <0x00007f16cb14b3a8> (a org.apache.hadoop.ipc.Client$Call)
at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:221)
at $Proxy1.complete(Unknown Source)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:82)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:59)
at $Proxy1.complete(Unknown Source)
at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.closeInternal(DFSClient.java:3390)
- locked <0x00007f16cb14b470> (a org.apache.hadoop.hdfs.DFSClient$DFSOutputStream)
at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.close(DFSClient.java:3304)
at org.apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.java:61)
at org.apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.java:86)
at org.apache.hadoop.hbase.io.hfile.HFile$Writer.close(HFile.java:650)
at org.apache.hadoop.hbase.regionserver.StoreFile$Writer.close(StoreFile.java:853)
at org.apache.hadoop.hbase.regionserver.Store.internalFlushCache(Store.java:467)
- locked <0x00007f16d00e6f08> (a java.lang.Object)
at org.apache.hadoop.hbase.regionserver.Store.flushCache(Store.java:427)
at org.apache.hadoop.hbase.regionserver.Store.access$100(Store.java:80)
at org.apache.hadoop.hbase.regionserver.Store$StoreFlusherImpl.flushCache(Store.java:1359)
at org.apache.hadoop.hbase.regionserver.HRegion.internalFlushcache(HRegion.java:907)
at org.apache.hadoop.hbase.regionserver.HRegion.internalFlushcache(HRegion.java:834)
at org.apache.hadoop.hbase.regionserver.HRegion.flushcache(HRegion.java:786)
at org.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.java:250)
at org.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.java:224)
at org.apache.hadoop.hbase.regionserver.MemStoreFlusher.run(MemStoreFlusher.java:146)
```
正在等待處理的處理程序線程(如 put,delete,scan 等):
```
"IPC Server handler 16 on 60020" daemon prio=10 tid=0x00007f16b011d800 nid=0x4a5e waiting on condition [0x00007f16afefd000..0x00007f16afefd9f0]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00007f16cd3f8dd8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1925)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:358)
at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1013)
```
還有一個正在忙著增加一個計數器(它正處于嘗試創建掃描器以讀取最后一個值的階段):
```
"IPC Server handler 66 on 60020" daemon prio=10 tid=0x00007f16b006e800 nid=0x4a90 runnable [0x00007f16acb77000..0x00007f16acb77cf0]
java.lang.Thread.State: RUNNABLE
at org.apache.hadoop.hbase.regionserver.KeyValueHeap.<init>(KeyValueHeap.java:56)
at org.apache.hadoop.hbase.regionserver.StoreScanner.<init>(StoreScanner.java:79)
at org.apache.hadoop.hbase.regionserver.Store.getScanner(Store.java:1202)
at org.apache.hadoop.hbase.regionserver.HRegion$RegionScanner.<init>(HRegion.java:2209)
at org.apache.hadoop.hbase.regionserver.HRegion.instantiateInternalScanner(HRegion.java:1063)
at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(HRegion.java:1055)
at org.apache.hadoop.hbase.regionserver.HRegion.getScanner(HRegion.java:1039)
at org.apache.hadoop.hbase.regionserver.HRegion.getLastIncrement(HRegion.java:2875)
at org.apache.hadoop.hbase.regionserver.HRegion.incrementColumnValue(HRegion.java:2978)
at org.apache.hadoop.hbase.regionserver.HRegionServer.incrementColumnValue(HRegionServer.java:2433)
at sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.hbase.ipc.HBaseRPC$Server.call(HBaseRPC.java:560)
at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1027)
```
從 HDFS 接收數據的線程:
```
"IPC Client (47) connection to sv4borg9/10.4.24.40:9000 from hadoop" daemon prio=10 tid=0x00007f16a02d0000 nid=0x4fa3 runnable [0x00007f16b517d000..0x00007f16b517dbf0]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00007f17d5b68c00> (a sun.nio.ch.Util$1)
- locked <0x00007f17d5b68be8> (a java.util.Collections$UnmodifiableSet)
- locked <0x00007f1877959b50> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at org.apache.hadoop.net.SocketIOWithTimeout$SelectorPool.select(SocketIOWithTimeout.java:332)
at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:157)
at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:155)
at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:128)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at org.apache.hadoop.ipc.Client$Connection$PingInputStream.read(Client.java:304)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
- locked <0x00007f1808539178> (a java.io.BufferedInputStream)
at java.io.DataInputStream.readInt(DataInputStream.java:370)
at org.apache.hadoop.ipc.Client$Connection.receiveResponse(Client.java:569)
at org.apache.hadoop.ipc.Client$Connection.run(Client.java:477)
```
這是一個主人試圖在 RegionServer 死后恢復租約:
```
"LeaseChecker" daemon prio=10 tid=0x00000000407ef800 nid=0x76cd waiting on condition [0x00007f6d0eae2000..0x00007f6d0eae2a70]
--
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.apache.hadoop.ipc.Client.call(Client.java:726)
- locked <0x00007f6d1cd28f80> (a org.apache.hadoop.ipc.Client$Call)
at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:220)
at $Proxy1.recoverBlock(Unknown Source)
at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.processDatanodeError(DFSClient.java:2636)
at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.<init>(DFSClient.java:2832)
at org.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:529)
at org.apache.hadoop.hdfs.DistributedFileSystem.append(DistributedFileSystem.java:186)
at org.apache.hadoop.fs.FileSystem.append(FileSystem.java:530)
at org.apache.hadoop.hbase.util.FSUtils.recoverFileLease(FSUtils.java:619)
at org.apache.hadoop.hbase.regionserver.wal.HLog.splitLog(HLog.java:1322)
at org.apache.hadoop.hbase.regionserver.wal.HLog.splitLog(HLog.java:1210)
at org.apache.hadoop.hbase.master.HMaster.splitLogAfterStartup(HMaster.java:648)
at org.apache.hadoop.hbase.master.HMaster.joinCluster(HMaster.java:572)
at org.apache.hadoop.hbase.master.HMaster.run(HMaster.java:503)
```
#### 131.2.5。 OpenTSDB
[OpenTSDB](http://opentsdb.net) 是 Ganglia 的絕佳替代品,因為它使用 Apache HBase 存儲所有時間序列而不必下采樣。監控托管 OpenTSDB 的 HBase 集群是一個很好的練習。
這是一個集群的例子,這個集群幾乎同時發生了數百次壓縮,嚴重影響了 IO 性能:( TODO:插圖繪制 compactionQueueSize)
使用每臺機器和每個集群的所有重要圖表構建儀表板是一個很好的做法,這樣就可以通過一次快速查看來完成調試問題。例如,在 StumbleUpon,每個集群有一個儀表板,其中包含來自操作系統和 Apache HBase 的最重要指標。然后,您可以在機器級別下載并獲得更詳細的指標。
#### 131.2.6。 clusterssh +頂
clusterssh + top,它就像一個窮人的監控系統,當你只有幾臺機器時,它非常有用,因為它很容易設置。啟動 clusterssh 將為每臺機器和另一個終端提供一個終端,在該終端中,您輸入的任何內容都將在每個窗口中重新輸入。這意味著您可以鍵入`top`一次,同時為所有計算機啟動它,可以全面查看集群的當前狀態。您還可以同時拖動所有日志,編輯文件等。
## 132.客戶
有關 HBase 客戶端的更多信息,請參閱[客戶端](#architecture.client)。
### 132.1。 ScannerTimeoutException 或 UnknownScannerException
如果從客戶端到 RegionServer 的 RPC 調用之間的時間超過掃描超時,則拋出此異常。例如,如果`Scan.setCaching`設置為 500,那么將在 ResultScanner 上每 500 `.next()`次調用一次 RPC 調用來獲取下一批行,因為數據正以 500 行的塊傳輸到客戶端。減少 setCaching 值可能是一個選項,但將此值設置得太低會導致對行數的低效處理。
參見[掃描緩存](#perf.hbase.client.caching)。
### 132.2。 Thrift 和 Java API 的性能差異
如果`Scan.setCaching`太高,可能會出現性能不佳甚至`ScannerTimeoutExceptions`,如 [ScannerTimeoutException 或 UnknownScannerException](#trouble.client.scantimeout) 中所述。如果 Thrift 客戶端對給定工作負載使用了錯誤的緩存設置,則與 Java API 相比,性能會受到影響。要在 Thrift 客戶端中為給定掃描設置緩存,請使用`scannerGetList(scannerId, numRows)`方法,其中`numRows`是表示要緩存的行數的整數。在一個案例中,發現將 Thrift 掃描的緩存從 1000 減少到 100,在給定相同查詢的情況下,將性能提高到與 Java API 接近。
另見 Jesse Andersen 的[博客文章](http://blog.cloudera.com/blog/2014/04/how-to-use-the-hbase-thrift-interface-part-3-using-scans/)關于在 Thrift 中使用 Scans。
### 132.3。調用`Scanner.next`時`LeaseException`
在某些情況下,從 RegionServer 獲取數據的客戶端會獲得 LeaseException 而不是通常的 [ScannerTimeoutException 或 UnknownScannerException](#trouble.client.scantimeout) 。通常,例外的來源是`org.apache.hadoop.hbase.regionserver.Leases.removeLease(Leases.java:230)`(行號可能不同)。它往往發生在緩慢/凍結`RegionServer#next`調用的環境中。可以通過`hbase.rpc.timeout`>來防止它。 `hbase.client.scanner.timeout.period`。 Harsh J 調查了該問題,作為郵件列表線程的一部分 [HBase,郵件#user-租約不存在異常](https://mail-archives.apache.org/mod_mbox/hbase-user/201209.mbox/%3CCAOcnVr3R-LqtKhFsk8Bhrm-YW2i9O6J6Fhjz2h7q6_sxvwd2yw%40mail.gmail.com%3E)
### 132.4。 Shell 或客戶端應用程序在正常操作期間會引發許多可怕的異常
從 0.20.0 開始,`org.apache.hadoop.hbase.*`的默認日志級別為 DEBUG。
在您的客戶端上,編輯 _ $ HBASE _HOME / conf / log4j.properties_ 并將其:`log4j.logger.org.apache.hadoop.hbase=DEBUG`更改為:`log4j.logger.org.apache.hadoop.hbase=INFO`,甚至是`log4j.logger.org.apache.hadoop.hbase=WARN`。
### 132.5。長客戶端暫停壓縮
這是關于 Apache HBase dist-list 的一個相當常見的問題。場景是客戶端通常將大量數據插入到相對未優化的 HBase 集群中。壓縮會加劇暫停,盡管它不是問題的根源。
有關預創建區域的模式,請參見[表創建:預創建區域](#precreate.regions),并確認該表不是以單個區域開頭。
有關群集配置,請參閱 [HBase 配置](#perf.configurations),特別是`hbase.hstore.blockingStoreFiles`,`hbase.hregion.memstore.block.multiplier`,`MAX_FILESIZE`(區域大小)和`MEMSTORE_FLUSHSIZE.`
稍微更長時間解釋為什么會發生暫停的原因如下:在 MemStores 上有時會阻塞 Puts,它被阻塞的刷新線程阻塞,因為有太多的文件需要壓縮,因為壓縮器有太多的小文件要壓縮而且必須重復壓縮相同的數據。即使是輕微的壓縮也會發生這種情況。使這種情況更加復雜,Apache HBase 不會壓縮內存中的數據。因此,存儲在 MemStore 中的 64MB 可能在壓縮后變為 6MB 文件 - 這導致更小的 StoreFile。好處是更多的數據被打包到同一個區域,但是通過能夠編寫更大的文件來實現性能 - 這就是為什么 HBase 在寫入新的 StoreFile 之前等待 flushsize 的原因。較小的 StoreFiles 成為壓縮的目標。如果沒有壓縮,文件會更大,并且不需要那么多的壓縮,但這是以 I / O 為代價的。
有關其他信息,請參閱[長客戶端暫停壓縮](http://search-hadoop.com/m/WUnLM6ojHm1/Long+client+pauses+with+compression&subj=Long+client+pauses+with+compression)上的此主題。
### 132.6。安全客戶端連接([由 GSS 異常引起:未提供有效憑據...])
您可能會遇到以下錯誤:
```
Secure Client Connect ([Caused by GSSException: No valid credentials provided
(Mechanism level: Request is a replay (34) V PROCESS_TGS)])
```
此問題是由 MIT Kerberos replay_cache 組件[#1201](http://krbdev.mit.edu/rt/Ticket/Display.html?id=1201) 和[#5924](http://krbdev.mit.edu/rt/Ticket/Display.html?id=5924) 中的錯誤引起的。這些錯誤導致舊版本的 krb5-server 錯誤地阻止從 Principal 發送的后續請求。這導致 krb5-server 阻止從一個客戶端發送的連接(一個具有多個線程連接實例的 HTable 實例用于每個 RegionServer);客戶端日志中記錄了`Request is a replay (34)`等消息您可以忽略這些消息,因為默認情況下,HTable 將為每個失敗的連接重試 5 * 10(50)次。如果重試后與 RegionServer 的任何連接失敗,HTable 將拋出 IOException,以便 HTable 實例的用戶客戶端代碼可以進一步處理它。注意:`HTable`在 HBase 1.0 中已棄用,有利于`Table`。
或者,將 krb5-server 更新為解決這些問題的版本,例如 krb5-server-1.10.3。有關詳細信息,請參閱 JIRA [HBASE-10379](https://issues.apache.org/jira/browse/HBASE-10379) 。
### 132.7。 ZooKeeper 客戶端連接錯誤
像這樣的錯誤......
```
11/07/05 11:26:41 WARN zookeeper.ClientCnxn: Session 0x0 for server null,
unexpected error, closing socket connection and attempting reconnect
java.net.ConnectException: Connection refused: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1078)
11/07/05 11:26:43 INFO zookeeper.ClientCnxn: Opening socket connection to
server localhost/127.0.0.1:2181
11/07/05 11:26:44 WARN zookeeper.ClientCnxn: Session 0x0 for server null,
unexpected error, closing socket connection and attempting reconnect
java.net.ConnectException: Connection refused: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1078)
11/07/05 11:26:45 INFO zookeeper.ClientCnxn: Opening socket connection to
server localhost/127.0.0.1:2181
```
...要么是由于 ZooKeeper 關閉,要么是由于網絡問題而無法訪問。
實用程序 [zkcli](#trouble.tools.builtin.zkcli) 可能有助于調查 ZooKeeper 問題。
### 132.8。客戶端耗盡內存但堆大小似乎穩定(但堆外/直接堆不斷增長)
您可能遇到了在郵件線程 [HBase,mail#user - 疑似內存泄漏](http://search-hadoop.com/m/ubhrX8KvcH/Suspected+memory+leak&subj=Re+Suspected+memory+leak)中描述和處理的問題,并繼續在 [HBase,郵件#dev - FeedbackRe:懷疑內存泄漏](http://search-hadoop.com/m/p2Agc1Zy7Va/MaxDirectMemorySize+Was%253A+Suspected+memory+leak&subj=Re+FeedbackRe+Suspected+memory+leak)。解決方法是將客戶端 JVM 傳遞給`-XX:MaxDirectMemorySize`合理的值。默認情況下,`MaxDirectMemorySize`等于`-Xmx`最大堆大小設置(如果設置了`-Xmx`)。嘗試將其設置為較小的值(例如,當一個用戶具有`12g`的客戶端堆時,成功將其設置為`1g`)。如果你把它設置得太小,它會帶來`FullGCs`所以保持它有點沉重。您希望僅在客戶端進行此設置,尤其是在運行新的實驗性服務器端堆外緩存時,因為此功能取決于能否使用大型直接緩沖區(您可能必須保持單獨的客戶端和服務器 - side config dirs)。
### 132.9。安全客戶端無法連接([由 GSS 異常引起:未提供有效憑據(機制級別:無法找到任何 Kerberos tgt)])
導致此癥狀的原因可能有多種。
首先,檢查您是否擁有有效的 Kerberos 票證。為了建立與安全的 Apache HBase 集群的通信,需要一個。通過運行`klist`命令行實用程序,檢查當前在憑證緩存中的票證(如果有)。如果未列出故障單,則必須通過使用指定的密鑰表運行`kinit`命令或通過交互方式輸入所需主體的密碼來獲取故障單。
然后,請參閱 [Java 安全指南疑難解答部分](http://docs.oracle.com/javase/1.5.0/docs/guide/security/jgss/tutorials/Troubleshooting.html)。通過將`javax.security.auth.useSubjectCredsOnly`系統屬性值設置為`false`來解決此處解決的最常見問題。
由于 MIT Kerberos 寫入其憑據緩存的格式發生了變化,因此 Oracle JDK 6 Update 26 及更早版本中存在一個錯誤,導致 Java 無法讀取由 MIT Kerberos 1.8.1 版本創建的 Kerberos 憑據緩存或更高。如果您的環境中存在這種有問題的組件組合,要解決此問題,請首先使用`kinit`登錄,然后立即使用`kinit -R`刷新憑據緩存。刷新將重寫憑證緩存而不會出現有問題的格式。
在 JDK 1.4 之前,JCE 是一個非捆綁產品,因此,JCA 和 JCE 通常被稱為獨立的,不同的組件。由于 JCE 現在捆綁在 JDK 7.0 中,因此區別越來越明顯。由于 JCE 使用與 JCA 相同的架構,JCE 應該更恰當地被認為是 JCA 的一部分。
由于 JDK 1.5 或更早版本,您可能需要安裝 [Java 密碼術擴展](https://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html)或 JCE。確保 JCE jar 位于服務器和客戶端系統上的類路徑中。
您可能還需要下載[無限強度 JCE 策略文件](http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html)。解壓縮并解壓縮下載的文件,并將策略 jar 安裝到 _<java-home>/ lib / security</java-home>_ 中。
## 133\. MapReduce
### 133.1。你認為你在群集中,但你實際上是本地的
使用`ImportTsv`發生了以下堆棧跟蹤,但是這樣的事情可能會在配置錯誤的任何作業上發生。
```
WARN mapred.LocalJobRunner: job_local_0001
java.lang.IllegalArgumentException: Can't read partitions file
at org.apache.hadoop.hbase.mapreduce.hadoopbackport.TotalOrderPartitioner.setConf(TotalOrderPartitioner.java:111)
at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:62)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:117)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.<init>(MapTask.java:560)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:639)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:323)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)
Caused by: java.io.FileNotFoundException: File _partition.lst does not exist.
at org.apache.hadoop.fs.RawLocalFileSystem.getFileStatus(RawLocalFileSystem.java:383)
at org.apache.hadoop.fs.FilterFileSystem.getFileStatus(FilterFileSystem.java:251)
at org.apache.hadoop.fs.FileSystem.getLength(FileSystem.java:776)
at org.apache.hadoop.io.SequenceFile$Reader.<init>(SequenceFile.java:1424)
at org.apache.hadoop.io.SequenceFile$Reader.<init>(SequenceFile.java:1419)
at org.apache.hadoop.hbase.mapreduce.hadoopbackport.TotalOrderPartitioner.readPartitions(TotalOrderPartitioner.java:296)
```
...看到堆棧的關鍵部分?這是...
```
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)
```
LocalJobRunner 表示作業在本地運行,而不是在群集上運行。
要解決此問題,您應該在設置`HADOOP_CLASSPATH`的情況下運行 MR 作業以包含 HBase 依賴項。 “hbase classpath”實用程序可用于輕松完成此操作。例如(用您的 HBase 版本替換 VERSION):
```
HADOOP_CLASSPATH=`hbase classpath` hadoop jar $HBASE_HOME/hbase-mapreduce-VERSION.jar rowcounter usertable
```
有關 HBase MapReduce 作業和類路徑的更多信息,請參見 [HBase,MapReduce 和 CLASSPATH](#hbase.mapreduce.classpath) 。
### 133.2。啟動一項工作,你得到 java.lang.IllegalAccessError:com / google / protobuf / HBaseZeroCopyByteString 或類 com.google.protobuf.ZeroCopyLiteralByteString 無法訪問其超類 com.google.protobuf.LiteralByteString
請參閱 [HBASE-10304 運行 hbase 作業 jar:IllegalAccessError:類 com.google.protobuf.ZeroCopyLiteralByteString 無法訪問其超類 com.google.protobuf.LiteralByteString](https://issues.apache.org/jira/browse/HBASE-10304) 和 [HBASE-11118 非環境變量解決方案“ IllegalAccessError:com.google.protobuf.ZeroCopyLiteralByteString 類無法訪問其超類 com.google.protobuf.LiteralByteString“](https://issues.apache.org/jira/browse/HBASE-11118)。嘗試運行 spark 作業時,問題也會出現。參見 [HBASE-10877 應擴展 HBase 不可重試的例外列表](https://issues.apache.org/jira/browse/HBASE-10877)。
## 134\. NameNode
有關 NameNode 的更多信息,請參閱 [HDFS](#arch.hdfs) 。
### 134.1。 HDFS 利用表和區域
要確定 HBase 在 HDFS 上使用多少空間,請使用 NameNode 中的`hadoop` shell 命令。例如......
```
hadoop fs -dus /hbase/
```
...返回所有 HBase 對象的匯總磁盤利用率。
```
hadoop fs -dus /hbase/myTable
```
...返回 HBase 表'myTable'的匯總磁盤利用率。
```
hadoop fs -du /hbase/myTable
```
...返回 HBase 表'myTable'下的區域列表及其磁盤利用率。
有關 HDFS shell 命令的更多信息,請參閱 [HDFS FileSystem Shell 文檔](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/FileSystemShell.html)。
### 134.2。瀏覽 HBase 對象的 HDFS
有時需要探索 HDFS 上存在的 HBase 對象。這些對象可能包括 WAL(寫前進日志),表,區域,StoreFiles 等。最簡單的方法是使用在端口 50070 上運行的 NameNode Web 應用程序.NameNode Web 應用程序將提供指向所有 DataNode 的鏈接在群集中,以便可以無縫瀏覽它們。
集群中 HBase 表的 HDFS 目錄結構是......
```
/hbase
/data
/<Namespace> (Namespaces in the cluster)
/<Table> (Tables in the cluster)
/<Region> (Regions for the table)
/<ColumnFamily> (ColumnFamilies for the Region for the table)
/<StoreFile> (StoreFiles for the ColumnFamily for the Regions for the table)
```
HBase WAL 的 HDFS 目錄結構是..
```
/hbase
/WALs
/<RegionServer> (RegionServers)
/<WAL> (WAL files for the RegionServer)
```
有關`fsck`等其他非 shell 診斷實用程序,請參閱 [HDFS 用戶指南](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html)。
#### 134.2.1。零大小 WALls 包含數據
問題:當獲取 RegionServer 的 _WALs_ 目錄中的所有文件的列表時,一個文件的大小為 0 但它包含數據。
答:這是 HDFS 的怪癖。當前正在寫入的文件的大小似乎為 0,但一旦關閉,它將顯示其真實大小
#### 134.2.2。用例
用于查詢 HBase 對象的 HDFS 的兩個常見用例是研究表的未壓縮程度。如果每個 ColumnFamily 都有大量 StoreFiles,則表明需要進行主要壓縮。此外,在進行重大壓縮后,如果生成的 StoreFile 為“小”,則表明需要減少表的 ColumnFamilies。
### 134.3。意外的文件系統增長
如果您看到 HBase 文件系統使用率出現意外峰值,那么兩個可能的罪魁禍首就是快照和 WAL。
快照
創建快照時,HBase 會保留在快照時重新創建表狀態所需的所有內容。這包括已刪除的單元格或過期版本。因此,您的快照使用模式應該經過精心規劃,并且您應該修剪不再需要的快照。快照存儲在`/hbase/.hbase-snapshot`中,恢復快照所需的存檔存儲在`/hbase/archive/<_tablename_>/<_region_>/<_column_family_>/`中。
```
*Do not* manage snapshots or archives manually via HDFS. HBase provides APIs and
HBase Shell commands for managing them. For more information, see <<ops.snapshots>>.
```
WAL
預寫日志(WAL)存儲在 HBase 根目錄的子目錄中,通常為`/hbase/`,具體取決于它們的狀態。已經處理的 WAL 存儲在`/hbase/oldWALs/`中,損壞的 WAL 存儲在`/hbase/.corrupt/`中進行檢查。如果其中一個子目錄的大小正在增長,請檢查 HBase 服務器日志以找出未正確處理 WAL 的原因。
如果使用復制并且`/hbase/oldWALs/`使用的空間超出預期,請記住,只要存在對等項,復制被禁用時就會保存 WAL。
**不要**通過 HDFS 手動管理 WAL。
## 135.網絡
### 135.1。網絡峰值
如果您看到周期性的網絡峰值,您可能需要檢查`compactionQueues`以查看主要壓縮是否正在發生。
有關管理壓縮的更多信息,請參見 [Managed Compactions](#managed.compactions) 。
### 135.2。環回 IP
HBase 期望環回 IP 地址為 127.0.0.1。
### 135.3。網絡接口
所有網絡接口都正常運行嗎?你確定嗎?請參閱[案例研究](#trouble.casestudy)中的故障排除案例研究。
## 136\. RegionServer
有關 RegionServers 的更多信息,請參見 [RegionServer](#regionserver.arch) 。
### 136.1。啟動錯誤
#### 136.1.1。 Master Starts,但 RegionServers 沒有
Master 認為 RegionServers 的 IP 為 127.0.0.1 - 這是 localhost 并解析為 master 自己的 localhost。
RegionServers 錯誤地通知 Master,他們的 IP 地址是 127.0.0.1。
修改區域服務器上的 _/ etc / hosts_ ,...
```
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 fully.qualified.regionservername regionservername localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
```
... to(從 localhost 中刪除主節點的名稱)...
```
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
```
#### 136.1.2。壓縮鏈接錯誤
由于需要在每個群集上安裝和配置 LZO 等壓縮算法,因此這是啟動錯誤的常見原因。如果你看到這樣的消息......
```
11/02/20 01:32:15 ERROR lzo.GPLNativeCodeLoader: Could not load native gpl library
java.lang.UnsatisfiedLinkError: no gplcompression in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
```
...然后壓縮庫存在路徑問題。請參閱鏈接上的“配置”部分:[LZO 壓縮配置]。
#### 136.1.3。 RegionServer 由于缺少文件系統的 hsync 而中止
為了向集群寫入提供數據持久性,HBase 依賴于在寫入日志中持久保存狀態的能力。當使用支持檢查所需呼叫可用性的 Apache Hadoop Common 文件系統 API 版本時,如果發現它無法安全運行,HBase 將主動中止群集。
對于 RegionServer 角色,失敗將顯示在日志中,如下所示:
```
2018-04-05 11:36:22,785 ERROR [regionserver/192.168.1.123:16020] wal.AsyncFSWALProvider: The RegionServer async write ahead log provider relies on the ability to call hflush and hsync for proper operation during component failures, but the current FileSystem does not support doing so. Please check the config value of 'hbase.wal.dir' and ensure it points to a FileSystem mount that has suitable capabilities for output streams.
2018-04-05 11:36:22,799 ERROR [regionserver/192.168.1.123:16020] regionserver.HRegionServer: ***** ABORTING region server 192.168.1.123,16020,1522946074234: Unhandled: cannot get log writer *****
java.io.IOException: cannot get log writer
at org.apache.hadoop.hbase.wal.AsyncFSWALProvider.createAsyncWriter(AsyncFSWALProvider.java:112)
at org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL.createWriterInstance(AsyncFSWAL.java:612)
at org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL.createWriterInstance(AsyncFSWAL.java:124)
at org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL.rollWriter(AbstractFSWAL.java:759)
at org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL.rollWriter(AbstractFSWAL.java:489)
at org.apache.hadoop.hbase.regionserver.wal.AsyncFSWAL.<init>(AsyncFSWAL.java:251)
at org.apache.hadoop.hbase.wal.AsyncFSWALProvider.createWAL(AsyncFSWALProvider.java:69)
at org.apache.hadoop.hbase.wal.AsyncFSWALProvider.createWAL(AsyncFSWALProvider.java:44)
at org.apache.hadoop.hbase.wal.AbstractFSWALProvider.getWAL(AbstractFSWALProvider.java:138)
at org.apache.hadoop.hbase.wal.AbstractFSWALProvider.getWAL(AbstractFSWALProvider.java:57)
at org.apache.hadoop.hbase.wal.WALFactory.getWAL(WALFactory.java:252)
at org.apache.hadoop.hbase.regionserver.HRegionServer.getWAL(HRegionServer.java:2105)
at org.apache.hadoop.hbase.regionserver.HRegionServer.buildServerLoad(HRegionServer.java:1326)
at org.apache.hadoop.hbase.regionserver.HRegionServer.tryRegionServerReport(HRegionServer.java:1191)
at org.apache.hadoop.hbase.regionserver.HRegionServer.run(HRegionServer.java:1007)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.hadoop.hbase.util.CommonFSUtils$StreamLacksCapabilityException: hflush and hsync
at org.apache.hadoop.hbase.io.asyncfs.AsyncFSOutputHelper.createOutput(AsyncFSOutputHelper.java:69)
at org.apache.hadoop.hbase.regionserver.wal.AsyncProtobufLogWriter.initOutput(AsyncProtobufLogWriter.java:168)
at org.apache.hadoop.hbase.regionserver.wal.AbstractProtobufLogWriter.init(AbstractProtobufLogWriter.java:167)
at org.apache.hadoop.hbase.wal.AsyncFSWALProvider.createAsyncWriter(AsyncFSWALProvider.java:99)
... 15 more
```
如果您嘗試在獨立模式下運行并看到此錯誤,請返回[快速入門 - 獨立 HBase](#quickstart) 部分并確保您已將**所有**包含在給定的配置設置中。
#### 136.1.4。 RegionServer 因無法初始化對 HDFS 的訪問而中止
我們將嘗試將 _AsyncFSWAL_ 用于 HBase-2.x,因為它具有更好的性能,同時消耗更少的資源。但 _AsyncFSWAL_ 的問題在于它侵入了 DFSClient 實現的內部,因此在升級 hadoop 時很容易被破解,即使是簡單的補丁發布也是如此。
如果你沒有指定 wal 提供者,如果我們無法初始化 _AsyncFSWAL_ ,我們將嘗試回退到舊的 _FSHLog_ ,但它可能并不總是有效。失敗將顯示在這樣的日志中:
```
18/07/02 18:51:06 WARN concurrent.DefaultPromise: An exception was
thrown by org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$13.operationComplete()
java.lang.Error: Couldn't properly initialize access to HDFS
internals. Please update your WAL Provider to not make use of the
'asyncfs' provider. See HBASE-16110 for more information.
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputSaslHelper.<clinit>(FanOutOneBlockAsyncDFSOutputSaslHelper.java:268)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper.initialize(FanOutOneBlockAsyncDFSOutputHelper.java:661)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper.access$300(FanOutOneBlockAsyncDFSOutputHelper.java:118)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$13.operationComplete(FanOutOneBlockAsyncDFSOutputHelper.java:720)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$13.operationComplete(FanOutOneBlockAsyncDFSOutputHelper.java:715)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:507)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:500)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:479)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:420)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:82)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.fulfillConnectPromise(AbstractEpollChannel.java:638)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.finishConnect(AbstractEpollChannel.java:676)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.epollOutReady(AbstractEpollChannel.java:552)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:394)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:304)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodException:
org.apache.hadoop.hdfs.DFSClient.decryptEncryptedDataEncryptionKey(org.apache.hadoop.fs.FileEncryptionInfo)
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputSaslHelper.createTransparentCryptoHelper(FanOutOneBlockAsyncDFSOutputSaslHelper.java:232)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputSaslHelper.<clinit>(FanOutOneBlockAsyncDFSOutputSaslHelper.java:262)
... 18 more
```
如果您遇到此錯誤,請在配置文件中明確指定 _FSHLog_ ,即 _ 文件系統 _。
```
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>
```
并且不要忘記發送電子郵件至 [user@hbase.apache.org](mailto:user@hbase.apache.org) 或 [dev@hbase.apache.org](mailto:dev@hbase.apache.org) 報告失敗以及您的 hadoop 版本,我們將嘗試在下一個版本中盡快解決問題。
### 136.2。運行時錯誤
#### 136.2.1。 RegionServer 掛起
你在運行舊的 JVM(&lt; 1.6.0_u21?)?當你看一個線程轉儲時,它是否看起來像是線程被阻塞但沒有人持有鎖都被阻止了?請參閱 HBaseServer 中的 [HBASE 3622 死鎖(JVM 錯誤?)](https://issues.apache.org/jira/browse/HBASE-3622)。將`-XX:+UseMembar`添加到 _conf / hbase-env.sh_ 中的 HBase `HBASE_OPTS`可能會修復它。
#### 136.2.2。 java.io.IOException ...(打開的文件太多)
如果您看到這樣的日志消息......
```
2010-09-13 01:24:17,336 WARN org.apache.hadoop.hdfs.server.datanode.DataNode:
Disk-related IOException in BlockReceiver constructor. Cause is java.io.IOException: Too many open files
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:883)
```
...請參閱鏈接上的“入門”部分:[ulimit 和 nproc 配置]。
#### 136.2.3。 xceiverCount 258 超過并發 xcievers 256 的限制
這通常顯示在 DataNode 日志中。
請參閱鏈接上的“入門”部分:[xceivers 配置]。
#### 136.2.4。系統不穩定,并且存在“java.lang.OutOfMemoryError:無法在異常中創建新的本機線程”HDFS DataNode 日志或任何系統守護程序的日志
請參閱有關 ulimit 和 nproc 配置的“入門”部分。最新 Linux 發行版的默認值為 1024 - 這對于 HBase 來說太低了。
#### 136.2.5。 DFS 不穩定和/或 RegionServer 租約超時
如果你看到這樣的警告信息......
```
2009-02-24 10:01:33,516 WARN org.apache.hadoop.hbase.util.Sleeper: We slept xxx ms, ten times longer than scheduled: 10000
2009-02-24 10:01:33,516 WARN org.apache.hadoop.hbase.util.Sleeper: We slept xxx ms, ten times longer than scheduled: 15000
2009-02-24 10:01:36,472 WARN org.apache.hadoop.hbase.regionserver.HRegionServer: unable to report to master for xxx milliseconds - retrying
```
...或者看到完整的 GC 壓縮,那么您可能正在體驗完整的 GC。
#### 136.2.6。 “沒有活動節點包含當前塊”和/或 YouAreDeadException
這些錯誤可能在用完 OS 文件句柄時或在節點無法訪問的嚴重網絡問題期間發生。
請參閱有關 ulimit 和 nproc 配置的“入門”部分,并檢查您的網絡。
#### 136.2.7。 ZooKeeper SessionExpired 事件
Master 或 RegionServers 關閉日志中的消息:
```
WARN org.apache.zookeeper.ClientCnxn: Exception
closing session 0x278bd16a96000f to sun.nio.ch.SelectionKeyImpl@355811ec
java.io.IOException: TIMED OUT
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:906)
WARN org.apache.hadoop.hbase.util.Sleeper: We slept 79410ms, ten times longer than scheduled: 5000
INFO org.apache.zookeeper.ClientCnxn: Attempting connection to server hostname/IP:PORT
INFO org.apache.zookeeper.ClientCnxn: Priming connection to java.nio.channels.SocketChannel[connected local=/IP:PORT remote=hostname/IP:PORT]
INFO org.apache.zookeeper.ClientCnxn: Server connection successful
WARN org.apache.zookeeper.ClientCnxn: Exception closing session 0x278bd16a96000d to sun.nio.ch.SelectionKeyImpl@3544d65e
java.io.IOException: Session Expired
at org.apache.zookeeper.ClientCnxn$SendThread.readConnectResult(ClientCnxn.java:589)
at org.apache.zookeeper.ClientCnxn$SendThread.doIO(ClientCnxn.java:709)
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:945)
ERROR org.apache.hadoop.hbase.regionserver.HRegionServer: ZooKeeper session expired
```
JVM 正在進行長時間運行的垃圾收集,這會暫停每個線程(也就是“停止世界”)。由于 RegionServer 的本地 ZooKeeper 客戶端無法發送心跳,因此會話超時。根據設計,我們會在超時后關閉任何無法聯系 ZooKeeper 集合的節點,以便它停止提供可能已在其他地方分配的數據。
* 確保你提供足夠的 RAM(在 _hbase-env.sh_ 中),默認的 1GB 將無法維持長時間運行的導入。
* 確保不交換,JVM 在交換時從不表現良好。
* 確保您沒有 CPU 占用 RegionServer 線程。例如,如果在具有 4 個內核的計算機上使用 6 個 CPU 密集型任務運行 MapReduce 作業,則可能會使 RegionServer 匱乏,從而導致更長時間的垃圾收集暫停。
* 增加 ZooKeeper 會話超時
如果您希望增加會話超時,請將以下內容添加到 _hbase-site.xml_ ,以將超時從默認值 60 秒增加到 120 秒。
```
<property>
<name>zookeeper.session.timeout</name>
<value>120000</value>
</property>
<property>
<name>hbase.zookeeper.property.tickTime</name>
<value>6000</value>
</property>
```
請注意,設置較高的超時意味著由失敗的 RegionServer 服務的區域將至少花費該時間量傳輸到另一個 RegionServer。對于提供實時請求的生產系統,我們建議將其設置為低于 1 分鐘并過度配置群集,以便每臺計算機上的內存負載越低(因此每臺計算機收集的垃圾越少)。
如果在只發生一次的上傳過程中發生這種情況(比如最初將所有數據加載到 HBase 中),請考慮批量加載。
有關 ZooKeeper 故障排除的其他一般信息,請參閱 [ZooKeeper,Cluster Canary](#trouble.zookeeper.general) 。
#### 136.2.8。 NotServingRegionException
在 DEBUG 級別的 RegionServer 日志中找到此異常是“正常”。此異常將返回給客戶端,然后客戶端返回`hbase:meta`以查找已移動區域的新位置。
但是,如果 NotServingRegionException 被記錄為 ERROR,則客戶端用盡了重試并且可能出現了錯誤。
#### 136.2.9。日志充斥著'2011-01-10 12:40:48,407 INFO org.apache.hadoop.io.compress.CodecPool:Gotbrand-new compressor'消息
我們沒有使用壓縮庫的本機版本。參見 [HBASE-1900 釋放 hadoop 0.21 后放回原生支持](https://issues.apache.org/jira/browse/HBASE-1900)。從 HBase lib 目錄下的 hadoop 復制本機庫或將它們符號鏈接到位,消息應該消失。
#### 136.2.10。 60020 上的服務器處理程序 X 捕獲:java.nio.channels.ClosedChannelException
如果您看到此類消息,則表示區域服務器正在嘗試從/向客戶端讀取/發送數據,但它已經消失。造成這種情況的典型原因是客戶端被殺死(當 MapReduce 作業被終止或失敗時,您會看到類似這樣的消息)或者客戶端收到 SocketTimeoutException。它是無害的,但如果你沒有做一些觸發它們,你應該考慮多挖一點。
### 136.3。反向 DNS 導致的快照錯誤
HBase 中的多個操作(包括快照)依賴于正確配置的反向 DNS。某些環境(如 Amazon EC2)在反向 DNS 方面存在問題。如果在 RegionServers 上看到如下錯誤,請檢查反向 DNS 配置:
```
2013-05-01 00:04:56,356 DEBUG org.apache.hadoop.hbase.procedure.Subprocedure: Subprocedure 'backup1'
coordinator notified of 'acquire', waiting on 'reached' or 'abort' from coordinator.
```
通常,RegionServer 報告的主機名需要與 Master 嘗試訪問的主機名相同。您可以通過在啟動時在 RegionServer 的日志中查找以下類型的消息來查看主機名不匹配。
```
2013-05-01 00:03:00,614 INFO org.apache.hadoop.hbase.regionserver.HRegionServer: Master passed us hostname
to use. Was=myhost-1234, Now=ip-10-55-88-99.ec2.internal
```
### 136.4。關機錯誤
## 137.碩士
有關 Master 的更多信息,請參閱 [master](#architecture.master) 。
### 137.1。啟動錯誤
#### 137.1.1。 Master 說您需要運行 HBase 遷移腳本
運行時,HBase 遷移腳本說根目錄中沒有文件。
HBase 期望根目錄不存在,或者已經由 HBase 先前運行初始化。如果使用 Hadoop DFS 為 HBase 創建新目錄,則會發生此錯誤。確保 HBase 根目錄當前不存在或已由先前的 HBase 運行初始化。確定的解決方案是使用 Hadoop dfs 刪除 HBase 根目錄,讓 HBase 創建并初始化目錄本身。
#### 137.1.2。包 len6080218 超出范圍!
如果群集中有許多區域,并且您在日志中看到此部分標題中上面報告的錯誤,請參閱 [HBASE-4246 群集太多的區域無法承受某些主故障轉移方案](https://issues.apache.org/jira/browse/HBASE-4246)。
#### 137.1.3。由于缺少文件系統的 hsync,Master 無法激活
HBase 的集群操作內部框架需要能夠在寫入日志中持久保存狀態。當使用支持檢查所需呼叫可用性的 Apache Hadoop Common 文件系統 API 版本時,如果發現它無法安全運行,HBase 將主動中止群集。
對于主角色,失敗將顯示在這樣的日志中:
```
2018-04-05 11:18:44,653 ERROR [Thread-21] master.HMaster: Failed to become active master
java.lang.IllegalStateException: The procedure WAL relies on the ability to hsync for proper operation during component failures, but the underlying filesystem does not support doing so. Please check the config value of 'hbase.procedure.store.wal.use.hsync' to set the desired level of robustness and ensure the config value of 'hbase.wal.dir' points to a FileSystem mount that can provide it.
at org.apache.hadoop.hbase.procedure2.store.wal.WALProcedureStore.rollWriter(WALProcedureStore.java:1034)
at org.apache.hadoop.hbase.procedure2.store.wal.WALProcedureStore.recoverLease(WALProcedureStore.java:374)
at org.apache.hadoop.hbase.procedure2.ProcedureExecutor.start(ProcedureExecutor.java:530)
at org.apache.hadoop.hbase.master.HMaster.startProcedureExecutor(HMaster.java:1267)
at org.apache.hadoop.hbase.master.HMaster.startServiceThreads(HMaster.java:1173)
at org.apache.hadoop.hbase.master.HMaster.finishActiveMasterInitialization(HMaster.java:881)
at org.apache.hadoop.hbase.master.HMaster.startActiveMasterManager(HMaster.java:2048)
at org.apache.hadoop.hbase.master.HMaster.lambda$run$0(HMaster.java:568)
at java.lang.Thread.run(Thread.java:745)
```
If you are attempting to run in standalone mode and see this error, please walk back through the section [Quick Start - Standalone HBase](#quickstart) and ensure you have included **all** the given configuration settings.
### 137.2。關機錯誤
## 138\. ZooKeeper
### 138.1。啟動錯誤
#### 138.1.1。找不到我的地址:ZooKeeper 仲裁服務器列表中的 xyz
ZooKeeper 服務器無法啟動,拋出該錯誤。 xyz 是服務器的名稱。
這是名稱查找問題。 HBase 嘗試在某臺機器上啟動 ZooKeeper 服務器,但該機器無法在`hbase.zookeeper.quorum`配置中找到自己。
使用錯誤消息中顯示的主機名而不是您使用的值。如果您有 DNS 服務器,可以在 _hbase-site.xml_ 中設置`hbase.zookeeper.dns.interface`和`hbase.zookeeper.dns.nameserver`,以確保它解析為正確的 FQDN。
### 138.2。 ZooKeeper,群集金絲雀
ZooKeeper 是集群的“礦井中的金絲雀”。它將是第一個發現問題的人,如果有的話,確保它的快樂是一個嗡嗡聲集群的捷徑。
請參見 [ZooKeeper 操作環境故障排除](https://wiki.apache.org/hadoop/ZooKeeper/Troubleshooting)頁面。它有檢查磁盤和網絡性能的建議和工具;即運行 ZooKeeper 和 HBase 的操作環境。
此外,實用程序 [zkcli](#trouble.tools.builtin.zkcli) 可能有助于調查 ZooKeeper 問題。
## 139.亞馬遜 EC2
### 139.1。 ZooKeeper 似乎不適用于 Amazon EC2
部署為 Amazon EC2 實例時,HBase 無法啟動。以下例外顯示在主服務器和/或 RegionServer 日志中:
```
2009-10-19 11:52:27,030 INFO org.apache.zookeeper.ClientCnxn: Attempting
connection to server ec2-174-129-15-236.compute-1.amazonaws.com/10.244.9.171:2181
2009-10-19 11:52:27,032 WARN org.apache.zookeeper.ClientCnxn: Exception
closing session 0x0 to sun.nio.ch.SelectionKeyImpl@656dc861
java.net.ConnectException: Connection refused
```
安全組策略阻止公共地址上的 ZooKeeper 端口。配置 ZooKeeper 仲裁對等體列表時,請使用內部 EC2 主機名。
### 139.2。 Amazon EC2 上的不穩定性
有關 HBase 和 Amazon EC2 的問題經常出現在 HBase dist-list 上。使用[搜索舊線程搜索 Hadoop](http://search-hadoop.com/)
### 139.3。遠程 Java 連接到 EC2 群集不起作用
請參閱安德魯的答案,在用戶列表中:[遠程 Java 客戶端連接到 EC2 實例](http://search-hadoop.com/m/sPdqNFAwyg2)。
## 140\. HBase 和 Hadoop 版本問題
### 140.1。 ...無法與客戶端版本通信...
如果您在日志中看到類似以下內容的內容... 2012-09-24 10:20:52,168 致命 org.apache.hadoop.hbase.master.HMaster:未處理的異常。開始關機。 org.apache.hadoop.ipc.RemoteException:服務器 IPC 版本 7 無法與客戶端版本 4 通信... ...您是否正在嘗試從具有 Hadoop 1.0.x 客戶端的 HBase 與 Hadoop 2.0.x 進行通信?使用針對 Hadoop 2.0 構建的 HBase 或重建 HBase,將-Dhadoop.profile = 2.0 屬性傳遞給 Maven(參見[針對各種 hadoop 版本構建。](#maven.build.hadoop)了解更多信息)。
## 141\. HBase 和 HDFS
Apache HDFS 的常規配置指南超出了本指南的范圍。有關配置 HDFS 的詳細信息,請參閱 [https://hadoop.apache.org/](https://hadoop.apache.org/) 中提供的文檔。本節以 HBase 的形式介紹 HDFS。
在大多數情況下,HBase 將其數據存儲在 Apache HDFS 中。這包括包含數據的 HFile,以及在將數據寫入 HFile 之前存儲數據并防止 RegionServer 崩潰的預寫日志(WAL)。 HDFS 為 HBase 中的數據提供可靠性和保護,因為它是分布式的。為了以最高效率運行,HBase 需要在本地提供數據。因此,最好在每個 RegionServer 上運行 HDFS DataNode。
HBase 和 HDFS 的重要信息和指南
HBase 是 HDFS 的客戶端。
HBase 是一個 HDFS 客戶端,使用 HDFS `DFSClient`類,對此類的引用出現在 HBase 日志中,帶有其他 HDFS 客戶端日志消息。
在多個地方需要配置。
與 HBase 相關的一些 HDFS 配置需要在 HDFS(服務器)端完成。其他必須在 HBase 內完成(在客戶端)。需要在服務器端和客戶端設置其他設置。
影響 HBase 的寫入錯誤可能會記錄在 HDFS 日志中而不是 HBase 日志中。
寫入時,HDFS 將通信從一個 DataNode 傳輸到另一個 DataNode。 HBase 使用 HDFS 客戶端類與 HDFS NameNode 和 DataNode 進行通信。 DataNode 之間的通信問題記錄在 HDFS 日志中,而不是 HBase 日志中。
HBase 使用兩個不同的端口與 HDFS 通信。
HBase 使用`ipc.Client`接口和`DataNode`類與 DataNode 通信。對這些的引用將出現在 HBase 日志中。這些通信信道中的每一個使用不同的端口(默認為 50010 和 50020)。通過`dfs.datanode.address`和`dfs.datanode.ipc.address`參數在 HDFS 配置中配置端口。
可能會在 HBase,HDFS 或兩者中記錄錯誤。
在對 HBase 中的 HDFS 問題進行故障排除時,請檢查兩個位置的日志以查找錯誤。
HDFS 需要一段時間才能將節點標記為已死。您可以配置 HDFS 以避免使用陳舊的 DataNode。
默認情況下,HDFS 不會將節點標記為已死,直到 630 秒無法訪問。在 Hadoop 1.1 和 Hadoop 2.x 中,可以通過啟用對陳舊 DataNode 的檢查來緩解此問題,但默認情況下禁用此檢查。您可以通過`dfs.namenode.avoid.read.stale.datanode`和`dfs.namenode.avoid.write.stale.datanode settings`分別啟用讀取和寫入檢查。陳舊的 DataNode 是`dfs.namenode.stale.datanode.interval`無法訪問的(默認為 30 秒)。避免過時的數據節點,并將其標記為讀取或寫入操作的最后可能目標。有關配置詳細信息,請參閱 HDFS 文檔。
HDFS 重試和超時的設置對 HBase 很重要。
您可以配置各種重試和超時的設置。請始終參考 HDFS 文檔以獲取當前建議和默認值。這里列出了一些對 HBase 很重要的設置。默認值是 Hadoop 2.3 的最新版本。查看 Hadoop 文檔以獲取最新的值和建議。
HBase Balancer 和 HDFS Balancer 不兼容
HDFS 平衡器嘗試在 DataNode 中均勻分布 HDFS 塊。在區域分裂或失敗后,HBase 依賴于壓縮來恢復局部性。這兩種類型的平衡不能很好地協同工作。
過去,普遍接受的建議是關閉 HDFS 負載均衡器并依賴 HBase 均衡器,因為 HDFS 均衡器會降低本地性能。如果您的 HDFS 版本低于 2.7.1,此建議仍然有效。
[HDFS-6133](https://issues.apache.org/jira/browse/HDFS-6133) 通過在 HDFS 服務配置中將`dfs.datanode.block-pinning.enabled`屬性設置為`true`,可以從 HDFS 負載均衡器中排除優先節點(固定)塊。
通過將 HBase 平衡器類(conf:`hbase.master.loadbalancer.class`)切換為`org.apache.hadoop.hbase.favored.FavoredNodeLoadBalancer`,可以啟用 HBase 以使用 HDFS 優先節點功能,此處記錄 [](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/favored/FavoredNodeLoadBalancer.html) 。
> HDFS-6133 在 HDFS 2.7.0 及更高版本中可用,但 HBase 不支持在 HDFS 2.7.0 上運行,因此您必須使用 HDFS 2.7.1 或更高版本才能將此功能與 HBase 一起使用。
連接超時
客戶端(HBASE)和 HDFS DataNode 之間發生連接超時。它們可能在建立連接,嘗試讀取或嘗試寫入時發生。下面的兩個設置組合使用,并影響 DFSClient 和 DataNode,ipc.cClient 和 DataNode 之間的連接,以及兩個 DataNode 之間的通信。
`dfs.client.socket-timeout`(默認值:60000)
建立連接或讀取時客戶端連接超時之前的時間。該值以毫秒表示,因此默認值為 60 秒。
`dfs.datanode.socket.write.timeout`(默認值:480000)
寫操作超時前的時間。默認值為 8 分鐘,以毫秒表示。
典型的錯誤日志
日志中經常會出現以下類型的錯誤。
`INFO HDFS.DFSClient: Failed to connect to /xxx50010, add to deadNodes and continue java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for connect. ch : java.nio.channels.SocketChannel[connection-pending remote=/region-server-1:50010]` ::塊的所有 DataNode 都已死,無法恢復。以下是導致此錯誤的事件序列:
`INFO org.apache.hadoop.HDFS.DFSClient: Exception in createBlockOutputStream java.net.SocketTimeoutException: 69000 millis timeout while waiting for channel to be ready for connect. ch : java.nio.channels.SocketChannel[connection-pending remote=/ xxx:50010]` ::此類錯誤表示寫入問題。在這種情況下,主人想要分割日志。它沒有本地 DataNode,因此它嘗試連接到遠程 DataNode,但 DataNode 已經死了。
## 142.運行單元或集成測試
### 142.1。運行測試時 MiniDFSCluster 的運行時異常
如果您看到以下內容
```
...
java.lang.NullPointerException: null
at org.apache.hadoop.hdfs.MiniDFSCluster.startDataNodes
at org.apache.hadoop.hdfs.MiniDFSCluster.<init>
at org.apache.hadoop.hbase.MiniHBaseCluster.<init>
at org.apache.hadoop.hbase.HBaseTestingUtility.startMiniDFSCluster
at org.apache.hadoop.hbase.HBaseTestingUtility.startMiniCluster
...
```
要么
```
...
java.io.IOException: Shutting down
at org.apache.hadoop.hbase.MiniHBaseCluster.init
at org.apache.hadoop.hbase.MiniHBaseCluster.<init>
at org.apache.hadoop.hbase.MiniHBaseCluster.<init>
at org.apache.hadoop.hbase.HBaseTestingUtility.startMiniHBaseCluster
at org.apache.hadoop.hbase.HBaseTestingUtility.startMiniCluster
...
```
...然后在啟動測試之前嘗試發出命令 umask 022。這是 [HDFS-2556](https://issues.apache.org/jira/browse/HDFS-2556) 的解決方法
## 143.案例研究
有關性能和故障排除案例研究,請參閱 [Apache HBase 案例研究](#casestudies)。
## 144.密碼特征
### 144.1。 sun.security.pkcs11.wrapper.PKCS11Exception:CKR_ARGUMENTS_BAD
此問題表現為最終由以下原因引起的異常:
```
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_ARGUMENTS_BAD
at sun.security.pkcs11.wrapper.PKCS11.C_DecryptUpdate(Native Method)
at sun.security.pkcs11.P11Cipher.implDoFinal(P11Cipher.java:795)
```
此問題似乎會影響某些 Linux 供應商提供的某些版本的 OpenJDK 7。 NSS 配置為默認提供程序。如果主機具有 x86_64 體系結構,則根據供應商軟件包是否包含缺陷,NSS 提供程序將無法正常運行。
要解決此問題,請找到 JRE 主目錄并編輯文件 _lib / security / java.security_ 。編輯文件以注釋掉該行:
```
security.provider.1=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/nss.cfg
```
然后相應地重新編號其余的提供者。
## 145.操作系統特定問題
### 145.1。頁面分配失敗
> 眾所周知,這個問題會影響 CentOS 6.2 和 CentOS 6.5。根據 [https://bugzilla.redhat.com/show_bug.cgi?id=770545](https://bugzilla.redhat.com/show_bug.cgi?id=770545) ,它也可能會影響某些版本的 Red Hat Enterprise Linux。
有些用戶報告看到以下錯誤:
```
kernel: java: page allocation failure. order:4, mode:0x20
```
據報道,提高`min_free_kbytes`的價值可以解決這個問題。此參數設置為系統上 RAM 量的百分比,并在 [http://www.centos.org/docs/5/html/5.1/Deployment_Guide/s3-proc-中有更詳細的描述。 sys-vm.html](http://www.centos.org/docs/5/html/5.1/Deployment_Guide/s3-proc-sys-vm.html) 。
要在系統上查找當前值,請運行以下命令:
```
[user@host]# cat /proc/sys/vm/min_free_kbytes
```
接下來,提高價值。嘗試加倍,然后將值翻兩番。請注意,將值設置得太低或太高可能會對系統產生不利影響。有關具體建議,請咨詢操作系統供應商。
使用以下命令修改`min_free_kbytes`的值,將 _<value></value>_ 替換為您的預期值:
```
[user@host]# echo <value> > /proc/sys/vm/min_free_kbytes
```
## 146\. JDK 問題
### 146.1。 NoSuchMethodError:java.util.concurrent.ConcurrentHashMap.keySet
如果你在日志中看到這個:
```
Caused by: java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
at org.apache.hadoop.hbase.master.ServerManager.findServerWithSameHostnamePortWithLock(ServerManager.java:393)
at org.apache.hadoop.hbase.master.ServerManager.checkAndRecordNewServer(ServerManager.java:307)
at org.apache.hadoop.hbase.master.ServerManager.regionServerStartup(ServerManager.java:244)
at org.apache.hadoop.hbase.master.MasterRpcServices.regionServerStartup(MasterRpcServices.java:304)
at org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos$RegionServerStatusService$2.callBlockingMethod(RegionServerStatusProtos.java:7910)
at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2020)
... 4 more
```
然后檢查你是否用 jdk8 編譯并嘗試在 jdk7 上運行它。如果是這樣,這將無效。在 jdk8 上運行或使用 jdk7 重新編譯。如果在 JRE 7 上運行,請參見 [HBASE-10607 JDK8 NoSuchMethodError 涉及 ConcurrentHashMap.keySet。](https://issues.apache.org/jira/browse/HBASE-10607)
- HBase? 中文參考指南 3.0
- Preface
- Getting Started
- Apache HBase Configuration
- Upgrading
- The Apache HBase Shell
- Data Model
- HBase and Schema Design
- RegionServer Sizing Rules of Thumb
- HBase and MapReduce
- Securing Apache HBase
- Architecture
- In-memory Compaction
- Backup and Restore
- Synchronous Replication
- Apache HBase APIs
- Apache HBase External APIs
- Thrift API and Filter Language
- HBase and Spark
- Apache HBase Coprocessors
- Apache HBase Performance Tuning
- Troubleshooting and Debugging Apache HBase
- Apache HBase Case Studies
- Apache HBase Operational Management
- Building and Developing Apache HBase
- Unit Testing HBase Applications
- Protobuf in HBase
- Procedure Framework (Pv2): HBASE-12439
- AMv2 Description for Devs
- ZooKeeper
- Community
- Appendix