web-dev-qa-db-ja.com

Datastax Cassandra CodecNotFoundExceptionをスローするドライバ

正確な例外は次のとおりです

com.datastax.driver.core.exceptions.CodecNotFoundException:要求された操作のコーデックが見つかりません:[varchar <-> Java.math.BigDecimal]

これらは私が使用しているソフトウェアのバージョンですSpark 1.5 Datastax-cassandra 3.2.1 CDH 5.5.1

私が実行しようとしているコードは、Spark APIを使用するJavaプログラムであり、基本的にhdfsからデータ(csv)を読み取り、cassandraテーブルにロードします。私はspark-cassandra-connectorを使用しています。最初にグアバグアバライブラリの競合に関する多くの問題がありましたが、グアバライブラリをシェーディングし、すべての依存関係を持つスナップショットjarを構築することで解決できました。

ただし、一部のファイルのデータを読み込むことができましたが、一部のファイルでコーデック例外が発生しました。この問題について調査したところ、同じ問題について次のスレッドが表示されました。

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のバージョンが間違っていることです。または、cassandra 3.0以降のバージョンではguava 16.0.1を使用しているため、依然としてguavaライブラリに関連するクラスパスの問題があり、上記の説明では、クラスパスに下位バージョンの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の主な依存関係の一部です。

YはCodecNotFoundExceptionですか?クラスパス(グアバ)のせいですか?またはcassandra-driver(datastax cassandra 3.2.1の場合はcassandra-driver-core-3.0.0-alpha4.jar)、またはコードのため。

別のポイントは、データ型がtimestampである列に挿入するすべての日付です。

また、spark-submitを実行すると、ログにクラスパスが表示されます。hadooplibsの下にある他のguavaバージョンがあります。 Rこれらは問題を引き起こしていますか?

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]
10

PreparedStatementに対してbind(params...)を呼び出すと、ドライバーは、cql型にマップされる型Java型)を提供することを期待します。

このエラー([timestamp <-> Java.lang.String])は、Java Stringをcql timestampにマップするようなコーデックが登録されていないことを示しています。 Javaドライバ、timestampタイプはJava.util.Dateにマップされます。したがって、ここには2つのオプションがあります:

  1. バインドされる列がタイムスタンプ用である場合、DateではなくString型の値を指定します。
  2. timestamp <-> Stringをマップするコーデックを作成します。これを行うには、 ドキュメントサイト で説明されているように、文字列をタイムスタンプにマップするMappingCodecのサブクラスを作成します。
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());
15
Andy Tolbert

より良いソリューションが提供されます ここ

ドライバーが時間型のボックスのすぐに提供する正しいマッピングは次のとおりです。

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