HBASE 故障排除

本文介绍处理 Apache Ambari 中的 HBASE 有效负载时遇到的最常见问题及其解决方法。

如何对多个未分配区域运行 hbck 命令报告

当 HBase 用户运行“hbase hbck”命令时,会出现“多个区域未分配,或者区域链中出现漏洞”错误消息,这是一个常见问题。

用户可以在 HBase Master UI 中看到所有区域服务器中非均衡区域的计数。 然后,用户可以运行“hbase hbck”命令,并且会在区域链中看到漏洞。

用户应首先修复分配问题,因为漏洞可能起因于这些区域脱机。

执行以下步骤,让未分配区域重新回到正常状态:

  1. 使用 SSH 登录到 HDInsight HBase 群集。
  2. 运行“hbase zkcli”命令,使用 zookeeper shell 进行连接。
  3. 运行“rmr /hbase/regions-in-transition”或“rmr /hbase-unsecure/regions-in-transition”命令。
  4. 使用“exit”命令从“hbase zkcli”shell 退出。
  5. 打开 Ambari UI,从 Ambari 重启活动 HBase Master 服务。
  6. 再次运行“hbase hbck”命令(没有任何其他选项)。

查看步骤 6 中命令的输出,确保所有区域均已分配。


如何解决用于区域分配的 hbck 命令的超时问题

可能的原因

此问题的可能原因是,多个区域长时间处于“过渡”状态。 从 HBase Master UI 中看,这些区域可能显示为脱机。 由于尝试过渡的区域过多,HBase Master 可能会超时,因此无法让这些区域重新回到联机状态。

解决步骤

以下是解决 hbck 超时问题的步骤:

  1. 使用 SSH 登录到 HDInsight HBase 群集。
  2. 运行“hbase zkcli”命令,使用 zookeeper shell 进行连接。
  3. 运行“rmr /hbase/regions-in-transition”或“rmr /hbase-unsecure/regions-in-transition”命令。
  4. 使用“exit”命令从“hbase zkcli”shell 退出。
  5. 打开 Ambari UI,从 Ambari 重启活动 HBase Master 服务。
  6. 再次运行“hbase hbck -fixAssignments”命令,这样就不会再次超时。

如何在群集中强制禁用 HDFS 安全模式

问题:

本地 HDFS 在 HDInsight 群集中卡在安全模式。

详细说明:

无法运行简单的 HDFS 命令,如下所示:

hdfs dfs -D "fs.default.name=hdfs://mycluster/" -mkdir /temp

尝试运行上述命令时遇到的错误如下所示:

hdiuser@hn0-spark2:~$ hdfs dfs -D "fs.default.name=hdfs://mycluster/" -mkdir /temp
17/04/05 16:20:52 WARN retry.RetryInvocationHandler: Exception while invoking ClientNamenodeProtocolTranslatorPB.mkdirs over hn0-spark2.2oyzcdm4sfjuzjmj5dnmvscjpg.dx.internal.chinacloudapp.cn/10.0.0.22:8020. Not retrying because try once and fail.
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.SafeModeException): Cannot create directory /temp. Name node is in safe mode.
It was turned on manually. Use "hdfs dfsadmin -safemode leave" to turn safe mode off.
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkNameNodeSafeMode(FSNamesystem.java:1359)
        at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirs(FSNamesystem.java:4010)
        at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.mkdirs(NameNodeRpcServer.java:1102)
        at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.mkdirs(ClientNamenodeProtocolServerSideTranslatorPB.java:630)
        at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:640)
        at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:982)
        at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2313)
        at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2309)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1724)
        at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2307)
        at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1552)
        at org.apache.hadoop.ipc.Client.call(Client.java:1496)
        at org.apache.hadoop.ipc.Client.call(Client.java:1396)
        at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:233)
        at com.sun.proxy.$Proxy10.mkdirs(Unknown Source)
        at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.mkdirs(ClientNamenodeProtocolTranslatorPB.java:603)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:278)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:194)
        at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:176)
        at com.sun.proxy.$Proxy11.mkdirs(Unknown Source)
        at org.apache.hadoop.hdfs.DFSClient.primitiveMkdir(DFSClient.java:3061)
        at org.apache.hadoop.hdfs.DFSClient.mkdirs(DFSClient.java:3031)
        at org.apache.hadoop.hdfs.DistributedFileSystem$24.doCall(DistributedFileSystem.java:1162)
        at org.apache.hadoop.hdfs.DistributedFileSystem$24.doCall(DistributedFileSystem.java:1158)
        at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)
        at org.apache.hadoop.hdfs.DistributedFileSystem.mkdirsInternal(DistributedFileSystem.java:1158)
        at org.apache.hadoop.hdfs.DistributedFileSystem.mkdirs(DistributedFileSystem.java:1150)
        at org.apache.hadoop.fs.FileSystem.mkdirs(FileSystem.java:1898)
        at org.apache.hadoop.fs.shell.Mkdir.processNonexistentPath(Mkdir.java:76)
        at org.apache.hadoop.fs.shell.Command.processArgument(Command.java:273)
        at org.apache.hadoop.fs.shell.Command.processArguments(Command.java:255)
        at org.apache.hadoop.fs.shell.FsCommand.processRawArguments(FsCommand.java:119)
        at org.apache.hadoop.fs.shell.Command.run(Command.java:165)
        at org.apache.hadoop.fs.FsShell.run(FsShell.java:297)
        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76)
        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:90)
        at org.apache.hadoop.fs.FsShell.main(FsShell.java:350)
mkdir: Cannot create directory /temp. Name node is in safe mode.

可能的原因:

HDInsight 群集已纵向收缩成很少的节点,低于或接近 HDFS 复制因子的要求。

解决步骤:

  • 使用以下命令报告 HDInsight 群集中 HDFS 的状态:
hdfs dfsadmin -D "fs.default.name=hdfs://mycluster/" -report
hdiuser@hn0-spark2:~$ hdfs dfsadmin -D "fs.default.name=hdfs://mycluster/" -report
Safe mode is ON
Configured Capacity: 3372381241344 (3.07 TB)
Present Capacity: 3138625077248 (2.85 TB)
DFS Remaining: 3102710317056 (2.82 TB)
DFS Used: 35914760192 (33.45 GB)
DFS Used%: 1.14%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0
Missing blocks (with replication factor 1): 0

-------------------------------------------------
Live datanodes (8):

Name: 10.0.0.17:30010 (10.0.0.17)
Hostname: 10.0.0.17
Decommission Status : Normal
Configured Capacity: 421547655168 (392.60 GB)
DFS Used: 5288128512 (4.92 GB)
Non DFS Used: 29087272960 (27.09 GB)
DFS Remaining: 387172253696 (360.58 GB)
DFS Used%: 1.25%
DFS Remaining%: 91.85%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 2
Last contact: Wed Apr 05 16:22:00 UTC 2017
...
  • 也可使用以下命令查看 HDInsight 群集中 HDFS 的完整性:
hdiuser@hn0-spark2:~$ hdfs fsck -D "fs.default.name=hdfs://mycluster/" /
Connecting to namenode via http://hn0-spark2.2oyzcdm4sfjuzjmj5dnmvscjpg.dx.internal.chinacloudapp.cn:30070/fsck?ugi=hdiuser&path=%2F
FSCK started by hdiuser (auth:SIMPLE) from /10.0.0.22 for path / at Wed Apr 05 16:40:28 UTC 2017
....................................................................................................

....................................................................................................
..................Status: HEALTHY
 Total size:    9330539472 B
 Total dirs:    37
 Total files:   2618
 Total symlinks:                0 (Files currently being written: 2)
 Total blocks (validated):      2535 (avg. block size 3680686 B)
 Minimally replicated blocks:   2535 (100.0 %)
 Over-replicated blocks:        0 (0.0 %)
 Under-replicated blocks:       0 (0.0 %)
 Mis-replicated blocks:         0 (0.0 %)
 Default replication factor:    3
 Average block replication:     3.0
 Corrupt blocks:                0
 Missing replicas:              0 (0.0 %)
 Number of data-nodes:          8
 Number of racks:               1
FSCK ended at Wed Apr 05 16:40:28 UTC 2017 in 187 milliseconds

The filesystem under path '/' is HEALTHY
  • 如果确定没有块处于缺失、损坏或复制状态,或者确定可以忽略这块,则请运行以下命令,使指定节点脱离安全模式:
hdfs dfsadmin -D "fs.default.name=hdfs://mycluster/" -safemode leave

如何解决 Apache Phoenix 的 JDBC 或 sqlline 连接问题

解决步骤:

若要使用 Apache Phoenix 进行连接,必须提供活动 zookeeper 节点的 IP。 确保 sqlline.py 尝试连接的 zookeeper 服务已启动并运行。

  1. 执行 SSH 登录,登录到 HDInsight 群集。
  2. 尝试以下命令:
"/usr/hdp/current/phoenix-client/bin/sqlline.py <IP of machine where Active Zookeeper is running"
Note: The IP of Active Zooker node can be identified from Ambari UI, by following the links to HBase -> "Quick Links" -> "ZK* (Active)" -> "Zookeeper Info". 

如果 sqlline.py 连接到 Apache Phoenix 且没有超时,请运行以下命令,验证 Apache Phoenix 的可用性和运行状况:

!tables
!quit
  • 如果以上命令正常运行,则没有问题。 用户提供的 IP 可能不正确。

    但如果命令暂停很长时间,然后引发下述错误,则请按下面的故障排除指南操作:

Error while connecting to sqlline.py (Hbase - phoenix) Setting property: [isolation, TRANSACTION_READ_COMMITTED] issuing: !connect jdbc:phoenix:10.2.0.7 none none org.apache.phoenix.jdbc.PhoenixDriver Connecting to jdbc:phoenix:10.2.0.7 SLF4J: Class path contains multiple SLF4J bindings. 
  • 在头节点 (hn0) 中运行以下命令,诊断 Phoenix SYSTEM.CATALOG 表的状况:
hbase shell

count 'SYSTEM.CATALOG'
  • 该命令应返回如下所示的错误:
ERROR: org.apache.hadoop.hbase.NotServingRegionException: Region SYSTEM.CATALOG,,1485464083256.c0568c94033870c517ed36c45da98129. is not online on 10.2.0.5,16020,1489466172189) 
  • 执行以下步骤,在 Ambari UI 中重启所有 zookeeper 节点上的 HMaster 服务:

    a. 转到 HBase 的摘要部分中的“HBase -> 活动 HBase Master”链接。 a. 在“组件”部分重启 HBase Master 服务。 a. 对剩余的“备用 HBase Master”服务重复以上步骤。

HBase Master 服务稳定下来并完成恢复操作可能需要长达五分钟的时间。 等待数分钟后,重复 sqlline.py 命令,确认系统目录表已启动并可进行查询。

“SYSTEM.CATALOG”表回到正常状态以后,Apache Phoenix 的连接问题应会自动得到解决。

哪些因素导致主服务器无法启动

错误:

原子重命名失败

详细说明:

在启动过程中,HMaster 执行大量的初始化步骤,包括将数据从暂存 (.tmp) 文件夹移动到数据文件夹;它还会查看 WAL(预写日志)文件夹中是否存在任何僵死的区域服务器,等等。

在上述所有情况下,它都会对这些文件夹执行基本的“list”命令。 在任何时候,如果发现这些文件夹的任意一个中存在意外的文件,它会引发一个异常并因此不会启动。

可能的原因:

尝试查明文件创建时间线,并在区域服务器日志中查看在该时间附近是否有任何进程崩溃(可联系任何 HBase 职员来协助执行此操作)。 这样我们就可以提供更可靠的机制来避免出现此 Bug 并确保进程正常关闭。

解决步骤:

在这种情况下,请尝试检查调用堆栈并查看哪个文件夹可能导致问题(例如,是 WAL 文件夹还是 .tmp 文件夹)。 然后,通过 Cloud Explorer 或通过 hdfs 命令,尝试找到问题文件 - 通常,这是一个 *-renamePending.json 文件(一个用于在 WASB 驱动程序中实现自动重命名操作的日志文件;由于此实现中的 Bug,在发生进程崩溃之类的问题时,这样的文件可能会保留)。 可以通过 Cloud Explorer 强制删除此文件。

此外,有时候在此位置中可能会存在 $$$.$$$ 性质的临时文件,无法通过 Cloud Explorer 看到此文件,只能通过 hdfs ls 命令看到。 可以使用 hdfs 命令“hdfs dfs -rm //\$\$\$.\$\$\$”删除此文件。

执行此操作后,HMaster 应当会立即启动。

错误:未列出服务器地址

区域 xxx 的 hbase: meta 中未列出服务器地址

详细说明:

客户在 hbase: meta 表未联机的 Linux 群集上遇到问题。 运行 hbck 时报告了“在任何区域中都未发现 hbase: meta 表 replicaId 0”错误。 重启 HBase 后,症状变为 hmaster 无法初始化。 在 hmaster 日志中,它报告了“区域 hbase: backup 的 hbase: meta 中未列出服务器地址”错误。

解决步骤:

  • 在 HBase shell 中键入以下命令(根据情况更改实际值)。
> scan 'hbase:meta'  
> delete 'hbase:meta','hbase:backup <region name>','<column name>'  
  • 删除 hbase: namespace 条目,因为扫描 hbase: namespace 表时可能会报告相同的错误。

  • 从 Ambari UI 重启活动 HMaster,使 HBase 恢复运行状态。

  • 在 HBase shell 中运行以下命令,使所有脱机表联机:

hbase hbck -ignorePreCheckPermission -fixAssignments 

延伸阅读:

Unable to process HBase table(无法处理 HBase 表)

错误:

HMaster 超时且出现严重异常,例如,“java.io.IOException: 等待分配命名空间表时超时 300000 毫秒”

详细说明:

当客户明显有大量表和区域且在重启 HMaster 服务后未刷新时,就会遇到此问题。 重启失败且出现以上消息。 未发现其他错误。

可能的原因:

这是 HMaster 的一个已知缺陷(因为尚未分配命名空间表,一般群集启动任务可能会花费很长时间并且 HMaster 会关闭),只有存在大量未刷新的数据且五分钟的超时时间不够用时才会出现此问题。

解决步骤:

  • 访问 Ambari UI,转到“HBase”->“配置”,在自定义 hbase-site.xml 中添加以下设置:
Key: hbase.master.namespace.init.timeout Value: 2400000  
  • 重启所需的服务(主要是 HMaster,可能还有其他 HBase 服务)。

哪些因素导致在区域服务器上重启失败

可能的原因:

首先,可以通过以下最佳做法防止此类情况。 在计划重启 HBase 区域服务器时,建议暂停繁重的工作负荷活动。 如果在关闭过程中应用程序继续与区域服务器进行连接,则会将区域服务器重启操作拖慢几分钟。 另外,建议用户参考 HDInsight HBase: How to Improve HBase cluster restart time by Flushing tables(HDInsight HBase:如何通过刷新表来加快 HBase 群集重启时间)来刷新所有表。

如果用户通过 Ambari UI 在 HBase 区域服务器上开始重启操作, 就会立即看到区域服务器关闭,且太长时间没有重启。

下面是幕后发生的情况:

  1. Ambari 代理将向区域服务器发送停止请求。
  2. 然后,Ambari 代理等待 30 秒,让区域服务器正常关闭。
  3. 如果客户的应用程序继续与区域服务器进行连接,则区域服务器不会立即关闭,因此,30 秒的超时将很快到期。
  4. 在 30 秒到期后,Ambari 代理将向区域服务器发送强制终止命令 (kill -9)。 可以在 ambari-agent 日志(位于相应 workernode 的 /var/log/ 目录中)查看此情况,如下所示:
2017-03-21 13:22:09,171 - Execute['/usr/hdp/current/hbase-regionserver/bin/hbase-daemon.sh --config /usr/hdp/current/hbase-regionserver/conf stop regionserver'] {'only_if': 'ambari-sudo.sh  -H -E t
est -f /var/run/hbase/hbase-hbase-regionserver.pid && ps -p `ambari-sudo.sh  -H -E cat /var/run/hbase/hbase-hbase-regionserver.pid` >/dev/null 2>&1', 'on_timeout': '! ( ambari-sudo.sh  -H -E test -
f /var/run/hbase/hbase-hbase-regionserver.pid && ps -p `ambari-sudo.sh  -H -E cat /var/run/hbase/hbase-hbase-regionserver.pid` >/dev/null 2>&1 ) || ambari-sudo.sh -H -E kill -9 `ambari-sudo.sh  -H 
-E cat /var/run/hbase/hbase-hbase-regionserver.pid`', 'timeout': 30, 'user': 'hbase'}
2017-03-21 13:22:40,268 - Executing '! ( ambari-sudo.sh  -H -E test -f /var/run/hbase/hbase-hbase-regionserver.pid && ps -p `ambari-sudo.sh  -H -E cat /var/run/hbase/hbase-hbase-regionserver.pid` >
/dev/null 2>&1 ) || ambari-sudo.sh -H -E kill -9 `ambari-sudo.sh  -H -E cat /var/run/hbase/hbase-hbase-regionserver.pid`'. Reason: Execution of 'ambari-sudo.sh su hbase -l -s /bin/bash -c 'export  
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/var/lib/ambari-agent ; /usr/hdp/current/hbase-regionserver/bin/hbase-daemon.sh --config /usr/hdp/curre
nt/hbase-regionserver/conf stop regionserver was killed due timeout after 30 seconds
2017-03-21 13:22:40,285 - File['/var/run/hbase/hbase-hbase-regionserver.pid'] {'action': ['delete']}
2017-03-21 13:22:40,285 - Deleting File['/var/run/hbase/hbase-hbase-regionserver.pid']

由于此关闭很突然,尽管区域服务器进程已被终止,但与该进程关联的端口可能还没有释放。 此状况可能会导致在启动区域服务器时发生 AddressBindException,如以下日志所示。 可以在启动区域服务器失败时所在工作节点的 /var/log/hbase 目录的 region-server.log 中验证此情况。

2017-03-21 13:25:47,061 ERROR [main] regionserver.HRegionServerCommandLine: Region server exiting
java.lang.RuntimeException: Failed construction of Regionserver: class org.apache.hadoop.hbase.regionserver.HRegionServer
at org.apache.hadoop.hbase.regionserver.HRegionServer.constructRegionServer(HRegionServer.java:2636)
at org.apache.hadoop.hbase.regionserver.HRegionServerCommandLine.start(HRegionServerCommandLine.java:64)
at org.apache.hadoop.hbase.regionserver.HRegionServerCommandLine.run(HRegionServerCommandLine.java:87)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76)
at org.apache.hadoop.hbase.util.ServerCommandLine.doMain(ServerCommandLine.java:126)
at org.apache.hadoop.hbase.regionserver.HRegionServer.main(HRegionServer.java:2651)

Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.apache.hadoop.hbase.regionserver.HRegionServer.constructRegionServer(HRegionServer.java:2634)
... 5 more

Caused by: java.net.BindException: Problem binding to /10.2.0.4:16020 : Address already in use
at org.apache.hadoop.hbase.ipc.RpcServer.bind(RpcServer.java:2497)
at org.apache.hadoop.hbase.ipc.RpcServer$Listener.<init>(RpcServer.java:580)
at org.apache.hadoop.hbase.ipc.RpcServer.<init>(RpcServer.java:1982)
at org.apache.hadoop.hbase.regionserver.RSRpcServices.<init>(RSRpcServices.java:863)
at org.apache.hadoop.hbase.regionserver.HRegionServer.createRpcServices(HRegionServer.java:632)
at org.apache.hadoop.hbase.regionserver.HRegionServer.<init>(HRegionServer.java:532)
... 10 more

Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:463)
at sun.nio.ch.Net.bind(Net.java:455)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.hadoop.hbase.ipc.RpcServer.bind(RpcServer.java:2495)
... 15 more

解决步骤:

出现这类情况时,可以尝试以下解决方法:

  • 在开始重启之前尝试降低 HBase 区域服务器上的负载。

  • 另外(如果以上步骤没有帮助),请尝试使用以下命令,手动重启工作节点上的区域服务器:

sudo su - hbase -c "/usr/hdp/current/hbase-regionserver/bin/hbase-daemon.sh stop regionserver"
sudo su - hbase -c "/usr/hdp/current/hbase-regionserver/bin/hbase-daemon.sh start regionserver"