NoNodeAvailableException:没有可用的节点执行查询。

15

我没有使用Elasticsearch,而是在使用CQL操作Cassandra数据库。我正在使用线程。在运行代码后一段时间,始终会在线程中出现异常:com.datastax.oss.driver.api.core.NoNodeAvailableException:没有可用的节点来执行查询。

我已经尝试只用一个线程进行测试,但错误仍然存在。以下是我的代码:

InetAddress addrOne = InetAddress.getByName("52.15.195.41");
InetSocketAddress addrSocOne = new InetSocketAddress(addrOne,9042);
CqlSession sessionOne = CqlSession.builder().addContactPoint(addrSocOne).withLocalDatacenter("us-east-2").withKeyspace("test").build();

while(counter <= 100)
{
    String query = "select max(id) FROM samplequeue";
    ResultSet rs = session.execute(query);
    for (Row row : rs) 
    {
        int exS = row.getInt("system.max(id)");
    }
    counter++;
    Thread.sleep(50);
}

这只是一个非常简单的修改示例,只是为了演示问题。我无法解决它。所有线程都会退出并给出相同的异常。我在AWS上运行cassandra 3.11.4。所有节点都正常运行,并且我可以在后端执行操作。


你是如何初始化session对象的? - Carlos Monroy Nieblas
@CarlosMonroyNieblas,我现在已经将代码部分添加到我的问题中了。 - SDt
William在下面提出了一个很好的观点。当您运行nodetool status时,您的数据中心名称是什么? - Aaron
3个回答

18

.withLocalDatacenter("us-east-2")更改为.withLocalDatacenter("datacenter1")并重试。


7
请问您能否解释一下为什么这个可以运行?它是一些硬编码的值吗? - Leonid Bor
我很惊讶这个方法居然奏效了,尽管我的数据中心名称与"datacenter1"不同(通过nodetool status确认)。但将其设置为"datacenter1"确实有效。在此之前,我得到的结果是不一致的,有时候可以工作,有时候则不行,但在我进行了这个操作之后,它就非常好用了。 - RyanQuey
更新:看起来这可能与机器上是否运行了使用Java驱动程序的C实例有关。我正在连接到在外部AWS上运行的C,但是在我的本地框中运行了C(特别是DSE),并且必须使用.withLocalDatacenter("datacenter1")。但是当我停止本地C实例(sudo service dse stop)然后再次尝试时,现在无法连接,并抱怨给出下一个评论中显示的错误。 - RyanQuey
You specified datacenter1 as the local DC, but some contact points ar e from a different DC: Node(endPoint=/<my-ip>:9042, hostId=<my-id>, hashCode=4a395efc)=SearchGraph; please provide the correct local DC, or check your contact points - RyanQuey

15

您可以在Cassandra中执行nodetool状态,然后您将获得数据中心的名称。这就是您必须放入withLocalDatacenter方法中的值:

/opt/apache-cassandra-3.11.2/bin$ ./nodetool status
Datacenter: **dc1**
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address         Load       Tokens       Owns (effective)  Host ID    Rack

这个解决方案对我很有效。在我的情况下,我在应用程序中使用了错误的数据中心名称DC1。但是通过使用“nodetools status”命令,我找到了正确的数据中心名称datacentre1。 - Gunjan Shah

0

在本地运行时,最好运行nodetool status命令获取数据中心名称,并在连接到Cassandra实例时在应用程序中使用。


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