ETL工具-nifi干货系列 第四讲 Avro schema 序列化框架

一、在使用nifi的过程中会使用到遇到avro schema、avro data、avroReader、avroWriter等,所以本节课和大家一起学习下avro相关知识。

二、什么是Avro

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

三、什么是avro schema

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

  • 一个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"。

demo 如下:

复制代码
{
    "type": "record",
    "name": "person",
    "aliases": ["xiaojingang"],
    "fields", [
        {"name": "id", "type": "long"},
        {"name": "name", "type": "string"}
    ]
}

2)Enums

Enum使用类型名称"enum",并支持以下属性

  • name:提供记录名称的json字符串(必选)
  • namespace:限定名称的json字符串
  • aliases:字符串的json数组,为该记录提供备用名称
  • doc:一个json字符串,为用户提供该模式的说明(可选)
  • symbols:一个json数组,以json字符串的形式列出符号。在枚举中每个符号必须唯一,不能重复,每个符号都必须匹配正则表达式"A-Za-z_A-Za-z0-9_*"。
  • default:该枚举的默认值。

demo 如下:

复制代码
{
    "type": "enum",
    "name": "personType",
    "symbols": ["xiaojinang", "dajingang"]
}

3) Arrays

  • item:数组中元素的schema

声明一个value为string的array,demo如下:

复制代码
{
"type": "array",
"items": "string",
"default": []
}

4)Maps

  • values:map的值(value)的schema,其key被假定为字符串

声明一个value为long类型,(key类型为string)的map,demo如下:

复制代码
{
    "type": "map",
    "values": "long",
    "default": {}
}

5)Unions

联合使用json数组表示,例如null, "test"声明一个模式,它可以是空值或字符串。

需要注意的是:当为union类型的字段指定默认值时,默认值的类型必须与union第一个元素匹配,因此,对于包含"null"的union,通常先列出"null",因为此类型的union的默认值通常为空。

另外, union不能包含多个相同类型的schema,类型为record、fixed和eum除外。

6)Fixed

Fixed使用类型名称"fixed"并支持以下属性:

  • name:提供记录名称的json字符串(必选)
  • namespace:限定名称的json字符串
  • aliases:字符串的json数组,为该记录提供备用名称
  • doc:一个json字符串,为用户提供该模式的说明(可选)
  • size:一个整数,指定每个值的字节数(必须)

16字节的数,demo如下:

复制代码
{
    "type": "fixed",
    "name": "md5",
    "size": 16
}

四、avro的优点

Avro 格式相比 JSON 具有以下几个优点:

  1. 紧凑的数据表示: Avro 使用二进制格式进行数据存储,相比 JSON 的文本格式,二进制数据通常更加紧凑,占用更小的存储空间。这意味着在网络传输和持久化存储时,Avro 可以减少数据的大小,降低传输和存储成本。

  2. 快速的序列化和反序列化: Avro 的二进制格式使得序列化和反序列化的过程更加高效。相比 JSON 的文本解析,Avro 的二进制序列化和反序列化速度更快,特别是对于大型数据集,性能提升更为显著。

  3. Schema 的支持: Avro 要求数据必须按照预先定义的 schema 进行序列化和反序列化。这意味着数据的结构和类型在传输过程中是明确的,可以提供更强的数据验证和类型安全性。而 JSON 是一种自描述的文本格式,数据结构和类型信息嵌入在数据中,有时候可能存在解析不准确或不一致的情况。

  4. Schema 的演化: Avro 允许 schema 的演化,即可以在不破坏现有数据的前提下对 schema 进行更新。这使得系统可以灵活地适应数据结构的变化,而无需进行大规模的数据迁移。相比之下,JSON 的结构变更可能需要更复杂的处理和数据转换。

  5. 支持多种语言: Avro 提供了多种编程语言的支持,包括 Java、Python、C++ 等。通过 Avro 的各语言库,可以方便地在不同的平台和系统中进行数据交换和处理。

Avro 格式相对于 JSON 具有更高的效率、更严格的数据约束和更好的可扩展性,特别适用于大规模数据处理和分布式系统中的数据交换与存储。

五、示例演示:

首先定义schema的内容,具体为4个字段的表,名称(字符串)、年龄(整型)、技能(数组)、其他(map类型),详细如下所示:

复制代码
{
    "type":"record",
    "name":"person",
    "fields": [
        {
            "name": "name",
            "type": "string"
        },
        {
            "name": "age",
            "type": "int"
        },
        {
            "name": "skill",
            "type": {
                "type":"array",
                "items": "string"
            }
        },
        {
            "name": "other",
            "type": {
                "type": "map",
                "values": "string"
            }
        }
    ]
}

再按照上面的schema定义两条数据(person.json):

复制代码
{"name":"java小金刚","age":20,"skill":["java","go","python","kafka"],"other":{"interests":"basketball"}}
{"name":"java大金刚","age":18, "skill":["java","scala"],"other":{}}

通过avro-tools可以生成一个avro文件:

复制代码
java -jar avro-tools-1.7.4.jar fromjson --schema-file person.avsc person.json > person.avro

对于一个已存在的文件,也可以通过avro-tools工具查看schema内容、数据内容。

复制代码
java -jar avro-tools-1.7.4.jar getschema person.avro
复制代码
java -jar avro-tools-1.7.4.jar tojson person.avro
相关推荐
geovindu6 小时前
SQL Data Sampling and Approximation Techniques using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
程序员梅雨1 天前
【从零开始学习数据仓库 | 第一篇】:维度建模理论
大数据·数据仓库·学习·阿里云·数据分析
棣廷1 天前
初识数据仓库——数仓分层到DataX数据采集
数据仓库
棣廷1 天前
初识Hive(2)
数据仓库·hive·hadoop
geovindu2 天前
Pivoting and Unpivoting Data in SQL using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
数据库小学妹2 天前
OLAP数据库怎么选?看清OLTP、数仓、湖仓边界
数据仓库·mpp·列式存储·联机分析处理·数据库选型·olap数据库
程序 代码狂人3 天前
切片表与分区表的区别(数据开发面试版)
java·大数据·开发语言·数据仓库·算法
天河归来3 天前
从原始消息到业务数据:三层数据架构的设计与实践
数据库·数据仓库·架构
注塑机数据采集联网4 天前
中科晟达注塑机 MES 系统:从车间到数字化的智能制造实践
大数据·数据仓库·人工智能·物联网·制造·数据库架构