最新消息:深度思考

avro入门指南(Java实现)

Java liuxuecheng 5633浏览 0评论

1.简介

Avro是一个数据序列化系统,它有以下特性:
(1)丰富的数据结构。
(2)一种紧凑、快速的二进制文件格式。
(3)存放持久化数据的容器文件。
(4)远程过程调用。
(5)支持动态语言、使用schema生成代码。

2.引入pom

加入以下的依赖:

<dependency>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro</artifactId>
  <version>1.8.2</version>
</dependency>

下面第一个maven插件可以通过avro的schema文件生成对应的java类,第二个是普通的java编译插件。将这个两个插件加入到中。

<plugin>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-maven-plugin</artifactId>
  <version>1.8.2</version>
  <executions>
    <execution>
      <phase>generate-sources</phase>
      <goals>
        <goal>schema</goal>
      </goals>
      <configuration>
        <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
        <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.7</source>
    <target>1.7</target>
  </configuration>
</plugin>

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<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
        DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(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

//avro反序列化demo
public class AvroDeserialize {
    public static void main(String args[]) {
        DatumReader<User> reader = new SpecificDatumReader<>(User.class);
        DataFileReader<User> fileReader = null;
        try {
            fileReader = new DataFileReader<User>(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();
        }
    }
}

运行结果如下图:
deserialize

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<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema);
        DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(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<GenericRecord> datumReader = new GenericDatumReader<GenericRecord>(schema);
        DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, datumReader);
        GenericRecord user = null;
        while (dataFileReader.hasNext()) {
            user = dataFileReader.next(user);
            System.out.println(user);
        }
    }
}

转载请注明:大数据随笔 » avro入门指南(Java实现)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址