Cassandra:带有地图结果的 UDF 在 Java 中获取 CodecNotFoundException
Posted
技术标签:
【中文标题】Cassandra:带有地图结果的 UDF 在 Java 中获取 CodecNotFoundException【英文标题】:Cassandra: UDF with map result gets CodecNotFoundException in Java 【发布时间】:2016-11-01 22:39:14 【问题描述】:使用自定义聚合函数执行查询时,有时会在 Java 驱动程序中遇到 com.datastax.driver.core.exceptions.CodecNotFoundException 异常。
聚合函数的结果是一个map。我希望 Java API 会有一个用于标准类型映射的编解码器。
cqlsh 也报错“Failed to format value OrderedMapSerializedKey”,但是以 JSON 格式显示数据。
最终的功能是:
CREATE OR REPLACE FUNCTION average_by_source_final_1( state avg_type_1)
CALLED ON NULL INPUT
RETURNS map<text,double>
LANGUAGE java
...
聚合为:
CREATE OR REPLACE AGGREGATE avg_by_source( text, double)
SFUNC average_by_source_1
STYPE avg_type_1
FINALFUNC average_by_source_final_1
INITCOND ((null, 0, 0.0), null)
;
我假设最终函数的返回类型需要编解码器,而不是 STYPE。
Java 的异常:
execution of 'average_by_source_1[avg_type_1, text, double]' failed: com.datastax.driver.core.exceptions.CodecNotFoundException
... com.datastax.driver.core.exceptions.FunctionExecutionException: execution of 'roger_ts_08.average_by_source_1[avg_type_1, text, double]' failed: com.datasta
x.driver.core.exceptions.CodecNotFoundException
at com.datastax.driver.core.exceptions.FunctionExecutionException.copy(FunctionExecutionException.java:58)
at com.datastax.driver.core.DriverThrowables.propagateCause(DriverThrowables.java:37)
at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:245)
at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:64)
at com.brocade.tspoc.CassandraDb.aggregateWithAggrFunc(CassandraDb.java:309)
at com.brocade.tspoc.Main.aggregateWithAggrFuncTest(Main.java:223)
at com.brocade.tspoc.Main.main(Main.java:42)
Caused by: com.datastax.driver.core.exceptions.FunctionExecutionException: execution of 'average_by_source_1[avg_type_1, text, double]' failed: com.datastax.driver.core.exceptions.CodecNotFoundException
at com.datastax.driver.core.Responses$Error.asException(Responses.java:130)
at com.datastax.driver.core.DefaultResultSetFuture.onSet(DefaultResultSetFuture.java:179)
at com.datastax.driver.core.RequestHandler.setFinalResult(RequestHandler.java:174)
at com.datastax.driver.core.RequestHandler.access$2600(RequestHandler.java:43)
at com.datastax.driver.core.RequestHandler$SpeculativeExecution.setFinalResult(RequestHandler.java:793)
at com.datastax.driver.core.RequestHandler$SpeculativeExecution.onSet(RequestHandler.java:627)
at com.datastax.driver.core.Connection$Dispatcher.channelRead0(Connection.java:1012)
在 cqlsh 中:
avg_by_source(source, value)
----------------------------------------------------------------------------------------------------
OrderedMapSerializedKey([(u'i1', 23.5), (u'i2', 1.2), (u's1', 50.0), (u's2', 15.0), (u's3', 8.0)])
(1 rows)
Failed to format value OrderedMapSerializedKey([(u'i1', 23.5), (u'i2', 1.2), (u's1', 50.0), (u's2', 15.0), (u's3', 8.0)]) : 'NoneType' object has no attribute 'sub_types'
【问题讨论】:
cqlsh 部分似乎是由最近修复的错误CASSANDRA-11534 引起的。问题是这个(cql bug)是否与Java驱动问题有关。 Java 驱动程序文档的第 2 版提到了 MapCodec<K,V>。但是 3.1 的文档只有抽象版本 (AbstractMapCodec<K,V>)。 这实际上可能与编解码器无关。在小型数据集上,我的代码运行良好,但在大型数据集上却失败了。但它总是失败,有时在几秒钟内,有时在几十秒后。有时它也会因 AccessControlException on FilePermission" "C:\Program Files\DataStax-DDC\apache-cassandra\conf\logback.xml" "read" 而失败。 【参考方案1】:这只是部分答案。对于大型数据集,我仍然经常在 Java 客户端和 cqlsh 中遇到 CodecNotFoundException。
我的部分问题是基于不正确的期望。我曾期望结果将作为行返回,每个地图条目都是一行。但查询结果是包含地图的单行。
读取结果的代码是:
Map<String,Double> map = queryResults.one().getMap( 0, String.class, Double.class);
【讨论】:
以上是关于Cassandra:带有地图结果的 UDF 在 Java 中获取 CodecNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章