在使用 SparkStreaming 程序处理数据,结果写入 HBase 时,遇到异常 NotServingRegionException,只是突然出现一次,平时正常,怀疑是和开发环境有关,本文记录查找问题的过程。本文中涉及的开发环境为 HBase v1.1.2。
问题出现
SparkStreaming 程序处理数据,结果写入 HBase,出现异常,并且一直持续:
1 | 2019-10-13_16:40:31 [JobGenerator] INFO consumer.SimpleConsumer:68: Reconnect due to socket error: java.nio.channels.ClosedChannelException |

留意重点信息:
1 | NotServingRegionException |
通过初步排查,发现只有一个数据表有此问题,更换其它表数据就可以正常写入,看来是和环境有关。
通过 phoenix 进行查询,发现也无法查询出数据,报错超时:
1 | java.lang.RuntimeException: org.apache.phoenix.exception.PhoenixIOException: org.apache.phoenix.exception.PhoenixIOException: Failed after attempts=36, exceptions: |

但是从这个超时异常中看不到有效的线索。
接着通过 RegionServer 查看 Region 的分布,尝试搜索日志中出现的 Region YOUR_TABLE,f,1565318245911.a70001dfe6d9320600286510318bfeb6,发现不存在,看来这个表的 Region 信息有异常。
通过搜索问题关键词,在 stackoverflow 上面找到一个例子,出现这种现象是因为这个表的 Region 损坏了,导致无法找到指定的 Region,但是可以手动修复。
问题解决
找问题原因,并且进一步得到了建议的解决方案,准备实施。
首先使用 hbase hbck"YOUR_TABLE" 检测数据表的状态,等待几十秒,会陆续打印出集群的状态以及表的状态:
1 | 2019-10-13 17:44:20,160 INFO [main-SendThread (dev5:2181)] zookeeper.ClientCnxn: Opening socket connection to server dev5/172.18.5.205:2181. Will not attempt to authenticate using SASL (unknown error) |



首先注意到前面那个不存在的 Region a70001dfe6d9320600286510318bfeb6 处于未部署状态,RegionServer 当然无法找到了。
可以看到最终的结论:INCONSISTENT,就是数据不一致。并且在输出日志里面还有说明出现了 Region 空洞【Region hole】。
那怎么解决呢,可以先尝试使用 hbase hbck -fix"YOUR_TABLE" 解决。
这里如果遇到操作 HDFS 无权限,记得切换用户 export HADOOP_USER_NAME=hbase,当然最好还是直接使用管理员权限操作:sudo -u hbase hbase hbck -fix"YOUR_TABLE"。
在修复过程中,仍旧会不断输出日志,如果看到:util.HBaseFsck: Sleeping 10000ms before re-checking after fix...
则说明修复完成,为了验证修复结果,HBase 还会自动检测一次。
再次检测后,如果看到如下信息,说明修复成功:
1 | Summary: |

接着就可以继续正常写入数据了。
备注
参考 stackoverflow 上面的例子:notservingregionexception 。

