java如何解决cassandra中的写入超时异常?
我正试图将50000条记录插入一个五节点的cassandra集群。我正在使用executeAsync来提高性能(减少应用程序端的插入时间)。我尝试了Batchstatement,但每次都出现以下异常
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
我插入了数据,即1000020000到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是准备好的语句,batch是批次数,batchSize是批次中的记录数
我无法理解问题的根本原因。我以为有些节点坏了,当我检查时,所有节点都正常运行
我应该如何调试异常
# 1 楼答案
我看到了一些错误:
让我们重新开始
BATCH
会重载协调器节点。批处理越大(以kb或语句数表示),协调器上的过载就越大李>BATCH
的工作方式。选择一个节点来协调所有语句,该节点将负责所有语句。通常,协调器是根据第一条语句选择的,如果语句涉及多个节点,那么协调器也需要协调属于不同节点的内容。相反,如果启动多个独立的异步查询,每个节点将只负责它们的语句。您将在所有集群节点上传播重载,而不是在一个节点上敲打李>new BoundStatement(ps).bind(xxxx)
语句。无论如何,这是一个简单的解决办法李>future
,并且最终将因为OOM错误而被杀死。此外,你没有给你的集群提供一种可能性,让它能够真正地接收你向它发射的所有数据,因为你发射数据的速度比你的集群接收数据的速度要快得多。你需要做的是限制列表中期货的数量。将其保持在某个最大值(如1000)。要执行这样的任务,你需要在循环中移动.getUninterruptibly
。通过这种方式,可以降低摄入率,并减少超时异常计数。根据应用程序的不同,超时异常的减少意味着重试次数更少,因此查询更少,开销更少,响应时间更长等等李>Future
的列表中有一个.getUninterruptibly
的循环是可以的,但是当集群 超载时,你将超时。此时,您应该捕获异常并处理它,无论是重试,还是重新抛出,无论是什么。我建议您围绕幂等查询设计模型,这样我就可以重试失败的查询,直到它们成功,而不必担心重试结果(这也可能发生在驱动程序级别!)李>希望有帮助