java - 如果结果集很大,则使用 Cassandra 和 DataStax Java 驱动程序时会出现 NoHostAvailableException

标签 java timeout cassandra datastax-java-driver datastax

设置:

  • 2 节点 Cassandra 1.2.6 集群
  • 副本=2
  • 没有二级索引的非常大的 CQL3 表
  • Rowkey 是一个 UUID.randomUUID().toString()
  • 读取一致性设置为ONE
  • 使用 DataStax Java 驱动程序 1.0

请求:

尝试通过“SELECT some-col from schema.table LIMIT nnn;”进行表扫描

失败:

一旦超出某个 nnn LIMIT,我就会开始从驱动程序中获取 NoHostAvailableExceptions。

它是这样写的:

com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /10.181.13.239 ([/10.181.13.239] Unexpected exception triggered))
            at com.datastax.driver.core.exceptions.NoHostAvailableException.copy(NoHostAvailableException.java:64)
            at com.datastax.driver.core.ResultSetFuture.extractCauseFromExecutionException(ResultSetFuture.java:214)
            at com.datastax.driver.core.ResultSetFuture.getUninterruptibly(ResultSetFuture.java:169)
            at com.jpmc.es.rtm.storage.impl.EventExtract.main(EventExtract.java:36)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:601)
            at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /10.181.13.239 ([/10.181.13.239] Unexpected exception triggered))
            at com.datastax.driver.core.RequestHandler.sendRequest(RequestHandler.java:98)
            at com.datastax.driver.core.RequestHandler$1.run(RequestHandler.java:165)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

鉴于:这可能不是对具有数百万行的大表做的最明智的事情,但这是我学习不该做的事情的方式,所以我真的很感激有人可以自愿提供这种错误进行调试。

例如,当发生这种情况时,没有迹象表明集群中的节点曾经遇到过请求问题(任一节点上的日志中都没有任何超时或失败的迹象)。此外,我在驱动程序上启用了跟踪,只要查询成功,它就会为您提供一些不错的自动跟踪(ala Oracle)信息。但在这种情况下,驱动程序会抛出 NoHostAvailableException 并且没有可用的 ExecutionInfo,因此在这种情况下跟踪没有提供任何好处。

我还发现有趣的是,这似乎没有被记录为超时(我的 JMX 控制台告诉我没有发生超时)。所以,我不明白故障实际上发生在哪里。我的想法是驱动程序有问题,但我不知道如何调试它(我真的很想调试)。

我读过一些人的帖子,他们说 query'g for resultSets > 10000 rows 可能不是一个好主意,我愿意接受这一点,但我想了解是什么导致了异常以及在哪里发生异常。

FWIW,我还尝试在 cassandra.yaml 中调整超时属性,但这没有任何区别。

我欢迎任何建议、轶事、侮辱或金钱捐助,以帮助我在 moron-developers 中注册。

问候!!

最佳答案

我的猜测(也许其他人可以证实)是您通过导致超时的查询对集群施加了过高的负载。所以,是的,调试起来有点困难,因为根本原因并不明显:是我设置的限制太大了,还是集群真的宕机了?

您希望避免对单个查询中请求的数据量设置过大的限制,通常是通过设置合理的限制并对结果进行分页,例如,

SELECT * FROM messages WHERE user_id = 101 LIMIT 1000;
SELECT * FROM messages WHERE user_id = 101 AND msg_id > [Last message ID received] LIMIT 1000;

在( see this document 中添加的自动分页功能,此答案中的代码示例是从中复制的)是 datastax java-driver 的一项重大改进,因为它消除了手动分页的需要并允许您执行以下操作:

Statement stmt = new SimpleStatement("SELECT * FROM images");
stmt.setFetchSize(100);
ResultSet rs = session.execute(stmt);

// Iterate over the ResultSet here

虽然这不一定能解决您的问题,但它可以最大限度地降低查询“太大”的可能性。

关于java - 如果结果集很大,则使用 Cassandra 和 DataStax Java 驱动程序时会出现 NoHostAvailableException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19528754/

相关文章:

Hadoop 作业在 FBUtilities.java 中抛出 NullPointerException

java - 什么是以及如何获取 Twitter 和 oauth-signpost 的 pinCode?

sockets - JMeter:java.net.SocketException:连接重置

java - 通过 "reference"而不是通过内容测试 .jar 库

Python 在终止后捕获子进程输出

android - 如何检查OkHttp3请求是否超时?

php - pecl 安装 cassandra 抛出 : "error: Unable to load libcassandra"

cassandra - 更新后保持 cassandra 数据模型同步

java - 线程执行器不工作 Spring 批处理

java - Android RxJava - GroupBy 和合并回来?