有一个HBase集群让我很困惑的非常简单的Java代码段:
Configuration my_conf = HBaseConfiguration.create();
my_conf.set("hbase.zookeeper.quorum", "192.168.0.100,192.168.0.101,192.168.0.102");
my_conf.set("hbase.zookeeper.property.clientPort", 2181);
my_conf.set("zookeeper.znode.parent", "/my-root-node");
try
{
Connection conn = ConnectionFactory.createConnection(my_conf);
Table my_table = conn.getTable(TableName.valueOf("mytable"));
long id = my_table.incrementColumnValue(Bytes.toBytes("my.row"), Bytes.toBytes("key"), Bytes.toBytes("auto"), 1, Durability.SKIP_WAL);
}
catch(IOException ex)
{
System.out.println(ex.toString());
}
事实是:如果直接在服务器端(该子网中的任何计算机)上启动,则此代码可以正常运行。
如果从任何外部计算机(如我的PC)启动,或从其他子网的服务器启动,则代码将挂起incrementColumnValue()
调用。
根据日志,我可以看到HBase进入incrementColumnValue()
调用,然后创建并启动RegionServerCallable
实例,然后等待它完成并挂起,直到检测到超时(无论长度如何)的超时时间,我将其更改为12小时,效果相同)。
超时异常包含以下消息:
callTimeout = 1200000,callDuration = 2214143:表上的行'my.row' “ mytable”为空
消息末尾的null
应该是区域名称,但是HBase似乎很难发现区域。
我不知道为什么如果从内部网络启动RPC呼叫就可以得到服务,而如果是从外部场所发起的内部子调用在内部则失败。任何帮助表示赞赏。