`
wx1569484809
  • 浏览: 63706 次
文章分类
社区版块
存档分类
最新评论

Avro 生成代码使用案例

 
阅读更多

摘要:最近研究 Kafka,其中数据对象的序列化和反序列化操作除了内置的序列化器外,还可以自定义对象序列化器,另外还有一中方法就是使用 Avro,这种方法通过规范Schema 达到更通用的效果。本文单独抽离出如何使用 Avro 生成代码,该过程同样也可以在 Kafka 使用中利用。

<!--more-->

概述

Avro 是 Hadoop 中的一个子项目,也是 Apache 中一个独立的项目,Avro 是一个基于二进制数据传输高性能的中间件。在 Hadoop 的其他项目中,例如 HBaseHiveClient 端与服务端的数据传输也采用了这个工具。Avro 是一个数据序列化的系统,它可以提供:

1、丰富的数据结构类型 2、快速可压缩的二进制数据形式 3、存储持久数据的文件容器 4、远程过程调用 RPC 5、简单的动态语言结合功能,Avro 和动态语言结合后,读写数据文件和使用 RPC 协议都不需要生成代码,而代码生成作为一种可选的优化只值得在静态类型语言中实现。 Avro 支持跨编程语言实现(C, C++, C#,Java, Python, Ruby, PHP),Avro 提供着与诸如 Thrift 和 Protocol Buffers 等系统相似的功能,但是在一些基础方面还是有区别的,主要是:

1、动态类型:Avro 并不需要生成代码,模式和数据存放在一起,而模式使得整个数据的处理过程并不生成代码、静态数据类型等等。这方便了数据处理系统和语言的构造。 2、未标记的数据:由于读取数据的时候模式是已知的,那么需要和数据一起编码的类型信息就很少了,这样序列化的规模也就小了。 3、不需要用户指定字段号:即使模式改变,处理数据时新旧模式都是已知的,所以通过使用字段名称可以解决差异问题。 Avro 和动态语言结合后,读/写数据文件和使用 RPC 协议都不需要生成代码,而代码生成作为一种可选的优化只需要在静态类型语言中实现。

当在 RPC 中使用 Avro 时,服务器和客户端可以在握手连接时交换模式。服务器和客户端有着彼此全部的模式,因此相同命名字段、缺失字段和多余字段等信息之间通信中需要解决的一致性问题就可以容易解决。

还有,Avro 模式是用 JSON(一种轻量级的数据交换模式)定义的,这样对于已经拥有 JSON 库的语言可以容易实现

本文主要介绍如何使用 AvroSchema 文件生成代码,不会详细介绍 Schema 的语法等内容,可参考官方文档,以及如下博文。Avro介绍

使用Avro生成代码

目标

在开发中,如果我们要使用 Avro 往往需要生成类文件,虽然这些文件不需要被管理,每次编译都可以自动生成,但是如果开发中能有一个生成好的类文件,对于测试和开发都有好处。本文介绍使用 Maven 依赖来完成这个过程,好处是不需要自己下载 jar,自己敲命令行来完成代码生成。

这里着重介绍以下问题:

  1. AvroMaven 插件的配置
  2. 如何执行代码生成命令

AvroMaven 插件的配置

首先引入依赖 org.apache.avro

<dependencies>
	<!-- avro Dependency-->
	<dependency>
		<groupId>org.apache.avro</groupId>
		<artifactId>avro</artifactId>
		<version>1.8.2</version>
	</dependency>
</dependencies>

然后添加 plugin

<plugin>
	<groupId>org.apache.avro</groupId>
	<artifactId>avro-maven-plugin</artifactId>
	<version>1.8.2</version>
	<!--global plugin configuration which used for run goal separately-->
	<configuration>
		<!--The Avro source directory for schema, protocol and IDL files.-->
		<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
		<!--The directory where Avro writes code-generated sources. IMPORTANT!! -->
		<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
		<!--The input directory containing any Avro files used in testing.-->
		<testSourceDirectory>${project.basedir}/src/test/avro/</testSourceDirectory>
		<!--The output directory where Avro writes code-generated files for your testing purposes.-->
		<testOutputDirectory>${project.basedir}/src/test/java/</testOutputDirectory>
	</configuration>
	<executions>
		<execution>
			<!--
			IMPORTANT: Because this configuration is set in the execution with phase `generate-sources`.
			So only run compile or package which include this phase will apply this configuration.
			So if only make this configuration, run `mvn avro:schema` will only generate to the target
			folder with default configuration.
			-->
			<phase>generate-sources</phase>
			<goals>
				<goal>schema</goal>
				<!--If you want to generate other code, need add more goals-->
				<goal>protocol</goal>
				<goal>idl-protocol</goal>
			</goals>
			<!---->
			<configuration>
				<!--default is ${basedir}/src/main/avro
				The Avro source directory for schema, protocol and IDL files.-->
				<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>

				<!--default is ${project.build.directory}/generated-sources/avro
				 The directory where Avro writes code-generated sources. IMPORTANT!! -->
				<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>

				<!--default is ${basedir}/src/test/avro
				The input directory containing any Avro files used in testing.-->
				<testSourceDirectory>${project.basedir}/src/test/avro/</testSourceDirectory>

				<!--default is ${project.build.directory}/generated-test-sources/avro
				The output directory where Avro writes code-generated files for your testing purposes.-->
				<testOutputDirectory>${project.basedir}/src/test/java/</testOutputDirectory>

				<!--fieldVisibility PUBLIC_DEPRECATED
				Determines the accessibility of fields (e.g. whether they are public or private).
				Must be one of PUBLIC, PUBLIC_DEPRECATED or PRIVATE. PUBLIC_DEPRECATED merely
				adds a deprecated annotation to each field, e.g. "@Deprecated public long time".-->


				<!--In addition, the includes and testIncludes configurables can also be used to
				specify alternative file extensions to the defaults, which are **/*.avsc, **/*.avpr
				and **/*.avdl for schema, protocol and IDL files respectively.-->
				<!--<includes>
				  <include>**/*.avro</include>
				</includes>
				<testIncludes>
				  <testInclude>**/*.test</testInclude>
				</testIncludes>-->
			</configuration>
		</execution>
	</executions>
</plugin>

这个配置需要注意几点

配置的位置

官方文档中配置放在了 execution 标签之下,这就意味着这个配置是在对应的 phase 执行的环境下才有效。所以官方的案例只有在执行 generate-sources 时才会生效。

如果我们希望能够通过 mvn 执行 goal 的时候使配置生效,我们可以把配置放在 plugin 之下,这样所有的 goal 都会使用该配置文件。

配置选项说明

重点如如下几种配置:

配置项 默认值 描述
sourceDirectory ${basedir}/src/main/avro Avro的Schema,Protocol,IDL 等文件
outputDirectory ${project.build.directory}/generated-sources/avro 代码生成的目标文件夹
testSourceDirectory ${basedir}/src/test/avro 测试使用的Schema,Protocol,IDL 等文件
testOutputDirectory ${project.build.directory}/generated-test-sources/avro 代码生成的目标文件夹

指定生成的包路径

通过上面的配置我们发现,只能指定到根路径,如果希望生成到指定的包路径,需要通过 Avro 的源文件指定 namespace 来唯一的指定包路径:

下面是一个 Schema 文件 weather.avsc

{
  "namespace": "science.mengxin.java.avro.demo",
  "type": "record",
  "name": "Weather",
  "doc": "A weather reading.",
  "fields": [
    {
      "name": "station",
      "type": "string",
      "order": "ignore"
    },
    {
      "name": "time",
      "type": "long"
    },
    {
      "name": "temp",
      "type": "int"
    }
  ]
}

如何执行代码生成命令

有了以上的配置,生成代码就非常简单

  1. 执行 mvn compile 或者 mvn package,代码将会按照配置文件生成
  2. 执行 mvn avro:schememvn avro:protocolmvn avro:idl-protocol 单独生成对应的代码

代码参考

以下是一个简单源码案例,仅供参考。

转载于:https://my.oschina.net/mengxin/blog/1853071

分享到:
评论

相关推荐

    avrohugger:从Avro模式生成Scala案例类定义

    模式到案例的代码生成,可在Scala中使用Avro。 avrohugger-core :在运行时生成源代码以供以后评估。 avrohugger-filesorter :对架构文件进行排序,以确保正确的编译顺序。 avrohugger-tools :在命令行使用...

    gogen-avro:生成Go代码以序列化和反序列化Avro模式

    戈根阿夫罗 根据您的Avro架构生成类型安全的Go代码,包括支持Avro架构演进规则的序列化器和反序列化器。... 要将通用Avro数据反序列化为Go结构而不生成代码,请使用读取器和写入器模式实例化一个新的generic.Codec :

    Thrift和Avro实例

    在这个实例中,你可能会发现Thrift和Avro的示例代码,包括如何定义服务接口、数据结构,以及如何在不同的编程语言环境中实现客户端和服务器端的交互。对于Thrift,你可能看到如下的步骤: 1. 定义.thrift文件,其中...

    利用AVRO定义avdl文件示例

    总结来说,本文主要讲述了如何使用AVRO定义avdl文件,包括创建avdl文件、编辑avdl文件以及生成协议方法类的过程。同时,通过具体实例介绍了如何在avdl文件中定义命名空间、协议、方法以及如何导入外部的avsc文件来...

    avro-1657:AVRO-1657 演示代码

    描述中的"演示代码"表明这是一个用于展示如何解决或体现AVRO-1657问题的实际代码实例。 **Apache Avro** Apache Avro是一个重要的数据序列化框架,主要特点包括: 1. **紧凑二进制格式**: Avro使用高效的二进制...

    avro-specificdata-thread-safety-demo:用于演示 Avro SpecificData 类的线程安全问题的项目

    SpecificData是Avro针对每个具体Schema生成的Java类的基类,它提供了方便的方法来操作和验证对象。然而,由于其设计原因,特定数据实例可能不完全线程安全,这可能导致在多线程环境中出现未预期的行为或错误。 线程...

    Rocketmq-AvroDemo:按照avro规范向rocketmq中生产和消费数据

    3. **生产者代码**: 在Java代码中,创建RocketMQ的生产者实例,然后利用Avro生成的类序列化数据并发送到RocketMQ主题。 4. **消费者代码**: 创建RocketMQ的消费者实例,订阅相关的主题。接收到消息后,根据相同的...

    avrojava.rar

    总的来说,"avrojava.rar"是一个展示了如何在Java项目中使用Avro 1.10.2和Maven进行数据序列化的实例。开发者可以通过学习这个例子,理解Avro的Schema定义,以及如何在Java中使用Avro API进行数据的序列化和反序列化...

    Apache RPC调用实例

    然后,Thrift编译器会生成与所选编程语言对应的代码,这些代码包含了客户端和服务器端的实现,它们可以透明地通过网络进行通信。 **服务定义** 在Thrift中,服务定义通常写在一个`.thrift`文件中。例如: ```...

    04、日志收集系统Flume-flume自定义开发案例.docx

    在本案例中,我们将探讨如何使用 Flume 进行自定义开发,特别是通过 Avro 客户端发送事件到远程 Flume 代理。这个案例展示了如何创建一个简单的 Java 应用 `MyApp`,该应用使用自定义的 `MyRpcClientFacade` 类来与 ...

    RPC学习文档

    - 创建一个实现了抽象类`SeIMPL`的对象实例,这个类是通过Avro Complex.avpr文件编译后生成的。 - 使用`Avro.Cluster.RPCClusterServer`创建服务器对象,并指定服务名、类别及端口号等参数。 - 示例代码: ```...

    kafka_producer.rar

    “kafka_test1.0”可能是测试代码或者一个简单的示例应用,用来演示如何实例化生产者,创建消息并发送到Kafka。这个测试程序可能会包含一些硬编码的配置参数,如broker地址、主题名等,以及protobuf或avro消息的创建...

    RPC调用框架比较分析

    - **avrotest.zip** 包含了Apache Avro的相关测试案例或示例代码。Avro是Hadoop生态系统的一部分,提供了一种紧凑、快速、动态的数据交换格式。 - Avro使用JSON来定义数据类型,并提供了序列化和反序列化的API,...

    hive影评案例.rar

    本案例“hive影评案例.rar”提供了使用Java编程语言与Hive进行交互的示例,旨在帮助学习大数据Hive的同学深入理解其工作原理和应用。下面我们将详细探讨Hive的核心概念、如何使用Java操作Hive以及在大数据分析中的...

    BaijiSerializer4J:受 Apache Avro 和 Thrift 启发的用于 Java 的 Baiji 序列化器

    3. **序列化和反序列化**:在代码中实例化生成的类,调用相应方法将 Java 对象转换为字节流,或者将字节流还原为 Java 对象。 4. **数据交换**:通过网络或文件系统传递序列化后的数据,实现跨进程或跨机器的数据...

    Hadoop Real-World Solutions Cookbook 源代码

    4. **Chap 4 - 数据处理与转换**:可能涉及到数据清洗、预处理和转换的技巧,如使用Pig或Hive进行数据处理,或者使用Avro、Parquet等高效的数据格式。 5. **Chap 6 - 数据分析与挖掘**:此章节可能深入到使用Hadoop...

    Kafka .Net Framework4.0 版本

    使用Kafka .Net库,你可以创建生产者和消费者实例,它们是与Kafka集群交互的基本单元。生产者负责生成消息并将其发布到特定的主题,而消费者则订阅这些主题并处理接收到的消息。Kafka .Net支持同步和异步消息发送,...

    Hadoop权威指南(中文版)2015上传.rar

    生成代码 其他序列化系统 深入了解数据库导入 导入控制 导入和一致性 直接模式导入 使用导入的数据 导入的数据与Hive 导入大对象 执行导出 深入了解导出 导出与事务 导出和SequenceFile 第16章 实例分析 Hadoop 在...

    Packt.Spark.for.Data.Science.Cookbook.2016

    - **大规模数据集处理方法**:介绍如何使用广播变量、累加器等特性来减少网络传输成本,以及如何采用 Tungsten 项目提供的内存管理和代码生成技术来提升性能。 #### 3. 机器学习应用 - **MLlib 库的介绍与使用**:...

    Hadoop权威指南 第二版(中文版)

     生成代码  其他序列化系统  深入了解数据库导入  导入控制  导入和一致性  直接模式导入  使用导入的数据  导入的数据与Hive  导入大对象  执行导出  深入了解导出  导出与事务  导出和SequenceFile ...

Global site tag (gtag.js) - Google Analytics