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

Java Cassandra跟踪和客户端延迟之间的差异,java,cassandra,driver,cql,cqlsh,Java,Cassandra,Driver,Cql,Cqlsh,我们使用的是Cassandra 2.0.15,所有应用程序主机都会定期(大约每3分钟)出现巨大的读取延迟(>60秒)。我们通过调用session.execute(stmt)来测量延迟。同时,Cassandra跟踪报告持续时间,这是一个常见的问题,当您得到一个组件来测试自己时 您可能会遇到相关工具看不到的延迟 组件不知道请求应该在何时启动 当JVM停止时,这会阻止您看到试图测量的延迟 最有可能的解释是第二种。假设您有一个100个任务的队列,但由于系统运行缓慢,每个任务需要1秒的时间。您在内部为

我们使用的是Cassandra 2.0.15,所有应用程序主机都会定期(大约每3分钟)出现巨大的读取延迟(>60秒)。我们通过调用
session.execute(stmt)
来测量延迟。同时,Cassandra跟踪报告持续时间,这是一个常见的问题,当您得到一个组件来测试自己时

  • 您可能会遇到相关工具看不到的延迟
  • 组件不知道请求应该在何时启动
  • 当JVM停止时,这会阻止您看到试图测量的延迟
最有可能的解释是第二种。假设您有一个100个任务的队列,但由于系统运行缓慢,每个任务需要1秒的时间。您在内部为每个任务计时,它会看到它花费了1秒,但是,将100个任务添加到队列中,第一个任务在0秒后启动,但最后一个任务在99秒后启动,然后报告它花费了1秒,但从您的角度看,完成任务花费了100秒,其中99秒等待启动


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

我跟踪到了问题的根源,即远程数据中心节点上的查询超时。集群在两个DC中有节点,但密钥空间仅在本地DC中复制,因此甚至考虑删除节点也令人惊讶。我能够将延迟时间降低到

  • 从一个更改为本地\u一个一致性和
  • 从普通循环负载均衡器更改为DC感知负载均衡器(还使用延迟感知和令牌感知)

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

    您使用的是什么java驱动程序版本?您是否在监视JVM(主机端和客户端)中的垃圾收集事件?您能发布查询Cassandra的Java代码吗?我是second@JimMeyer。您可以发布可用的RAM和JVM设置吗?他们遵守了吗?我跟踪到了远程数据中心节点上超时的查询。集群在两个DC中有节点,但密钥空间仅在本地DC中复制,因此甚至考虑删除节点也令人惊讶。通过(a)将一致性从1更改为本地一致性,以及(b)将普通循环负载平衡器更改为DC感知负载平衡器(也使用延迟感知和令牌感知),我能够降低延迟。为什么驱动程序会试图联系远程主机以获取非复制的密钥空间?如果“组件”(Cassandra集群)认为它响应很快,我可以看到这种推理是适用的,但客户端却看到了其他情况。在我的例子中,我有两个不同的客户端在同一台机器上运行,并且测量它们与“组件”的交互,一个客户端得到一致的快速响应,另一个客户端看到很大的延迟。
    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()))
    }