【发布时间】:2015-12-15 21:11:09
【问题描述】:
我们正在使用 Cassandra 2.0.15,并且看到所有应用程序主机定期(大约每 3 分钟)出现巨大的读取延迟(>60 秒)。我们在调用session.execute(stmt) 时测量此延迟。同时,Cassandra 跟踪报告持续时间
--编辑:回复cmets--
Cassandra 服务器 JVM 设置:-XX:+CMSClassUnloadingEnabled -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -XX:+HeapDumpOnOutOfMemoryError -Xss256k -XX:StringTableSize=1000003 -Xms32G -Xmx32G -XX:+UseG1GC -Djava.net.preferIPv4Stack=true -Dcassandra.jmx.local.port=7199 -XX:+DisableExplicitGC。
客户端 GC 可以忽略不计(如下)。客户端设置:-Xss256k -Xms4G -Xmx4G,Cassandra驱动版本为2.1.7.1
客户端测量代码:
val selectServiceNames = session.prepare(QueryBuilder.select("service_name").from("service_names"))
override def run(): Unit = {
val start = System.currentTimeMillis()
try {
val resultSet = session.execute(selectServiceNames.bind())
val serviceNames = resultSet.all()
val elapsed = System.currentTimeMillis() - start
latency.add(elapsed) // emits metric to statsd
if (elapsed > 10000) {
log.info("Canary2 sensed high Cassandra latency: " + elapsed + "ms")
}
} catch {
case e: Throwable =>
log.error(e, "Canary2 select failed")
} finally {
Thread.sleep(100)
schedule()
}
}
集群构建代码:
def createClusterBuilder(): Cluster.Builder = {
val builder = Cluster.builder()
val contactPoints = parseContactPoints()
val defaultPort = findConnectPort(contactPoints)
builder.addContactPointsWithPorts(contactPoints)
builder.withPort(defaultPort) // This ends up config.protocolOptions.port
if (cassandraUsername.isDefined && cassandraPassword.isDefined)
builder.withCredentials(cassandraUsername(), cassandraPassword())
builder.withRetryPolicy(ZipkinRetryPolicy.INSTANCE)
builder.withLoadBalancingPolicy(new TokenAwarePolicy(new LatencyAwarePolicy.Builder(new RoundRobinPolicy()).build()))
}
还有一个我无法解释的观察结果。我在一个循环中运行了两个以相同方式(如上)执行相同查询的线程,唯一的区别是黄色线程在查询之间休眠 100 毫秒,而绿色线程在查询之间休眠 60 秒。绿色线程比黄色线程更频繁地达到低延迟(低于 1 秒)。
【问题讨论】:
-
你用的是什么java驱动版本?
-
您是否正在监视 JVM(主机端和客户端)中的垃圾收集事件?
-
你能发布你查询 Cassandra 的 Java 代码吗?
-
我第二个@JimMeyer。您可以发布您的可用 RAM 和 JVM 设置吗?他们是否关注best practices as outlined by Datastax?
-
我将问题追踪到远程数据中心的节点上的查询超时。集群在两个 DC 中有节点,但 keyspace 仅在本地 DC 内复制,因此甚至考虑删除节点是令人惊讶的。我能够通过 (a) 从 ONE 更改为 LOCAL_ONE 一致性和 (b) 从普通的循环负载均衡器更改为 DC 感知的(也使用延迟感知和令牌感知)来降低延迟。为什么驱动程序会尝试联系远程主机以获得非复制的密钥空间?
标签: java cassandra driver cql cqlsh