当前位置: 首页 > 知识库问答 >
问题:

如何解决cassandra写超时异常?

狄令
2023-03-14

我正在尝试将50000条记录插入到一个五节点的卡桑德拉集群中。我正在使用执行异步以提高性能(减少应用程序端的插入时间)。我尝试了具有多个批处理大小的批处理语句,但每次我都遇到以下异常。

Exception in thread "main" com.datastax.driver.core.exceptions.WriteTimeoutException: Cassandra timeout during write query at consistency ONE (1 replica were required but only 0 acknowledged the write)
at com.datastax.driver.core.exceptions.WriteTimeoutException.copy(WriteTimeoutException.java:54)
at com.datastax.driver.core.DefaultResultSetFuture.extractCauseFromExecutionException(DefaultResultSetFuture.java:259)
at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:175)
at 

我插入了数据,即10000,20000到40000条记录,没有任何问题。以下是我编写的java代码。

for (batchNumber = 1; batchNumber <= batches; batchNumber++) {
    BatchStatement batch = new BatchStatement();
    for (record = 1; record <= batchSize; record++) {
        batch.add(ps.bind(query));
    }
    futures.add(session.executeAsync(batch));           
}
for (ResultSetFuture future : futures) {
    resultSet = future.getUninterruptibly();
}

其中ps是准备好的语句,batches是批数,batchSize是批中的记录数。

我无法理解这个问题的根本原因。我认为一些节点是关闭的,当我检查时,所有节点都运行正常。

我应该如何调试异常?

共有2个答案

夏侯元忠
2023-03-14

这不是巴奇的用途。当您向批处理中添加多个语句时,Cassandra 将尝试以原子方式应用它们。它们要么全部成功,要么都不成功,并且它们都必须在单个查询超时内完成。

此外,如果您发出的请求多于同时处理的请求,它们将进入队列,而队列中的等待时间会导致超时。

要在不超时的情况下完成所有操作,请使用单个语句并限制任何时间的飞行数量。或者,使用 COPY 命令从 CSV 加载数据。

吴炎彬
2023-03-14

我看到一些错误:

  1. 似乎您正在尝试弄清楚可以批量处理的最大查询数是多少。
  2. 您似乎认为批处理多个语句会给您带来某种性能提升。
  3. 您在循环中错误地重用了相同的预准备语句。
  4. 您没有以某种摄入率限制您的应用程序。
  5. 您没有执行任何异常处理,例如在某些批处理失败时重试。

让我们重新开始。

  1. 批处理中的最大语句数应小于 10。越小越好。顺便说一句,批处理的总大小必须小于 YAML 配置文件中的任何值。通常,如果您的批次大于5kb,则日志中会出现警告。如果批处理大于 50kb,则批处理将失败。您可以调整这些值,但应记住,BATCH 会重载协调器节点。批处理越大(以 kb 或语句数表示),协调器上的过载就越大。
  2. 将不相关的语句批处理在一起不会带来任何好处。相反,您实际上会失去性能。这是由于批处理的工作方式。选择一个节点来协调所有语句,该节点将负责所有语句。通常,协调器是根据第一个语句选择的,如果您的语句命中多个节点,则协调器也需要协调属于不同节点的事物。相反,如果您要触发多个单独的异步查询,则每个节点将仅对其语句负责。您将在所有群集节点上分散过载,而不是在一个节点上锤击。
  3. 您正在以错误的方式使用预准备语句。您应该添加一个新的绑定语句。无论如何,这都是一个简单的解决方案。
  4. 如果要运行大量查询,则会一直运行这些查询。您将耗尽应用程序内存,因为它将继续向列表中添加未来的s,并且最终会因为OOM错误而被杀死。此外,您没有让集群能够实际引入您向其发送的所有数据,因为您可以比集群引入更快地触发数据。您需要做的是限制列表中的期货数量。最多将其保持在某个值(例如,例如1000)。要执行此类任务,您需要在循环内使用 .getUn不间断地移动最后一个循环。这样,可以降低引入速率,并看到超时异常计数减少。根据应用程序的不同,减少超时异常意味着更少的重试,从而减少查询,减少开销,缩短响应时间等...
  5. 在“未来”的列表中有一个带有 .getUninter 的循环是可以的,但是您应该记住的是,当您的集群过载时,您将获得超时。此时,您应该捕获异常并对其进行处理,无论是重试,还是重新抛出,还是其他任何内容。我建议你围绕幂等查询设计模型,这样我就可以重试失败的查询,直到它们成功为止,而不必担心重试后果(这也可能发生在驱动程序级别!

希望有帮助。

 类似资料:
  • 我使用将整个代码库从更改为 由于节俭,我从一开始就经常超时,我无法继续...采用CQL,按照我成功设计的表格和更少的超时.... 有了这个,我能够插入大量不符合节俭原则的数据…但是经过一个阶段,数据文件夹大约在3.5GB左右。我经常遇到写入超时异常。即使我再次做同样的早期工作用例,现在也会引发超时异常。它的随机曾经工作过,即使在重新设置后也无法再次工作。 CASSADNRA服务器日志 这是卡桑德拉

  • 我已经使用弹性Beanstalk在EC2实例中部署了springboot java jar。jar中的api在将用户添加到DB后会发送一个确认邮件。这个功能在localhost中运行良好,但是在aws实例上,我得到了gatway超时504。 这里是SMTP服务器的设置(它是不使用用户名、密码的smart服务器,并且我在服务器中添加了我的EC2公司的公共ip地址)Java SMTP设置: java.

  • 我有cassandra单片应用程序,我想写在高速率从队列中读取一些有效载荷。Cassandra集群有3个节点。当我开始并行处理大量消息(通过生成线程)时,我得到以下异常 我将CQLsession创建为bean 我将此CqlSession注入到映射器和其他类中以运行查询 在我的datastax驱动程序中,我给了3个节点的ip作为联系点,我是否需要在CQLsession创建/或我的cassandra节

  • 我正在尝试运行一个简单的play-scala示例,但是我在启动activator时遇到了一些问题,因为我有很多连接超时。我只使用activator创建了应用程序并尝试启动它。没有开发或自定义配置。我用的是Play2.4.2。 它试图解决的许多依赖项似乎并不存在:如果我试图在浏览器中打开url,我只得到“请求路径未找到”。例子如下: 这种行为浪费了很多时间,没有任何价值。是否可以避免不存在的路径或最

  • 我正在使用for循环来处理表元素。在第一次迭代中,它将在页面上搜索所需的元素。如果该元素在该页面上不可用,那么它将在第二个页面上搜索。如果元素在第一个页面上可用,Webdriver会成功地找到该元素,但如果元素在第一个页面上不可用,则它会在第二个页面上查找该元素。但在这里,for循环失败,出现称为“stale Element exception”的异常。 错误消息: 线程“main”org.ope

  • 我正在迁移一个带有MySQL数据库的Java应用程序。现在连接会在某个时候超时,尽管使用相同参数的同一个连接在以前的几个事务中工作得很好。代码如下: 公共类DBConnection{ } 和我的日志: null 2016-06-21 15:53:31,436警告[com.arjuna.ats.arjuna](Transaction Reaper Worker 0)arjuna012108:Chec