avro格式详解

【Avro介绍】

Apache Avro是hadoop中的一个子项目,也是一个数据序列化系统,其数据最终以二进制格式,采用行式存储的方式进行存储。

Avro提供了:

  • 丰富的数据结构

  • 可压缩、快速的二进制数据格式

  • 一个用来存储持久化数据的容器文件

  • 远程过程调用

  • 与动态语言的简单集成,代码生成不需要读取或写入数据文件,也不需要使用或实现RPC协议。代码生成是一种可选的优化,只值得在静态类型语言中实现。

基于以上这些优点,avro在hadoop体系中被广泛使用。除此之外,在hudi、iceberg中也都有用到avro作为元数据信息的存储格式。

【schema】

Avro依赖"schema"(模式)来实现数据结构的定义,schema通过json对象来进行描述表示,具体表现为:

  • 一个json字符串命名一个定义的类型

  • 一个json对象,其格式为`{"type":"typeName" ...attributes...}`,其中`typeName`为原始类型名称或复杂类型名称。

  • 一个json数组,表示嵌入类型的联合

schema中的类型由原始类型(也就是基本类型)(null、boolean、int、long、float、double、bytes和string)和复杂类型(record、enum、array、map、union和fixed)组成。

1、原始类型

原始类型包括如下几种:

  • null:没有值

  • boolean:布尔类型的值

  • int:32位整形

  • long:64位整形

  • float:32位浮点

  • double:64位浮点

  • bytes:8位无符号类型

  • string:unicode字符集序列

原始类型没有指定的属性值,原始类型的名称也就是定义的类型的名称,因此,schema中的"string"等价于{"type":"string"}。

2、复杂类型

Avro支持6种复杂类型:records、enums、arrays、maps、unions和fixed。

1)Records

reocrds使用类型名称"record",并支持以下属性

  • name:提供记录名称的json字符串(必选)

  • namespace:限定名称的json字符串

  • doc:一个json字符串,为用户提供该模式的说明(可选)

  • aliases:字符串的json数组,为该记录提供备用名称

  • fields:一个json数组,罗列所有字段(必选),每个字段又都是一个json对象,并包含如下属性:

    • name:字段的名称(必选)

    • doc:字段的描述(可选)

    • type:一个schema,定义如上

    • default:字段的默认值

    • order:指定字段如何影响记录的排序顺序,有效值为`"ascending"`(默认值)、"descending"和"ignore"。

    • aliases:别名

一个简单示例:

{
    "type": "record",
    "name": "LongList",
    "aliases": ["LinkedLongs"],
    "fields", [
        {"name": "v
### 使用 Avro 格式编写 DataField 在 Avro 中,定义和写入数据字段涉及创建模式(Schema)并按照该模式序列化数据。为了向现有记录添加新字段,必须提供默认值以便旧版本的数据可以被兼容读取[^1]。 #### 定义 Schema Avro 的 `Schema` 可以通过 JSON 表达,其中每种类型的定义遵循特定结构: - 基本类型可以直接作为字符串指定; - 复杂类型则需用 JSON 对象来描述其属性; - 联合类型可以通过 JSON 数组表达多个可能的成员类型[^3]。 对于希望增加的新字段,如果允许为空,则可将其声明为联合类型的一部分,并设置 `null` 作为其中一个选项以及默认值。 ```json { "type": "record", "name": "User", "fields": [ {"name": "username", "type": "string"}, { "name": "age", "type": ["int", "null"], "default": null } ] } ``` 上述例子展示了如何给名为 `User` 的记录添加一个新的可选整型字段 `age` 并设定了它的缺省值为 `null`。 #### 序列化 Record 实例 一旦有了合适的 Schema,在编程环境中就可以利用相应库函数完成实际对象到字节流之间的转换过程。以下是 Python 下的一个简单实例演示怎样基于已知 schema 创建并写出带有新增字段的对象: ```python import avro.schema from avro.datafile import DataFileWriter from avro.io import DatumWriter schema_str = ''' {"namespace": "example.avro", "type": "record", "name": "User", "fields": [ {"name": "username", "type": "string"}, {"name": "age", "type": ["int", "null"], "default": null} ]} ''' # 解析 schema 字符串成 schema 对象 schema = avro.schema.Parse(schema_str) with open('users.avro', 'wb') as f: writer = DataFileWriter(f, DatumWriter(), schema) user_data = {'username': 'Alice'} # 即使未显式给出 age,默认情况下也会自动填充 None(null) writer.append(user_data) another_user_with_age = {'username': 'Bob', 'age': 30} writer.append(another_user_with_age) writer.close() ``` 此代码片段说明了即使不总是需要指明所有字段的具体数值——特别是那些已经设置了合理默认值得情况;当确实有具体信息时也可以正常传递完整的信息集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值