maven依赖avro_大数据通用的序列化器——Apache Avro

1. 简介

Apache Avro(以下简称 Avro)是一种与编程语言无关的序列化格式。Doug Cutting 创建了这个项目,目的是提供一种共享数据文件的方式。

Avro 数据通过与语言无关的 schema 来定义。schema 通过 JSON 来描述,数据被序列化成二进制文件或 JSON 文件,不过一般会使用二进制文件。Avro 在读写文件时需要用到 schema,schema 一般会被内嵌在数据文件里。

Avro 有一个很有意思的特性是,当负责写消息的应用程序使用了新的 schema,负责读消息的应用程序可以继续处理消息而无需做任何改动。

到写本篇博客的时间为止,avro的最新版本为1.8.2

2. 创建 maven 工程

(1) 加入 avro 依赖

org.apache.avro

avro

1.8.2

(2) 加入 avro 插件的依赖

org.apache.avro

avro-maven-plugin

1.8.2

generate-sources

schema

${project.basedir}/src/main/avro/

${project.basedir}/src/main/java/

org.apache.maven.plugins

maven-compiler-plugin

1.6

1.6

以上是官网列出的 avro 插件的依赖,其中提供了 maven 的编译插件,该插件使用JDK1.6版本来编译代码,我在这里改为了1.8,因为我的JDK版本是1.8

org.apache.maven.plugins

maven-compiler-plugin

1.8

1.8

在引入这个插件后,在 pom.xml 中会有编译错误(错误原因我也不清楚),选择忽略即可

选择忽略之后,在 pom 中会自动生成以下配置来说明 pom 文件已经忽略了 avro 插件引起的错误

org.eclipse.m2e

lifecycle-mapping

1.0.0

org.apache.avro

avro-maven-plugin

[1.8.2,)

schema

以上错误是在 Eclipse 中创建 avro 的 maven 项目时才会出现,在 IDEA 中就不会出现这种情况。

(3) 更新 maven 工程

作了以上修改后,发现 maven 项目上有报错,但 pom 中并没有错误:

在项目上右键更新maven项目即可:

3. 使用 avro

(1) 通过生成代码的方式使用 avro

<1> 定义 schema 文件

注意在 avro 插件的依赖中定义的两个路径

${project.basedir}/src/main/avro/

${project.basedir}/src/main/java/

该配置的意思是,根据/src/main/avro/下的schema文件,生成对应的类文件到/src/main/java/下,所以我们先创建一个资源文件夹/src/main/avro

然后再在该资源文件夹下创建 schema 文件,这里定义一个简单的schema文件user.avsc,注意,后缀一定是avsc,其中的内容如下:

{

"namespace": "com.avro.example",

"type": "record",

"name": "User",

"fields": [

{"name": "name", "type": "string"},

{"name": "favorite_number", "type": ["int", "null"]},

{"name": "favorite_color", "type": ["string", "null"]}

]

}

namespace:定义了根据 schema 文件生成的类的包名

type:固定写法

name:生成的类的名称

fields:定义了生成的类中的属性的名称和类型,其中"type": ["int", "null"]的意思是,favorite_number 这个属性是int类型,但可以为null

avro 支持的类型有null、boolean、int、long、float、double、bytes、string这些基本类型和record、enum、array、map、union、fixed这些复杂类型,关于复杂类型可以参考官网的说明:http://avro.apache.org/docs/current/spec.html#schema_complex,本文只是一个入门

<2> 生成 User 类

在编译程序之前,项目中是没有com.avro.example.User这个类的:

在运行 maven build compile 后,就生成这个类:

<3> 序列化

package com.avro.serializer;

import java.io.File;

import java.io.IOException;

import org.apache.avro.file.DataFileWriter;

import org.apache.avro.io.DatumWriter;

import org.apache.avro.specific.SpecificDatumWriter;

import com.avro.example.User;

/**

* @Title AvroSerializerTest.java

* @Description 使用 avro 对 com.avro.example.User 类的对象进行序列化

* @Author YangYunhe

* @Date 2018-06-21 15:42:02

*/

public class AvroSerializerTest {

public static void main(String[] args) throws IOException {

User user1 = new User();

user1.setName("Tom");

user1.setFavoriteNumber(7);

User user2 = new User("Jack", 15, "red");

User user3 = User.newBuilder()

.setName("Harry")

.setFavoriteNumber(1)

.setFavoriteColor("green")

.build();

DatumWriter userDatumWriter = new SpecificDatumWriter<>(User.class);

DataFileWriter dataFileWriter = new DataFileWriter(userDatumWriter);

dataFileWriter.create(user1.getSchema(), new File("users.avro"));

dataFileWriter.append(user1);

dataFileWriter.append(user2);

dataFileWriter.append(user3);

dataFileWriter.close();

}

}

运行以上程序,就会把这3个User对象经过 avro 序列化后写到了项目根目录下的"user.avro"文件中:

<4> 反序列化

package com.avro.deserializer;

import java.io.File;

import java.io.IOException;

import org.apache.avro.file.DataFileReader;

import org.apache.avro.io.DatumReader;

import org.apache.avro.specific.SpecificDatumReader;

import com.avro.example.User;

/**

* @Title AvroDeSerializerTest.java

* @Description 解析 avro 序列化后的对象

* @Author YangYunhe

* @Date 2018-06-21 15:58:10

*/

public class AvroDeSerializerTest {

public static void main(String[] args) throws IOException {

DatumReader userDatumReader = new SpecificDatumReader(User.class);

DataFileReader dataFileReader = new DataFileReader(new File("users.avro"), userDatumReader);

User user = null;

while (dataFileReader.hasNext()) {

user = dataFileReader.next(user);

System.out.println(user);

}

}

}

程序运行结果为:

{"name": "Tom", "favorite_number": 7, "favorite_color": null}

{"name": "Jack", "favorite_number": 15, "favorite_color": "red"}

{"name": "Harry", "favorite_number": 1, "favorite_color": "green"}

(2) 通过不生成代码的方式使用 avro

<1> 序列化

package com.avro.serializer;

import java.io.File;

import java.io.IOException;

import org.apache.avro.Schema;

import org.apache.avro.file.DataFileWriter;

import org.apache.avro.generic.GenericData;

import org.apache.avro.generic.GenericDatumWriter;

import org.apache.avro.generic.GenericRecord;

import org.apache.avro.io.DatumWriter;

import com.avro.deserializer.AvroDeSerializerWithoutCodeGenerationTest;

/**

* @Title AvroSerializerWithoutCodeGenerationTest.java

* @Description 通过不生成代码的方式使用avro序列化User对象

* @Author YangYunhe

* @Date 2018-06-21 16:04:13

*/

public class AvroSerializerWithoutCodeGenerationTest {

public static void main(String[] args) throws IOException {

String avscFilePath =

AvroDeSerializerWithoutCodeGenerationTest.class.getClassLoader().getResource("user.avsc").getPath();

Schema schema = new Schema.Parser().parse(new File(avscFilePath));

GenericRecord user1 = new GenericData.Record(schema);

user1.put("name", "Tony");

user1.put("favorite_number", 18);

GenericRecord user2 = new GenericData.Record(schema);

user2.put("name", "Ben");

user2.put("favorite_number", 3);

user2.put("favorite_color", "red");

File file = new File("user2.avro");

DatumWriter datumWriter = new GenericDatumWriter(schema);

DataFileWriter dataFileWriter = new DataFileWriter(datumWriter);

dataFileWriter.create(schema, file);

dataFileWriter.append(user1);

dataFileWriter.append(user2);

dataFileWriter.close();

}

}

<2> 反序列化

package com.avro.deserializer;

import java.io.File;

import java.io.IOException;

import org.apache.avro.Schema;

import org.apache.avro.file.DataFileReader;

import org.apache.avro.generic.GenericDatumReader;

import org.apache.avro.generic.GenericRecord;

import org.apache.avro.io.DatumReader;

/**

* @Title AvroDeSerializerWithoutCodeGenerationTest.java

* @Description 通过不生成代码的方式使用avro反序列化

* @Author YangYunhe

* @Date 2018-06-21 16:07:44

*/

public class AvroDeSerializerWithoutCodeGenerationTest {

public static void main(String[] args) throws IOException {

String avscFilePath =

AvroDeSerializerWithoutCodeGenerationTest.class.getClassLoader().getResource("user.avsc").getPath();

Schema schema = new Schema.Parser().parse(new File(avscFilePath));

File file = new File("user2.avro");

DatumReader datumReader = new GenericDatumReader(schema);

DataFileReader dataFileReader = new DataFileReader(file, datumReader);

GenericRecord user = null;

while (dataFileReader.hasNext()) {

user = dataFileReader.next(user);

System.out.println(user);

}

}

}

程序运行结果:

{"name": "Tony", "favorite_number": 18, "favorite_color": null}

{"name": "Ben", "favorite_number": 3, "favorite_color": "red"}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值