使用 avro-tools, jq 查看 Apache Avro 序列化文件

Apache Avro 是类似于 Google protobuf 那样的数据交换协议,但 Avro 可以用 JSON 格式来定义 Schema, 所以相比而言更容易上手。它也是 Hadoop, Kafka 所采用的交换格式。对于生成的 avro 序列化文件如果要编写代码来解读其中内容的话就太过于麻烦,Apache 给了我们一个便捷的工具来处理 Avro Schema 和数据。

Java 版的 Avro Tools 可点击链接 avro-tools-1.8.2.jar 下载,当前版本 1.8.2(发布于 2017/05/20),执行命令是

java -jar avro-tools-1.8.2.jar ..............

如果是 Mac 平台,还可以通过

brew install avro-tools

来安装,执行命令就只是 avro-tools 了。

在本文中还会用到一个 JSON 格式化高亮显示的工具 jq, 在 Mac 下通过以下命令安装

brew install jq

avro-tools 和 jq 已准备就绪,接下来演示下如何使用它们。

avro-tools 能做什么

能做的事情很多,可以编译 Schema 为 Java 代码,从 avro 文件中获得元数据,Schema, 生成 JSON 数据,还能合并和修复 avro 文件等等。

定义 Schema 文件

创建一个 Avro Schema 文件 user.avsc, 内容如下

创建 JSON 数据文件

avro-tools 可以通过 Schema 定义和 JSON 数据文件来生成 avro 序列化文件,所以现定义 user.json 内容如下

注意,这个不是真正意义上的 JSON 文件,每个 {} 表示一条记录,不需要 [], 也不用逗号分隔。

生成 avro 文件

avro-tools fromjson --schema-file user.avsc --code deflate user.json > user.avro

现在生成了一个序列化文件 user.avro, 并选取了压缩方式为 deflate。可用 vi 打它来大致查看下

是一个 avro 文件上,Schema 内容也在里面,avro.codec 是 deflate, 数据内容看不出来,即使用不压缩的数据用 vi 看得也不明白,所以需要用 avro-tools 来查看记录内容

查看 avro 数据

用 avro-tools 的 tojson 命令

➜  avro-tools tojson user.avro
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
{"id":1,"name":"Yanbin","address":"Chicago"}
{"id":2,"name":"Someone1","address":"Shenzhen"}
{"id":3,"name":"Someone2","address":"Ji'an"}

上面蓝色部分即为序列化 user.avro 文件中数据记录,而且从前面我们应该注意到每次执行 avro-tools 命令都会打印 log4j 的告警信息--找不到 appenders, 这是 avro-tools 没处理好的,可以简单用 2 > /dev/null 屏蔽掉。后面也会介绍一个办法来消除这个 log4j 告警信息。

➜  avro-tools tojson user.avro 2>/dev/null
{"id":1,"name":"Yanbin","address":"Chicago"}
{"id":2,"name":"Someone1","address":"Shenzhen"}
{"id":3,"name":"Someone2","address":"Ji'an"}

avro-tools getscheme

➜  avro-tools getschema user.avro 2>/dev/null
{
  "type" : "record",
  "name" : "User",
  "namespace" : "cc.unmi.data",
  "fields" : [ {
    "name" : "id",
    "type" : "int"
  }, {
    "name" : "name",
    "type" : "string"
  }, {
    "name" : "address",
    "type" : "string"
  } ]
}

avro-tools getmeta

➜  avro-tools getmeta user.avro 2>/dev/null
avro.schema    {"type":"record","name":"User","namespace":"cc.unmi.data","fields":[{"name":"id","type":"int"},{"name":"name","type":"string"},{"name":"address","type":"string"}]}
avro.codec    deflate

avro-tools + jq 高亮格式化显示

格式化并高亮显示,命令 avro-tools tojson user.avro | jq

紧凑高亮显示,命令 avro-tools tojson user.avro | jq

一行一记录的显示好处是节约屏幕,并且更方便于用 grep 来查找记录

消除 avro-tools 的 log4j 警告信息

默认情况下我们每次执行 avro-tools 命令都会看到 lo4j 的警告信息

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

这对我们是没有用处的,应该是 avro-tools 中 Java 代码是被应用中 Java 项目中,一般都会有可用的日志配置文件,但作为命令来运行就没有 log4j 配置文件。因此消除上面信息的办法就是给它一个 log4j.properties 文件

进到 avro-tools 命令所在的目录,用 brew 安装的话,在 /usr/local/Cellar/avro-tools/1.8.1/bin 目录中,在该目录中创建文件

log4j.properties, 内容如下

log4j.rootLogger = ERROR, nullAppender
log4j.appender.nullAppender=org.apache.log4j.varia.NullAppender

并修改 avro-tools 命令文件如下

#!/bin/bash
exec java -Dlog4j.configuration=file:/usr/local/Cellar/avro-tools/1.8.1/bin/log4j.properties \
  -jar /usr/local/Cellar/avro-tools/1.8.1/libexec/avro-tools-1.8.1.jar "$@"

如此,则以后执行 avro-tools 命令就不会看到 log4j:WARN 信息了。如果常见得 NullAppender 太过份了点,可以配置只有 ERROR 级别的信息输出到控制台 ConsoleAppender.

链接:1. Reading and Writing Avro Files From the Command Line

本文链接 https://yanbin.blog/avro-tools-jq-view-apache-avro-file/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

1 Comment
Inline Feedbacks
View all comments
chenhua
chenhua
7 years ago

Nice !