1.简介
Avro是一个数据序列化系统,它有以下特性:
(1)丰富的数据结构。
(2)一种紧凑、快速的二进制文件格式。
(3)存放持久化数据的容器文件。
(4)远程过程调用。
(5)支持动态语言、使用schema生成代码。
2.引入pom
在加入以下的依赖:
org.apache.avro
avro
1.8.2
下面第一个maven插件可以通过avro的schema文件生成对应的java类,第二个是普通的java编译插件。将这个两个插件加入到中。
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.7
1.7
3.定义schema
avro的schema是json格式的,支持的基本类型有:null,boolean,int,long,float,double,bytes,string。支持的复杂类型有:record,enum,array,map,union,fixed。
定义一个schema文件User.avsc:
{
"namespace": "net.bigdataer.demo.avro",
"type": "record",
"name": "User",
"fields": [
{
"name": "name",
"type": "string",
"doc":"姓名"
},
{
"name": "favorite_number",
"type": [
"int",
"null"
]
},
{
"name": "favorite_color",
"type": [
"string",
"null"
]
}
]
}
一个avsc文件必须要有type和name以及fields。同时此文件定义了namespace,它和name一起确定了文件的全名:net.bigdataer.demo.avro.User。
4.编译schema
有两种方式可以编译avro的schema,一种是使用avro-tools-1.8.2.jar手动编译,一种是使用上面提到的插件在ide中编译。下面分别对这两种方式做说明:
4.1使用avro-tools-1.8.2.jar 编译
编译命令格式如下:
java -jar avro-tools-1.8.2.jar compile schema 比如: java -jar avro-tools-1.8.2.jar compile schema user.avsc
avro-tools这个包提供了很多的工具,比如tojson可以将avro文件转为可视化的json。
4.2 使用maven插件编译
使用上面提到的avro-maven-plugin插件,可以直接在ide中执行package命令就可以编译出对应的java文件。
5.序列化与反序列化
avro序列化文件有两种方式,一种是根据schema生成实体类,另外一种不用生成实体类,只要指定schema,使用GenericRecord当做实体。下面就两种方式分别给出demo:
5.1 使用生成类User
//avro序列化demo
public class AvroWriter {
public static void main(String args[]) throws IOException {
User user1 = new User();
user1.setName("Alyssa");
user1.setFavoriteNumber(256);
User user2 = new User("Ben", 7, "red");
User user3 = User.newBuilder()
.setName("Charlie")
.setFavoriteColor("blue")
.setFavoriteNumber(null)
.build();
DatumWriter userDatumWriter = new SpecificDatumWriter(User.class);
DataFileWriter dataFileWriter = new DataFileWriter(userDatumWriter);
dataFileWriter.create(user1.getSchema(), new File("d://logs/users.avro"));
dataFileWriter.append(user1);
dataFileWriter.append(user2);
dataFileWriter.append(user3);
dataFileWriter.close();
}
}
使用avro-tools查看生成文件的内容:
java -jar avro-tools-1.8.2.jar tojson users.avro
//avro反序列化demo
public class AvroDeserialize {
public static void main(String args[]) {
DatumReader reader = new SpecificDatumReader<>(User.class);
DataFileReader fileReader = null;
try {
fileReader = new DataFileReader(new File("d://logs/users.avro"), reader);
User user = null;
while (fileReader.hasNext()) {
user = fileReader.next(user);
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下图:
5.2使用GenericRecord
//序列化
public class AvroGenericWriter {
public static void main(String args[]) throws IOException {
Schema schema = new Schema.Parser().parse(new File("d://logs/user.avsc"));
GenericRecord user1 = new GenericData.Record(schema);
user1.put("name", "Alyssa");
user1.put("favorite_number", 256);
GenericRecord user2 = new GenericData.Record(schema);
user2.put("name", "Ben");
user2.put("favorite_number", 7);
user2.put("favorite_color", "red");
File file = new File("d://logs/users-generic.avro");
DatumWriter datumWriter = new GenericDatumWriter(schema);
DataFileWriter dataFileWriter = new DataFileWriter(datumWriter);
dataFileWriter.create(schema, file);
dataFileWriter.append(user1);
dataFileWriter.append(user2);
dataFileWriter.close();
}
}
//反序列化
public class AvroGenericReader {
public static void main(String args[]) throws IOException {
Schema schema = new Schema.Parser().parse(new File("d://logs/user.avsc"));
File file = new File("d://logs/users-generic.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);
}
}
}