# 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.日志

关键过程日志如下...（将&lt;user&gt;替换为启动服务的用户，将&lt;hostname&gt;替换为机器名称）&lt;/hostname&gt;&lt;/user&gt;

NameNode：_ $ HADOOP _HOME / logs / hadoop- &lt;user&gt;-namenode- &lt;hostname&gt;.log&lt;/hostname&gt;&lt;/user&gt;_

DataNode：_ $ HADOOP _HOME / logs / hadoop- &lt;user&gt;-datanode- &lt;hostname&gt;.log&lt;/hostname&gt;&lt;/user&gt;_

JobTracker：_ $ HADOOP _HOME / logs / hadoop- &lt;user&gt;-jobtracker- &lt;hostname&gt;.log&lt;/hostname&gt;&lt;/user&gt;_

TaskTracker：_ $ HADOOP _HOME / logs / hadoop- &lt;user&gt;-tasktracker- &lt;hostname&gt;.log&lt;/hostname&gt;&lt;/user&gt;_

HMaster：_ $ HBASE _HOME / logs / hbase- &lt;user&gt;-master- &lt;hostname&gt;.log&lt;/hostname&gt;&lt;/user&gt;_

RegionServer：_ $ HBASE _HOME / logs / hbase- &lt;user&gt;-regionserver- &lt;hostname&gt;.log&lt;/hostname&gt;&lt;/user&gt;_

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`&gt;来防止它。 `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 安装到 _&lt;java-home&gt;/ lib / security&lt;/java-home&gt;_ 中。

## 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/&lt;_tablename_&gt;/&lt;_region_&gt;/&lt;_column_family_&gt;/`中。

```
*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`的值，将 _&lt;value&gt;&lt;/value&gt;_ 替换为您的预期值：

```
[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)