当试图几千条记录一次插入到远程卡桑德拉分贝,我重复地遇到超时(5〜6千的元素连接速度慢)与NoHostAvailableException处理幻象DSL
错误:
All host(s) tried for query failed (tried: /...:9042
(com.datastax.driver.core.exceptions.OperationTimedOutException: [/...]
Timed out waiting for server response))
com.datastax.driver.core.exceptions.NoHostAvailableException:
All host(s) tried for query failed (tried: /...:9042
(com.datastax.driver.core.exceptions.OperationTimedOutException: [/...]
Timed out waiting for server response))
模型:
class RecordModel extends CassandraTable[ConcreteRecordModel, Record] {
object id extends StringColumn(this) with PartitionKey[String]
...
abstract class ConcreteRecordModel extends RecordModel
with RootConnector with ResultSetFutureHelper {
def store(rec: Record): Future[ResultSet] =
insert.value(_.id, rec.id).value(...).future()
def store(recs: List[Record]): Future[List[ResultSet]] = Future.traverse(recs)(store)
连接器:
val connector = ContactPoints(hosts).withClusterBuilder(
_.withCredentials(
config.getString("username"),
config.getString("password")
).withPoolingOptions(
new PoolingOptions().setCoreConnectionsPerHost(HostDistance.LOCAL, 4)
.setMaxConnectionsPerHost(HostDistance.LOCAL, 10)
.setCoreConnectionsPerHost(HostDistance.REMOTE, 2)
.setMaxConnectionsPerHost(HostDistance.REMOTE, 4)
.setMaxRequestsPerConnection(HostDistance.LOCAL, 32768)
.setMaxRequestsPerConnection(HostDistance.REMOTE, 2000)
.setPoolTimeoutMillis(10000)
)
).keySpace(keyspace)
我已经尝试调整池选项,分开和一起。但是,即使加倍所有的REMOTE
设置并没有改变超时明显
目前的解决方法,这是我想避免 - 分裂清单分成批次,等待每完成:
def store(recs: List[Record]): Future[List[ResultSet]] = {
val rs: Iterator[List[ResultSet]] = recs.grouped(1000) map { slice =>
Await.result(Future.traverse(slice)(store), 100 seconds)
}
Future.successful(rs.to[List].flatten)
}
会是什么处理这个问题的好方法?
谢谢
编辑
的错误确实表明未能/超载集群,但我怀疑这里的网络发挥了重要作用。上面提供的数字来自远程机器。当同一个数据中心的机器提供相同的C *时,它们要高得多。另一个可疑的细节是,用quill喂养相同的C *实例不会遇到任何超时问题,远程或不远。
我真的不喜欢节流的是批量大小是随机的和静态的,而它们应该是适应性的。
IIUC你建议的方式去增加更多的机器?这可以完成,但我仍然想知道接受请求的数量很少。在上面添加了一些细节,也许你有一个想法。你可以分享一些合理的重试策略的细节吗?什么是集群恢复的合理时间。已经尝试过增加超时退出,但有时甚至在30秒后重试似乎要早。 – kostja
使用羽毛笔时,您是否执行相同的查询?这些例外情况肯定发生在超时客户端,但是由于集群花费太长时间来响应结果。你在服务器的日志中看到很多GC吗?如果群集没有出现CPU/IO明显负载的情况,那么您也可以增加客户端的读取超时 http://docs.datastax.com/en/drivers/java/2.1/com/datastax/驱动器/核心/ SocketOptions.html#setReadTimeoutMillis,内部 - – Kurt