HBase客户端host末配置引起的一个错误

昨天碰到一个问题。hbase数据在执行put的时候,程序挂死。 特记录一下。
问题描述:
程序往hbase中插入数据,发现在其中一台机器上面执行的时候,程序总是是挂死。
使用jstack查看时候:

"main" prio=10 tid=0x00007f844800a000 nid=0x3c52 waiting on condition [0x00007f844c6ee000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithRetries(RpcRetryingCaller.java:150)
    - locked <0x00000000af7e6b48> (a org.apache.hadoop.hbase.client.RpcRetryingCaller)
    at org.apache.hadoop.hbase.client.HTable.getRowOrBefore(HTable.java:752)
    at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:146)
    at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.prefetchRegionCache(HConnectionManager.java:1261)
    at 
    ... ... 

而hbase、zookeeper也全部是正常的。查看此进程的连接:

[lch@hadoop247 ~]$ netstat -anp | grep 15441
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 ::ffff:192.168.0.247:34294  ::ffff:**192.168.0.222:2181**   ESTABLISHED 15441/java          
unix  2      [ ACC ]     STREAM     LISTENING     170567 15441/java          /tmp/.java_pid15441.tmp
unix  2      [ ]         STREAM     CONNECTED     169961 15441/java          
[lch@hadoop247 ~]$ 

发现它只与zookeeper有连接。 初步怀疑是zookeeper的防火墙。结果查看一下防火墙也正常的,在zookeeper上面抓包。
这里写图片描述

抓包信息也全部正常的。
查看源码:

  public synchronized T callWithRetries(RetryingCallable<T> callable, int callTimeout)
  throws IOException, RuntimeException {
    ... ... 
    ```for (int tries = 0;; tries++) {```
      long expectedSleep = 0;
      try {
        beforeCall();
        callable.prepare(tries != 0); // if called with false, check table status on ZK
        return callable.call();
      } catch (Throwable t) {
         ... ... 
        }
      } finally {
        afterCall();
      }
      try {
        Thread.sleep(expectedSleep);
      } catch (InterruptedException e) {
        throw new InterruptedIOException("Interrupted after " + tries + " tries on " + retries);
      }
    }
  }

程序挂死的地方找到了,正是因为它

for (int tries = 0;; tries++)

注意中间是没有判断的,如果出现异常的时候,程序就不会return,而是直接进入死循环了。
出错的地方找到了。 肯定是系统出现了异常,直接在catch后面加一行日志代码。很快就找到了原因。
原因很简单:/etc/hosts没有配置中,客户端需要连hadoop240这个节点,而它又找不到hadoop240的IP,就不断的抛出异常。最后导致进行死循环。
吐槽一下:死循环了,也没有个日志。 如果是我写出这种中间不加判断的循环代码,估计直接被老大拍死了。

结论:
hbase与hadoop的问题,一定要先看两点:
1. /etc/hosts有没有配置, 配置是否正确
2. 各个节点的系统时间是否一致。

你可能感兴趣的:(hbase)