无法运行自定义聚合OperationTimedOut:errors = {},last_host = 127.0.0.1

时间:2015-09-14 14:38:05

标签: scala stored-procedures cassandra cql spark-cassandra-connector

我正在运行apache-cassandra-2.2.1,enable_user_defined_functions设置为true cassandra.yml。我已根据this article定义了一个自定义聚合,如下所示:

CREATE FUNCTION sumFunc(current double, candidate double) CALLED ON NULL INPUT RETURNS double LANGUAGE java AS 'if(current == null) return candidate; return current + candidate;'
CREATE AGGREGATE sum(double) SFUNC sumFunc STYPE double INITCOND null;

当我从CQLSH控制台调用它时,我看到超时:

cqlsh:test> SELECT word, sum(frequency) FROM words;
OperationTimedOut: errors={}, last_host=127.0.0.1

我可以成功运行任何其他查询,我也可以从scala运行查询(但我没有得到完整的结果集):

CassandraConnector(conf).withSessionDo { session =>
  val result: ResultSet = session.execute("SELECT word, SUM(frequency) FROM test.words;")
  while(result.isExhausted == false) {
    println(result.one)
  }
}

1 个答案:

答案 0 :(得分:1)

首先,您的查询可能无法达到您的预期,因为它不会按表格中的每个单词进行分组。您将得到表中所有频率的总和。要获得单词的频率总和,您需要执行此操作:

SELECT word, sum(frequency) FROM words WHERE word='someword';

其次,我在尝试聚合超过300,000行的大型分区时看到了超时错误(请参阅this)。因此,在超时错误开始之前,你的单词表太大而无法聚合。我希望Cassandra不会在正在取得进展的查询上超时,但它似乎有一些硬编码的超时会中止任务,无论是否他们正在进步或实际上被卡住了。

由于您的查询没有WHERE子句,因此您尝试聚合整个表而不是单个分区。这将导致超时错误的可能性更大,因为聚合将发生在多个节点而不是单个节点上的数据上,因此您应该尝试将聚合限制为单个分区。

我认为INITCOND你想要使用0而不是null。

聚合的名称可能与内置系统和函数冲突,因此您可能希望选择其他名称。但是,看起来你可以使用内置的sum函数而不是定义一个(Cassandra 2.2有sum(),avg(),min()和max())的未记录的内置函数。