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
相关推荐
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ProtonBase3 小时前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
csding1115 小时前
写入hive metastore报问题Permission denied: user=hadoop,inode=“/user/hive”
数据仓库·hive·hadoop
不会写代码的女程序猿1 天前
关于ETL的两种架构(ETL架构和ELT架构)
数据仓库·架构·etl
ssxueyi2 天前
数据仓库有哪些?
大数据·数据仓库·数据湖
武子康2 天前
大数据-256 离线数仓 - Atlas 数据仓库元数据管理 正式安装 启动服务访问 Hive血缘关系导入
大数据·数据仓库·hive·hadoop
向阳逐梦2 天前
开源云原生数据仓库ByConity ELT 的测试体验
数据仓库·云原生·开源
ssxueyi2 天前
数据仓库是什么?数据仓库简介
数据仓库
小刘鸭!3 天前
Hive解决数据倾斜
数据仓库·hive·hadoop
武子康3 天前
大数据-255 离线数仓 - Atlas 数据仓库元数据管理 数据血缘关系 元数据
大数据·数据仓库·hive·hadoop·spring