理解 avro 及其解析模块:fastavro、pyavroc

在我看来,avro 文件最大的特点无非是:便于实现并发。

avro 是一种快速可压缩的二进制数据形式,对数据二进制序列化后可以节约数据存储空间和网络传输带宽使用,avro 文件总体上由文件头(Header)和数据块(Data Block)及同步标识(Synchronization marker)三部分组成。

avro 文件的组成,from CSDN

关于 avro 文件,Wikipedia 给出的定义是:

Avro是一种远程过程调用和数据序列化框架,是在Apache的Hadoop项目之内开发的。它使用JSON来定义数据类型和通讯协议,使用压缩二进制格式来序列化数据。它主要用于Hadoop,它可以为持久化数据提供一种序列化格式,并为Hadoop节点间及从客户端程序到Hadoop服务的通讯提供一种电报格式。

还有一点,avro 定义了一个对象容器存储的文件格式,一个文件有一个模式(schema),这样便可以高效、精确地对文件进行切割划分。Avro文件的文件头包含以下元信息(metadata),每个avro 文件都包含这些信息:

image

enter image description here

下面详细解释这三个部分:

  • 文件头为标识为Header的青色大框部分,包括文件的 schema、codec、sync marker 等信息。在 fastavro 的命令行工具中,使用fastavro --schema weather.avro可以获取文件的 schema 信息,schema 提供了文件类型、变量数据格式等等细节
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ fastavro --schema weather.avro

{
"type": "record",
"namespace": "test",
"doc": "A weather reading.",
"fields": [
{
"type": "string",
"name": "station"
},
{
"type": "long",
"name": "time"
},
{
"type": "int",
"name": "temp"
}
],
"name": "Weather"
}
  • 数据块为文件头下方紧邻的灰色的 Data Block 部分,包括 block 内数据(record)个数、序列化对象大小、16 byte 大小的同步标识(sync marker)。在这些信息的基础上,每个 block 在文件中都有唯一确定的标识,这样就可以有效地提取或跳过某个 block 的二进制数据, 块大小,对象计数和同步标记的组合可以帮助检测损坏的块并确保数据完整性。
  • 同步标识 sync marker 数据块下方紧接着的橘色的 Synchronization marker 部分

1. avro 文件解析模块:fastavro 和 pyavroc

目前,Python 环境下使用较多的模块有三种,解析速度最快的是底层基于 C 实现的 pyavroc, 它的遍历速度大约是 fastavro 的 4 倍,每遍历 1 W 条 record 只需要 0.5s。只不过 pyavroc 的安装稍微麻烦一点,需要先安装 Cmake 编译,其他的两个安装都比较简单,一个 pip 命令就可以搞定。

Name Description Relative speed (bigger is better)
python-avro Avro’s implementation (pure Python) 1
fastavro python-avro improved, using Cython 10
pyavroc Python/C API on upstream Avro-C 40

1.1 安装 pyavroc

1.1.1 安装步骤

作者在 github 上给出的安装步骤,按照步骤一步一步来就好了,安装完成之后import pyavroc就可以直接使用。

https://github.com/Byhiras/pyavroc#installating-the-module

1.1.2 安装 cmake

pyavroc 是使用 cmake 进行编译的,先安装 cmake。

https://blog.csdn.net/qing666888/article/details/79090622

1
2
3
4
5
6
7
sudo wget https://cmake.org/files/v3.12/cmake-3.12.1-Linux-x86_64.tar.gz --no-check-certificate

tar -xzf cmake-3.12.1-Linux-x86_64.tar.gz

export PATH=$PATH:/file/path/cmake-3.10.1-Linux-x86_64/bin

cmake --version # 如果返回版本信息则表示安装成功

1.2.3 安装 pyavroc

前面的准备工作做好之后,在目录下有一个脚本,直接执行脚本会创建一个 build 的文件夹,进入文件夹,里面有一个 whl 的安装文件(可能跟文档说的不一样)。

./clone_avro_and_build.sh

python setup.py bdist_wheel -d build

cd build

pip install pyavroc-0.7.2-cp36-cp36m-linux_x86_64.whl

1.2 安装 fastavro

pip install fastavro

2. pyavro 与 fastavro 读取 avro 文件

fastavro 读取 avro 文件时有两种方法:逐条遍历和块读取。

1
2
3
4
5
6
7
8
9
10
11
12
# 逐条遍历
from fastavro import reader
with open('some-file.avro', 'rb') as fo:
avro_reader = reader(fo)
for record in avro_reader:
process_record(record)
# 块 block_reader 读取
from fastavro import block_reader
with open('some-file.avro', 'rb') as fo:
avro_reader = block_reader(fo)
for block in avro_reader:
process_block(block)

pyavroc 的速度虽说比 fastavro 要快,但是它的方法少得可怜,比如读取文件,pyavroc 只能逐条遍历,没有类似 fastavro 的块读取:

1
2
3
4
5
>>> import pyavroc
>>> with open('myfile.avro') as fp:
>>> reader = pyavroc.AvroFileReader(fp, types=True)
>>> for record in reader:
>>> print record

写到这里,本文还没有提及到 avro 快速的原因,下一篇文章将会继续提到。

觉得还不错?赞助一下~
0%