datastax会话因大量并行查询而挂起

时间:2018-11-16 20:13:17

标签: scala cassandra datastax

大图片。

并行处理2000个查询时,datastax会话挂起。

并行查询

我正在使用Alpakka,它包装了Datastax Cassandra驱动程序。我正在使用Scala Play框架。

要对大数据进行行计数,必须按分区进行。我使用以下代码对每个分区的行进行计数:

val futureList: ListBuffer[Future[Any]] = new ListBuffer[Future[Any]]
  val acc: mutable.HashMap[String, Long] = new mutable.HashMap[String, Long]()
  targets.isDefined match {
    case true =>
      targets.get.foreach {
        e =>
          val cq: CassandraQueries = new CassandraQueries()
          Logger.info("targets collected so far: "+acc.size)
          Logger.info("Calling count for "+e._1)


          futureList += cq.futureQuery("SELECT count(*) FROM " + keyspaceName + ".\"sparseData\" where label = " + e._2 + ";", sparseRowCountResult(acc, e._1), 120000)
      }

      val results = Future.sequence(futureList.toList)

在我的一个键空间中,我有2000个分区,因此有2000个并行查询。

查询结果

查询由Alpakka / Datastax处理,并返回Future[Seq[Row]].

Logger.info("furtureQuery: session closed -> "+ session.isClosed)
    val stmt = new SimpleStatement(query).setFetchSize(200).setReadTimeoutMillis(readTimeoutMillis)
    val sb: StringBuilder = new StringBuilder()
    val source = CassandraSource(stmt)
    source.runWith(Sink.seq).onComplete {
      case Success(f) => out(Some(f), None)

      case Failure(e) =>
        Logger.error("simpleQuery failed with " + e.getMessage)
        out(None, Some(e.getMessage))

    }

异常并挂起 经过大约1000次查询后,出现以下错误。此后,会话无任何结果。 SuccessFailure都不会出现。

  

akka.ConfigurationException:无法在config中指定记录器   已加载[akka.event.Logging $ DefaultLogger],原因是   [akka.event.Logging $ LoggerInitializationException:记录器   log1-Logging $ DefaultLogger没有响应LoggerInitialized,   改为发送[TIMEOUT]

问题

我确定我可以延长日志记录的超时时间。但这是一种症状,而不是真正的问题。

我该怎么做:

  • 配置会话连接以允许2000个并行请求吗?

  • 将Future.sequence约束为已知数量的可能请求吗?

  • 如何以编程方式从这样的Sessiion挂机中恢复?

2 个答案:

答案 0 :(得分:1)

在创建群集实例时,可以通过指定池选项来增加每个连接的运行中请求数量,如下所示:

PoolingOptions poolingOptions = new PoolingOptions();
poolingOptions.setMaxRequestsPerConnection(HostDistance.LOCAL, 10240);

Cluster cluster = Cluster.builder()
    .withContactPoints("127.0.0.1")
    .withPoolingOptions(poolingOptions)
    .build();

但是您仍然需要在代码中处理BusyPoolException,因为使用异步请求时,仍然很容易使一个特定的连接过载。

更多信息在driver's documentation中。

答案 1 :(得分:1)

触发2000个查询将执行范围查询。利用群集对象元数据,获取令牌范围并计算密钥的令牌。然后,在一个范围查询中对属于同一范围的查询进行批处理。