有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Cassandra跟踪和客户端延迟之间的java差异

我们在Cassandra 2.0.15上,所有应用程序主机都会定期(大约每3分钟)出现巨大的读取延迟(>;60秒)。我们通过调用session.execute(stmt)来测量这种延迟。同时,卡桑德拉追踪了<;1s。我们还在一个循环中通过cqlsh从相同的主机在这些峰值延迟时间运行查询,cqlsh总是在1s内返回。在Java驱动程序级别,什么可以解释这种差异

--编辑:回复评论--

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

Client side GC is negligible

客户端测量代码:

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秒。绿色线程的低延迟(1s以下)比黄色线程频繁得多

enter image description here


共 (2) 个答案

  1. # 1 楼答案

    当你让一个组件测试自己时,这是一个常见的问题

    • 您可能会遇到相关工具看不到的延迟
    • 组件不知道请求应该在何时启动
    • 当JVM停止时,这会阻止您看到试图测量的延迟

    最有可能的解释是第二种。假设您有一个100个任务的队列,但由于系统运行缓慢,每个任务需要1秒的时间。您在内部为每个任务计时,它会看到它花费了1秒,但是将100个任务添加到队列中,第一个任务在0秒后启动,但最后一个任务在99秒后启动,然后报告它花费了1秒,但从您的角度来看,完成任务需要100秒,其中99秒等待启动

    结果到达您的过程中也可能会出现延迟,但这种情况不太可能发生,除非您在处理结果时所做的操作超过了数据库所需的时间。i、 e.你可能认为瓶颈在服务器上

  2. # 2 楼答案

    我追踪到了远程数据中心节点超时的查询。集群在两个DC中有节点,但密钥空间仅在本地DC中复制,因此甚至考虑删除节点,这是令人惊讶的。我把延迟时间缩短了

    1. 从一个变为一个一致性和
    2. 从普通循环负载均衡器更改为DC感知负载均衡器(还使用延迟感知和令牌感知)

    在我看来,它仍然像Java驱动程序中的一个bug,它试图使用远程数据中心的节点作为协调节点,而该数据中心中显然不存在密钥空间。此外,即使这在某种程度上是不可能的,我也在使用延迟感知策略,该策略应该将远程DC节点排除在考虑范围之外