Cassandra NoHostAvailableException Java-CQLDriver

3
我正在使用Cassandra的CQL驱动程序构建一个Java应用程序。当我使用本地Cassandra服务器时,我可以正确运行它。然而,当我尝试在远程Cassandra服务器上运行相同的代码时,它就无法工作。在初始化过程中会出现以下错误:
以下是我为CQL驱动使用的Maven依赖项:
<dependency>
        <groupId>com.datastax.cassandra</groupId>
        <artifactId>cassandra-driver-core</artifactId>
        <version>2.1.3</version>
    </dependency>

    <dependency>
        <groupId>com.datastax.cassandra</groupId>
        <artifactId>cassandra-driver-mapping</artifactId>
        <version>2.1.2</version>
    </dependency>

以下是错误信息:
com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: yyyy.yyy.yyy.yyy.yyy-yyy.net/yy.yy.yy.yy:9160 (com.datastax.driver.core.ConnectionException: [yyyy.yyy.yyy.yyy.yyy-yyy.net/yy.yy.yy.yy:9160] Unexpected error during transport initialization (com.datastax.driver.core.ConnectionException: [yyyy.yyy.yyy.yyy.yyy-yyy.net/yy.yy.yy.yy:9160] Operation timed out)), 
    Unexpected error during transport initialization      (com.datastax.driver.core.ConnectionException: [xxxx.xxx.xxx.xxx.xxx-xxx.net/xx.xx.xx.xx:9160] Operation timed out)))
         at   com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:220)
    at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:78)
    at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1231)
    at com.datastax.driver.core.Cluster.init(Cluster.java:158)
    at com.datastax.driver.core.Cluster.connect(Cluster.java:246)

一切正常的本地Cassandra服务器是:

cqlsh 4.1.1, Cassandra 2.0.7 , CQL spec: 3.1.1, Thrift Protocol 19.39.0

连接超时的远程Cassandra服务器是:
cqlsh 3.1.8 | Cassandra 1.2.12 | CQL spec 3.0.0 | Thrift protocol 19.36.1

我正在使用以下代码进行连接。有人能否评论一下远程连接情况出了什么问题?
clusterOBJECT = Cluster.builder().addContactPointsWithPorts(addrs)
                .withQueryOptions(new     QueryOptions().setConsistencyLevel(ConsistencyLevel.ONE))
                .withProtocolVersion(1).withoutJMXReporting()
                .withPort(port)
                .withSocketOptions(options)
                .withRetryPolicy(DefaultRetryPolicy.INSTANCE)
                .withLoadBalancingPolicy(new TokenAwarePolicy(new DCAwareRoundRobinPolicy())).build();
        session = clusterOBJECT.connect();

我在addContactPointsWithPorts中提供了有效的主机名和端口号(9160)。此外,这些主机名是可ping通的。

注:cassandra.yaml文件中已经设置了以下属性。

start_native_transport: true
native_transport_port: 9042

[编辑] 将端口更改为9042后,我能够连接到Cassandra。但是很快我看到连接被这个异常断开了。

com.datastax.driver.core.TransportException: [/xx.xx.xxx.xx:9042] Cannot connect
    at com.datastax.driver.core.Connection.<init>(Connection.java:106)
    at com.datastax.driver.core.PooledConnection.<init>(PooledConnection.java:35)
    at com.datastax.driver.core.Connection$Factory.open(Connection.java:528)
    at com.datastax.driver.core.DynamicConnectionPool.<init>(DynamicConnectionPool.java:74)
    at com.datastax.driver.core.HostConnectionPool.newInstance(HostConnectionPool.java:33)
    at com.datastax.driver.core.SessionManager.replacePool(SessionManager.java:270)
    at com.datastax.driver.core.SessionManager.access$400(SessionManager.java:39)
    at com.datastax.driver.core.SessionManager$3.call(SessionManager.java:303)
    at com.datastax.driver.core.SessionManager$3.call(SessionManager.java:295)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
 Caused by: java.net.ConnectException: Connection refused: /xx.xx.xxx.xx:9042
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)
    at org.jboss.netty.channel.socket.nio.NioClientBoss.connect(NioClientBoss.java:150)
    at org.jboss.netty.channel.socket.nio.NioClientBoss.processSelectedKeys(NioClientBoss.java:105)
    at org.jboss.netty.channel.socket.nio.NioClientBoss.process(NioClientBoss.java:79)
    at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318)
    at org.jboss.netty.channel.socket.nio.NioClientBoss.run(NioClientBoss.java:42)
    ... 3 more

谢谢。

1
你们的网络结构是什么?客户端和服务器位于哪里?是否涉及任何内部/外部地址?你能够通过 telnet 连接这些端口吗? - Roman Tumaykin
你的 cassandra.yaml 文件中,诸如 listen_addressbroadcast_addressrpc_address 等项的值是什么?基本上,发布 cat cassandra.yaml | grep address 命令的输出结果(减去被注释掉的行)。 - Aaron
cassandra.yaml文件中的rpc_address和listen_address都为空。listen_address:rpc_address: - learner
broadcast_address被注释掉并且没有被使用。 - learner
2个回答

0

我在addContactPointsWithPorts中提供了有效的主机名和端口(9160)。此外,这些主机名是可ping通的。

在阅读您原始帖子中的这行内容并仔细检查一些文档后,我认为我知道这里发生了什么。关于Java驱动程序文档清楚地说明:

Apache Cassandra的Java驱动程序2.0仅与Cassandra查询语言版本3(CQL3)和Cassandra的新二进制协议配合使用

连接要求部分也指出:

您已在cassandra.yaml中配置了以下内容:

start_native_transport : true
rpc_address : IP address or hostname

集群中可从客户端机器访问的节点可以在9042端口上接受连接。注意:客户端端口可以使用cassandra.yaml中的native_transport_port进行配置。
换句话说,您不应该使用Thrift(9160)使用Java-CQL驱动程序连接到Cassandra。尝试不设置端口(在withPort或主机名中)。它应该自行尝试使用9042。
编辑:好的,我刚刚尝试了一下使用.addContactPoints(没有在主机名中指定端口)和.withPort(9160),它起作用了。这似乎与我之前在帖子中引用的文档相矛盾。无论如何,我仍然建议使用本机协议(9042),因为Thrift协议正在被弃用。此外,较新版本的Cassandra(2.1)和DataStax CQL驱动程序已经证明优于基于Thrift的驱动程序。

0

我认为这里的关键是“本地”和“远程”。我已经提出了问题,但没有得到答案,但我怀疑有两个问题之一:

  1. 防火墙正在阻止客户端访问端口9160和9042。您是否尝试过使用telnet命令连接到节点的9160和9042端口?

  2. 存在私有/公共地址问题,通常在集群位于私有网络内部,客户端尝试使用外部IP地址访问集群时会出现此问题。在这种情况下,集群不知道由基础架构分配的公共IP地址。在这种情况下,驱动程序需要负责进行地址转换。 例如,Java驱动程序有一个名为AddressTranslater的策略,您可以实现它来执行从内部IP到外部IP的转换-例如使用AWS API。http://www.datastax.com/drivers/java/2.0/com/datastax/driver/core/policies/AddressTranslater.html 这里是一个实现的链接(我自己没有使用过):http://docs.hazelcast.org/docs/3.3/javadoc/com/hazelcast/client/spi/impl/AwsAddressTranslator.html


嗨rtumaykin,感谢您的回复。我能够telnet到这些端口,并且使用9042端口我能够连接到cassandra。但是现在我面临的问题是,在连接几分钟后,我看到以下日志。 com.datastax.driver.core.TransportException:[/xx.xx.xxx.xx:9042]无法连接 at com.datastax.driver.core.Connection.<init>(Connection.java:106) at com.datastax.driver.core.PooledConnection.<init>(PooledConnection.java:35)然而,我仍然能够使用cassandra,但是这些日志存在。有关详细日志,请参见我对问题的编辑。 - learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接