昨天碰到一个问题。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. 各个节点的系统时间是否一致。