Apache Avro使用入门指南

转载 2017年09月07日 10:41:59

  Avro有C, C++, C#, Java, PHP, Python, and Ruby等语言的实现,本文只简单介绍如何在Java中使用Avro进行数据的序列化(data serialization)。本文使用的是Avro 1.7.4,这是写这篇文章时最新版的Avro。读完本文,你将会学到如何使用Avro编译模式、如果用Avro序列化和反序列化数据。

一、准备项目需要的jar包

  文本的例子需要用到的Jar包有这四个:avro-1.7.1.jar、avro-tools-1.7.4.jar、 jackson-core-asl-1.8.8.jar、jackson-mapper-asl-1.8.8.jar,请先将这几个jar包下载好,并存放在一个地方(本文是存放在$HIVE_HOME/lib目录中)。如果你是用Maven,你可以在你项目的pom.xml文件中加入以下依赖:

<dependency>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro</artifactId>
  <version>1.7.4</version>
</dependency>
 
<plugin>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-maven-plugin</artifactId>
  <version>1.7.4</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.6</source>
    <target>1.6</target>
  </configuration>
</plugin>

  当然,如果你需要,你也可以在Avro源码中进行编译,获取avro-1.7.1.jar和avro-tools-1.7.4.jar。关于如何编译avro已经超出本文的范围。

二、定义模式(Schema)

  在avro中,它是用Json格式来定义模式的。模式可以由基础类型(null, boolean, int, long, float, double, bytes, and string)和复制类型(record, enum, array, map, union, and fixed)的数据组成。本文只是定义了一个简单的模式user.avsc:

{
   "namespace": "example.avro",
   "type": "record",
   "name": "User",
   "fields": [
      {
         "name": "name",
         "type": "string"
      },
      {
         "name": "favorite_number",
         "type": [
            "int",
            "null"
         ]
      },
      {
         "name": "favorite_color",
         "type": [
            "string",
            "null"
         ]
      }
   ]
}

  上面的模式是定义了一个用户的记录,在模式定义中,必须包含它的类型("type": "record")、一个名字("name": "User")以及fields。在本例中fields包括了name, favorite_number和favorite_color,上面的模式我们还定义了一个命名空间 ("namespace": "example.avro"),namespace可以名字一起使用,从而组成模式的全名(本例为example.avro.User)。

三、编译模式

  Avro可以允许我们根据模式的定义而生成相应的类,一旦我们定义好相关的类,我们程序中就不需要直接使用模式了。可以用avro-tools jar包来生成代码,语法如下:

java -jar $HIVE_HOME/lib/avro-tools-1.7.4.jar
     compile schema
     <schema file> <destination>

所以,在本例中我们可以这样来使用

java -jar $HIVE_HOME/lib/avro-tools-1.7.4.jar compile schema user.avsc .

  这时候,在当前目录下会生成example/avro/User.java类,细心的读者可能会发现example/avro不就是模式定义中的namespace么?的确是的。

  如果你直接用Avro Maven plugin,那么你就不需要手动的编译模式,因为Avro Maven plugin会自动给你编译好。

  现在我们已经生成好了一个User.java类,我们就可以用代码生成User,并用avro将它序列化存放到本地文件中,最后我们再将其反序列化。

四、如何使用

我们可以用下面的代码生成几个User:

User user1 = new User();
user1.setName("Alyssa");
user1.setFavoriteNumber(256);
// Leave favorite color null
 
// Alternate constructor
User user2 = new User("Ben", 7, "red");
 
// Construct via builder
User user3 = User.newBuilder()
             .setName("Charlie")
             .setFavoriteColor("blue")
             .setFavoriteNumber(null)
             .build();

从上面的列子中,我们可以看出,我们可以调用User的构造函数或者是builder来获取一个User实例。下面对上述的几个User进行序列化操作,并将序列化的数据存放到users.avro文件中:

// Serialize user1 and user2 to disk
File file = new File("users.avro");
DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
dataFileWriter.create(user1.getSchema(), new File("users.avro"));
dataFileWriter.append(user1);
dataFileWriter.append(user2);
dataFileWriter.append(user3);
dataFileWriter.close();

运行完这个代码之后,将会在磁盘产生users.avro文件,里面是用avro序列化user的数据。我们可以对其进行反序列化,获取到原来的数据:

// Deserialize Users from disk
DatumReader<User> userDatumReader = new SpecificDatumReader<User>(User.class);
DataFileReader<User> dataFileReader =
                           new DataFileReader<User>(file, userDatumReader);
User user = null;
while (dataFileReader.hasNext()) {
    // Reuse user object by passing it to next(). This saves us from
    // allocating and garbage collecting many objects for files with
    // many items.
    user = dataFileReader.next(user);
    System.out.println(user);
}

这段代码将会产生成以下的结果:

{"name": "Alyssa", "favorite_number": 256, "favorite_color": null}
{"name": "Ben", "favorite_number": 7, "favorite_color": "red"}
{"name": "Charlie", "favorite_number": null, "favorite_color": "blue"}

五、一个完整的例子

import java.io.*;
import java.lang.*;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.DatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.file.DataFileReader;
import example.avro.User;
 
public class Test {
    public static void main(String args[]) {
        User user1 = new User();
        user1.setName("Alyssa");
        user1.setFavoriteNumber(256);
        // Leave favorite color null
 
        // Alternate constructor
        User user2 = new User("Ben", 7, "red");
 
        // Construct via builder
        User user3 = User.newBuilder()
             .setName("Charlie")
             .setFavoriteColor("blue")
             .setFavoriteNumber(null)
             .build();
        //Serialize user1, user2 and user3 to disk
        File file = new File("users.avro");
        DatumWriter<User> userDatumWriter =
                   new SpecificDatumWriter<User>(User.class);
        DataFileWriter<User> dataFileWriter =
                   new DataFileWriter<User>(userDatumWriter);
        try {
            dataFileWriter.create(user1.getSchema(), new File("users.avro"));
            dataFileWriter.append(user1);
            dataFileWriter.append(user2);
            dataFileWriter.append(user3);
            dataFileWriter.close();
        } catch (IOException e) {
        }
        //Deserialize Users from dist
        DatumReader<User> userDatumReader =
                             new SpecificDatumReader<User>(User.class);
        DataFileReader<User> dataFileReader = null;
        try {
            dataFileReader = new DataFileReader<User>(file, userDatumReader);
        } catch (IOException e) {
        }
        User user = null;
        try {
            while (dataFileReader.hasNext()) {
                // Reuse user object by passing it to next(). This saves
                // us from allocating and garbage collecting many objects for
                // files with many items.
                user = dataFileReader.next(user);
                System.out.println(user);
            }
        } catch (IOException e) {
        }
    }
}

编译上述代码:

javac -classpath /home/q/hive-0.11.0/lib/avro-1.7.1.jar
                 :/home/q/hive-0.11.0/lib/avro-tools-1.7.4.jar
                 :/home/q/hive-0.11.0/lib/jackson-core-asl-1.8.8.jar
                 :/home/q/hive-0.11.0/lib/jackson-mapper-asl-1.8.8.jar
                 example/avro/User.java Test.java

运行上述代码:

java  -classpath /home/q/hive-0.11.0/lib/avro-1.7.1.jar
                 :/home/q/hive-0.11.0/lib/avro-tools-1.7.4.jar
                 :/home/q/hive-0.11.0/lib/jackson-core-asl-1.8.8.jar
                 :/home/q/hive-0.11.0/lib/jackson-mapper-asl-1.8.8.jar:User.jar:.
                 Test

相关文章推荐

Kafka入门经典教程

问题导读 1.Kafka独特设计在什么地方? 2.Kafka如何搭建及创建topic、发送消息、消费消息? 3.如何书写Kafka程序? 4.数据传输的事务定义有哪三种? 5.Kafka...

Apache Avro使用入门指南

一、引言 1、 简介 Avro是Hadoop中的一个子项目,也是Apache中一个独立的项目,Avro是一个基于二进制数据传输高性能的中间件。在Hadoop的其他项目中例如HBase(Re...

Apache Avro 1.8.1 入门指南(Java)

Apache Avro是一个数据序列化系统。序列化就是将对象转换成二进制流,相应的反序列化就是将二进制流再转换成对应的对象。因此,Avro就是用来在传输数据之前,将对象转换成二进制流,然后此二进制流达...

使用Apache Avro

Avro[1]是最近加入到Apache的Hadoop家族的项目之一。为支持数据密集型应用,它定义了一种数据格式并在多种编程语言中支持这种格式。 Avro提供的功能类似于其他编组系统,如Thrift、...

Apache Zeppelin使用入门指南:安装

Apache Zeppelin是一款基于web的notebook(类似于ipython的notebook),支持交互式地数据分析。原生就支持Spark、Scala、SQL 、shell, markdo...
  • LW_GHY
  • LW_GHY
  • 2016-05-21 00:24
  • 1628

Apache Zeppelin使用入门指南:添加外部依赖

在现实情况下,我们编写程序一般都是需要依赖外部的相关类库的,比如我们现在需要Spark读取Mysql里面的数据,所以我们需要添加Mysql相关的依赖。这里将介绍两种方法来添加外部依赖。   一、...
  • LW_GHY
  • LW_GHY
  • 2016-05-21 00:02
  • 1571

Apache Avro

一、概述 Apache Avro是一种数据序列化的系统,它提供了: 1) 支持多种数据结构 2) 二进制文件格式(压缩率高&传输速度快) 3) 容器文件格式(以便于存放持久化数据) 4) RPC 5)...

Apache Kafka编程入门指南:Producer

Kafka最初由Linkedin公司开发的分布式、分区的、多副本的、多订阅者的消息系统。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。kafka对消息保存时根据T...

Apache Kafka编程入门指南:Producer

转载:http://m.blog.csdn.net/article/details?id=50926720 Kafka最初由Linkedin公司开发的分布式、分区的、多副本的、多订阅者的消息系统...

[译]Apache MINA 2.0 第一章 入门指南

【译】Apache MINA 2.0 第一章 入门指南 举报 只看楼主 发言 楼主 ヅ虫虫ゎ 管理员 2014-01-23 14:34:18      第一章,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)