Spark Dataset无法将Kryo反序列化回Avro

时间:2018-10-01 18:26:32

标签: apache-spark apache-spark-sql apache-spark-dataset apache-spark-2.0

在以下代码中,我创建了一个Dataset<Person>,并希望将其写到Avro文件中。由于使用ZonedDateTime的Person类,Spark 2.1.0不会使用Encoders.bean(Person.class)接受我(即NullPointerExceptions),所以我改用Encoders.kryo(Person.class)

调用ds.printSchema()时,我看到数据集包含一个带有我的编码Person对象的字段。

调用ds.write()时,我期望反序列化可以免费使用,并且我会看到Avro模式包含Person字段namelastUpdated。不幸的是,它只是一个二进制字段。

public class Person
{
    private String name;
    private ZonedDateTime lastUpdated;

    // constructor + getters/setters omitted
}

public class MyTest
{
    private SparkContext sc;

    @Before
    public void setUp()
    {
        sc = new SparkContext(new SparkConf()
                .setMaster("local[2]")
                .setAppName("test"));
    }

    @Test
    public void test()
    {
        final Person bob = new Person("Bob", ZonedDateTime.now());

        Dataset<Person> ds = SparkSession.builder().sparkContext(sc).getOrCreate().sqlContext().createDataset(Arrays.asList(bob), Encoders.kryo(Person.class));

        System.out.println(ds.first());
        // com.db.rca.ts.fd.spark.Person@20d87335[name=Bob,lastUpdated=2018-10-01T19:23:18.742null[Europe/London]]

        ds.printSchema();
        // root
        // |-- value: binary (nullable = true)

        ds.write()
            .mode(SaveMode.Overwrite)
            .format("com.databricks.spark.avro")
            .save("./target/output");

       // avro file output contains the one binary field?

    }
}

我已从示例中删除了业务逻辑以提供工作代码。将数据加载到类型安全的数据集中然后写出以使Person类的所有字段在Avro模式中可见的正确方法是什么?

如果JavaRDD API尚不先进,我将恢复使用Dataset API。

0 个答案:

没有答案