在Spark Cassandra连接器中映射UUID

时间:2018-12-12 16:14:56

标签: java apache-spark cassandra rdd

我有以下代码将RDD保存到cassandra:

 JavaRDD<UserByID> mapped = ......

CassandraJavaUtil.javaFunctions(mapped)
.writerBuilder("mykeyspace", "user_by_id", mapToRow(UserByID.class)).saveToCassandra();

UserByID是一个普通的可序列化的POJO,带有带有getter和setter的以下变量

private UUID userid;

Cassandra表具有与类UserByID变量完全相同的名称,并且userid在Cassandra表中具有uuid类型,我正在使用相同的类映射从该表成功加载数据。

CassandraJavaRDD<UserByID> UserByIDRDD = javaFunctions(spark)
 .cassandraTable("mykeyspace", "user_by_id", mapRowTo(UserByID.class));

但是,当我调用上面的saveToCassandra函数时,出现以下异常:

org.apache.spark.SparkException: Job aborted due to stage failure: Task
0 in stage 227.0 failed 1 times, most recent failure: Lost task 0.0
in stage 227.0 (TID 12721, localhost, executor driver): 
java.lang.IllegalArgumentException: 
The value (4e22e71a-a387-4de8-baf1-0ef6e65fe33e) of the type 
(java.util.UUID) cannot be converted to 
struct<leastSignificantBits:bigint,mostSignificantBits:bigint> 

要解决该问题,我已经注册了UUID编解码器,但无济于事,我正在使用spark-cassandra-connector_2.11版本2.4.0和相同版本的spark-core_2.11任何建议吗?

我的参考是here,但没有Java UUID示例,感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

这真是一个奇怪的错误-可以在连接器2.4.0和Spark 2.2.1上正常运行,如下例所示:

表定义:

CREATE TABLE test.utest (
    id int PRIMARY KEY,
    u uuid
);

POJO class

public class UUIDData {
    private UUID u;
    private int id;
    ...
    // getters/setters
};

Spark job

public static void main(String[] args) {
    SparkSession spark = SparkSession
            .builder()
            .appName("UUIDTest")
            .getOrCreate();

    CassandraJavaRDD<UUIDData> uuids = javaFunctions(spark.sparkContext())
            .cassandraTable("test", "utest", mapRowTo(UUIDData.class));

    JavaRDD<UUIDData> uuids2 = uuids.map(x -> new UUIDData(x.getId() + 10, x.getU()));

    CassandraJavaUtil.javaFunctions(uuids2)
            .writerBuilder("test", "utest", mapToRow(UUIDData.class))
            .saveToCassandra();
}

我注意到,在您的代码中,您使用的是函数mapRowTomapToRow,而没有在POJO上调用.class-您确定代码已编译并且您没有运行任何旧版本的代码?