Datastax Cassandra驱动程序抛出CodecNotFoundException异常

10

以下是确切的异常:

com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [varchar <-> java.math.BigDecimal]

我正在使用以下软件版本:Spark 1.5、Datastax-cassandra 3.2.1、CDH 5.5.1

我正在尝试执行一个使用Java API的Spark程序,它基本上从HDFS读取数据(CSV文件)并将其加载到Cassandra表中。我正在使用spark-cassandra-connector。最初,我遇到了许多有关Google's guava库冲突的问题,但通过阴影化guava库并构建具有所有依赖项的快照jar,我成功解决了这些问题。

然而,对于某些文件,我能够加载数据,但对于某些文件,我会收到Codec异常。当我研究这个问题时,我得到了以下与此问题相关的线程。

https://groups.google.com/a/lists.datastax.com/forum/#!topic/java-driver-user/yZyaOQ-wazk

https://groups.google.com/a/lists.datastax.com/forum/#!topic/java-driver-user/yZyaOQ-wazk

通过阅读这些讨论,我了解到可能是我使用的cassandra-driver版本不正确,或者与guava库相关的类路径问题仍然存在,因为Cassandra 3.0及更高版本使用guava 16.0.1,并且上述讨论中说可能在类路径中存在较低版本的guava。

以下是pom.xml文件

 <dependencies>
 <dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>1.5.0</version> 
</dependency>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>
<dependency>
<groupId>com.datastax.spark</groupId>
<artifactId>spark-cassandra-connector-java_2.10</artifactId>
<version>1.5.0-M3</version>
</dependency>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>cassandra-clientutil</artifactId>
<version>3.2.1</version>
</dependency>

</dependencies>
  <build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.3</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                 <filters>
    <filter>
        <artifact>*:*</artifact>
        <excludes>
            <exclude>META-INF/*.SF</exclude>
            <exclude>META-INF/*.DSA</exclude>
            <exclude>META-INF/*.RSA</exclude>
        </excludes>
    </filter>
</filters>
                    <relocations>
                        <relocation>
                            <pattern>com.google</pattern>
                            <shadedPattern>com.pointcross.shaded.google</shadedPattern>
                        </relocation>

                    </relocations>
                    <minimizeJar>false</minimizeJar>
                    <shadedArtifactAttached>true</shadedArtifactAttached>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>
</build>
</project>

这些是使用上述pom下载的依赖项。

spark-core_2.10-1.5.0.jar
spark-cassandra-connector-   java_2.10-1.5.0-M3.jar
spark-cassandra-connector_2.10-1.5.0-M3.jar
spark-repl_2.10-1.5.1.jar
spark-bagel_2.10-1.5.1.jar
spark-mllib_2.10-1.5.1.jar
spark-streaming_2.10-1.5.1.jar
spark-graphx_2.10-1.5.1.jar
guava-16.0.1.jar
cassandra-clientutil-3.2.1.jar
cassandra-driver-core-3.0.0-alpha4.jar
这是一些我的快照 jar 包的主要依赖项。
为什么出现了 CodecNotFoundException?是因为类路径(guava)吗?还是因为 cassandra-driver(cassandra-driver-core-3.0.0-alpha4.jar 用于 datastax cassandra 3.2.1),或者是因为代码本身?
另一个问题是,我正在向数据类型为 timestamp 的列中插入所有日期。
此外,当我执行 spark-submit 时,日志中显示了类路径。在 hadoop 库下有其他 guava 版本,它们会导致问题吗?
在进行 spark-submit 时,我们如何指定特定于用户的类路径?这有帮助吗?
很高兴听到对这些问题的观点。 谢谢
以下是堆栈跟踪。
com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [timestamp <-> java.lang.String]
at com.datastax.driver.core.CodecRegistry.notFound(CodecRegistry.java:689)
at com.datastax.driver.core.CodecRegistry.createCodec(CodecRegistry.java:550)
at com.datastax.driver.core.CodecRegistry.findCodec(CodecRegistry.java:530)
at com.datastax.driver.core.CodecRegistry.codecFor(CodecRegistry.java:485)
at com.datastax.driver.core.AbstractGettableByIndexData.codecFor(AbstractGettableByIndexData.java:85)
at com.datastax.driver.core.BoundStatement.bind(BoundStatement.java:198)
at com.datastax.driver.core.DefaultPreparedStatement.bind(DefaultPreparedStatement.java:126)
at com.cassandra.test.LoadDataToCassandra$1.call(LoadDataToCassandra.java:223)
at com.cassandra.test.LoadDataToCassandra$1.call(LoadDataToCassandra.java:1)
at org.apache.spark.api.java.JavaPairRDD$$anonfun$toScalaFunction$1.apply(JavaPairRDD.scala:1027)
at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
at org.apache.spark.util.Utils$.getIteratorSize(Utils.scala:1555)
at org.apache.spark.rdd.RDD$$anonfun$count$1.apply(RDD.scala:1121)
at org.apache.spark.rdd.RDD$$anonfun$count$1.apply(RDD.scala:1121)
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1850)
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1850)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
at org.apache.spark.scheduler.Task.run(Task.scala:88)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

我也得到了

com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [Math.BigDecimal <-> java.lang.String]

你能分享一下堆栈跟踪吗? - Andy Tolbert
我已分享了堆栈跟踪。 - Syed Ammar Mustafa
2个回答

15
当您在PreparedStatement上调用bind(params...)时,驱动程序希望您提供与cql类型相对应的java类型的值。
这个错误([timestamp <-> java.lang.String])告诉您没有注册将java String映射到cql timestamp的编解码器。在java驱动程序中,timestamp类型映射到java.util.Date。所以您有两个选择:
1. 在绑定的列是时间戳时,提供Date类型的值而不是String。 2. 创建一个将timestamp <-> String映射的编解码器。为此,您可以创建MappingCodec的子类,如文档网站所述,将String映射到时间戳。
public class TimestampAsStringCodec extends MappingCodec<String, Date> {
    public TimestampAsStringCodec() { super(TypeCodec.timestamp(), String.class); }

    @Override
    protected Date serialize(String value) { ... }

    @Override
    protected String deserialize(Date value) { ... }
}

然后您需要注册编解码器:

cluster.getConfiguration().getCodecRegistry()
    .register(new TimestampAsStringCodec());

谢谢,我现在提供了一个日期类型的值。还有一件事是,cassandra-driver-core-3.0.0-alpha4.jar足够稳定吗?当我尝试其他驱动程序,如cassandra-driver-core-3.0.0或3.0.1时,我会遇到以下异常DEFAULT_SSL_CIPHER_SUITES错误。 - Syed Ammar Mustafa
据我回忆,alpha4中没有重大bug,但是它毕竟是一个alpha版本,使用GA发布的版本(最好是3.0.2)会更好。您能否创建一个新问题来解决DEFAULT_SSL_CIPHER_SUITES错误?在3.0中进行的一个更改是不需要显式声明密码套件。我猜测这与此有关。 - Andy Tolbert
我的Cassandra表列类型为timeuuid。您能建议Datastax Mapper类中应该使用什么数据类型吗? - Vinod Jayachandran
@VinodJayachandran 您可以扩展 MappingCodec<String, UUID> 并在构造函数中调用 super(TypeCodec.timeUUID(), String.class); - metadaddy

-1

更好的解决方案在这里提供

The correct mappings that the driver offers out of the box for temporal types are:

    DATE      <-> com.datastax.driver.core.LocalDate : use getDate()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接