为啥新添加的 HBase 区域服务器无法获取分配的区域?

Posted

技术标签:

【中文标题】为啥新添加的 HBase 区域服务器无法获取分配的区域?【英文标题】:Why can't a new-added HBase region server get regions assigned to?为什么新添加的 HBase 区域服务器无法获取分配的区域? 【发布时间】:2018-05-11 07:26:26 【问题描述】:

当我向 HBase 集群添加一个新的区域服务器时,没有为这个新的区域服务器分配任何区域。

新的区域服务器现在出现在 Web UI 上,但它的 Num.根据web UI,区域和每秒请求数均为零。

这是region server log,这是master log。

似乎区域服务器添加成功,但重新平衡机制不起作用。

如何在所有区域服务器上重新平衡区域?

这是我第一次在这里提问,希望有人能帮忙,非常感谢。

【问题讨论】:

【参考方案1】:

转到 HBase shell 并运行命令 balancer。这将运行平衡器一次。它返回 true(成功)或 false(有问题)。如果您遇到问题,请检查是否处于过渡阶段。

Balancer 可以定期运行,在 HBase shell 中使用balance_switch

【讨论】:

非常感谢您的回答。我找到了原因,是因为平衡器无法正常运行,您给我灵感。谢谢!【参考方案2】:

我找到了这个现象的原因。部分区域的分裂过程出现了问题,一直在过渡中,从未完成分裂过程,导致平衡器无法正常运行。

查看 HMster.java 的平衡器代码片段:

public boolean balance() throws IOException 
  //...
  if (this.assignmentManager.getRegionStates().isRegionsInTransition()) 
    Map<String, RegionState> regionsInTransition =
      this.assignmentManager.getRegionStates().getRegionsInTransition();
    LOG.debug("Not running balancer because " + regionsInTransition.size() +
      " region(s) in transition: " + org.apache.commons.lang.StringUtils.
        abbreviate(regionsInTransition.toString(), 256));
    return false;
  
  //...

“if”语句始终为 true,因此该方法始终返回 false,并且不会运行下面实际平衡区域服务器集群的代码。

我不知道是什么导致了某些区域的拆分失败,但是当我尝试将一个区域从一个区域服务器移动到另一个区域时,我在区域服务器中发现了错误消息:

2018-05-17 13:11:12,695 ERROR         [B.defaultRpcServer.handler=99,queue=9,port=26020] regionserver.RSRpcServices: Failed warming up region tsdb,\x00\x12\x19Z\xD2P,1525840795373.c3ebb018b9c3fc101a7b9def9100fb5f.
java.io.IOException: java.io.IOException: java.io.FileNotFoundException: File does not exist: /hbase-holmes/data/default/tsdb/32ef153360b7a9499e555a7937418ee7/t/a6cdb25689234e539ed82230ed7b790f
    at org.apache.hadoop.hdfs.server.namenode.INodeFile.valueOf(INodeFile.java:71)
    at org.apache.hadoop.hdfs.server.namenode.INodeFile.valueOf(INodeFile.java:61)
    at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getBlockLocationsInt(FSNamesystem.java:1828)
    at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getBlockLocations(FSNamesystem.java:1799)
    at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getBlockLocations(FSNamesystem.java:1712)
    at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.getBlockLocations(NameNodeRpcServer.java:588)
    at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.getBlockLocations(ClientNamenodeProtocolServerSideTranslatorPB.java:365)
    at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
    at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:616)
    at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:982)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2049)
    at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2045)
    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:1698)
    at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2043)

    at org.apache.hadoop.hbase.regionserver.HRegion.initializeStores(HRegion.java:943)
    at org.apache.hadoop.hbase.regionserver.HRegion.initializeWarmup(HRegion.java:967)
    at org.apache.hadoop.hbase.regionserver.HRegion.warmupHRegion(HRegion.java:6554)
    at org.apache.hadoop.hbase.regionserver.RSRpcServices.warmupRegion(RSRpcServices.java:1709)
    at org.apache.hadoop.hbase.protobuf.generated.AdminProtos$AdminService$2.callBlockingMethod(AdminProtos.java:22241)
    at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2188)
    at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:112)
    at org.apache.hadoop.hbase.ipc.RpcExecutor.consumerLoop(RpcExecutor.java:133)
    at org.apache.hadoop.hbase.ipc.RpcExecutor$1.run(RpcExecutor.java:108)
    at java.lang.Thread.run(Thread.java:745)
...

我想要移动的区域是c3ebb018b9c3fc101a7b9def9100fb5f但是错误说出了什么找不到的文件中的文件32EF153360b7a937418ee7,后来我发现该区域C3EBB018B9C3FC101A7B9DEF9100FB5F是区域32EF153360B7A9499E555A7937418EE7。

然后我检查了hdfs,我发现父区域丢失了,并且它的子区域中指向父母存储文件的参考文件存在。也就是说,子区域中的参考文件指向了一些不存在的文件。

因此,区域服务器在子区域中找到了参考文件,但找不到父区域,然后抛出此异常。

最后,我删除了分割区域的参考文件,平衡器开始正常工作。但我不知道是否有一些数据丢失。

【讨论】:

以上是关于为啥新添加的 HBase 区域服务器无法获取分配的区域?的主要内容,如果未能解决你的问题,请参考以下文章

了解 hbase 如何使用 hdfs

HBase Java 客户端无法访问远程 HBase 区域服务器

按表重新平衡 hbase 区域

为啥我的模块无法处理内核分页请求?

为啥客户端无法获取虚拟机DHCP服务器分配的IP地址

无法启动 HBase 主机:加载的协处理器是:[]