【大数据】详解 AVRO 格式

详解 AVRO 格式

  • 1.Avro 介绍
  • 2.schema
    • 2.1 原始类型
    • 2.2 复杂类型
      • 2.2.1 Records
      • 2.2.2 Enums
      • 2.2.3 Arrays
      • 2.2.4 Maps
      • 2.2.5 Unions
      • 2.2.6 Fixed
  • 3.Avro 的文件存储格式
    • 3.1 数据编码
      • 3.1.1 原始类型
      • 3.1.2 复杂类型
    • 3.2 存储格式
    • 3.3 存储格式
  • 4.小结

1.Avro 介绍

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

Avro提供了:

  • ✅ 丰富的数据结构。
  • ✅ 可压缩、快速的二进制数据格式。
  • ✅ 一个用来存储持久化数据的容器文件。
  • ✅ 远程过程调用。
  • ✅ 与动态语言的简单集成,代码生成不需要读取或写入数据文件,也不需要使用或实现 RPC 协议。代码生成是一种可选的优化,只值得在静态类型语言中实现。

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

2.schema

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

  • 一个 json 字符串命名一个定义的类型。
  • 一个 json 对象,其格式为 {"type":"typeName" ... attributes ...},其中 typeName原始类型名称复杂类型名称
  • 一个 json 数组,表示嵌入类型的联合。

schema 中的类型由 原始类型(也就是 基本类型)(nullbooleanintlongfloatdoublebytesstring)和 复杂类型recordenumarraymapunionfixed)组成。

2.1 原始类型

原始类型包括如下几种:

  • null:没有值
  • boolean:布尔类型的值
  • int 32 32 32 位整形
  • long 64 64 64 位整形
  • float 32 32 32 位浮点
  • double 64 64 64 位浮点
  • bytes 8 8 8 位无符号类型
  • stringunicode 字符集序列

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

2.2 复杂类型

Avro 支持 6 种复杂类型:recordsenumsarraysmapsunionsfixed

2.2.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": "value", "type": "long"},{"name": "next", "type": ["null", "LongList"]}]
}

2.2.2 Enums

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

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

示例:

{"type": "enum","name": "Suit","symbols": ["SPADES", "HEARTS", "DIAMONDS", "CLUBS"]
}

2.2.3 Arrays

  • item:数组中元素的 schema

一个例子:声明一个 valuestringarray

{"type": "array","items": "string","default": []
}

2.2.4 Maps

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

一个例子:声明一个 valuelong 类型,(key 类型为 string)的 map

{"type": "map","values": "long","default": {}
}

2.2.5 Unions

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

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

另外,union 不能包含多个相同类型的 schema,类型为 recordfixedenum 除外。

2.2.6 Fixed

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

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

例如,16 字节的数可以声明为:

{"type": "fixed","name": "md5","size": 16
}

3.Avro 的文件存储格式

3.1 数据编码

3.1.1 原始类型

  • 对于 null 类型:不写入内容,即 0 字节长度的内容表示。
  • 对于 boolean 类型:以 1 字节的 0 或 1 来表示 falsetrue
  • 对于 intlong:以 zigzag 的方式编码写入。
  • 对于 float:固定 4 字节长度,先通过 floatToIntBits 转换 32 位整数,然后按小端编码写入。
  • 对于 double:固定 8 字节长度,先通过 doubleToLongBits 转换为 64 位整型,然后按小端编码写入。
  • 对于 bytes:先写入长度(采用 zigzag 编码写入),然后是对应长度的二进制数据内容。
  • 对于 string:同样先写入长度(采用 zigzag 编码写入),然后再写入字符串对应 utf8 的二进制数据。

3.1.2 复杂类型

  • 对于 enums:只需要将 enum 的值所在的 Index 作为结果进行编码即可,例如,枚举值为 ["A","B","C","D"],那么 0 就表示 "A",3 表示 "D"
  • 对于 maps:被编码为一系列的块。每个块由一个长整数的计数表示键值对的个数(采用 zigzag 编码写入),其后是多个键值对,计数为 0 的块表示 map 的结束。每个元素按照各自的 schema 类型进行编码。
  • 对于 arrays:与 map 类似,同样被编码为一系列的块,每个块包含一个长整数的计数,计数后跟具体的数组项内容,最后以 0 计数的块表示结束。数组项中的每个元素按照各自的 schema 类型进行编码。
  • 对于 unions:先写入 long 类型的计数表示每个 value 值的位置序号(从零开始),然后再对值按对应 schema 进行编码。
  • 对于 records:直接按照 schema 中的字段顺序来进行编码。
  • 对于 fixed:使用 schema 中定义的字节数对实例进行编码。

3.2 存储格式

在一个标准的 avro 文件中,同时存储了 schema 的信息,以及对应的数据内容。具体格式由三部分组成:

  • 魔数:固定 4 字节长度,内容为字符 'O''b''j',以及版本号标识,通常为 1 1 1

  • 元数据信息:文件的元数据属性,包括 schema、数据压缩编码方式等。整个元数据属性以一个 map 的形式编码存储,每个属性都以一个 KV 的形式存储,属性名对应 key,属性值对应 value,并以字节数组的形式存储。最后以一个固定 16 字节长度的随机字符串标识元数据的结束。

  • 数据内容:而数据内容则由一个或多个数据块构成。每个数据块的最前面是一个 long 型(按照 zigzag 编码存储)的计数表示该数据块中实际有多少条数据,后面再跟一个 long 型的计数表示编码后的( N N N 条)数据的长度,随后就是按照编码进行存储的一条条数据,在每个数据块的最后都有一个 16 字节长度的随机字符串标识块的结束。

整体存储内容如下图所示:
在这里插入图片描述

3.3 存储格式

我们通过一个实际例子来对照分析下。

首先定义 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":"hncscwc","age":20,"skill":["hadoop","flink","spark","kafka"],"other":{"interests":"basketball"}}
{"name":"tom","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 文件内容:
在这里插入图片描述
另外,对于一个已存在的文件,也可以通过 avro-tools 工具查看 schema 内容、数据内容。

[root@localhost avro]$ java -jar avro-tools-1.7.4.jar getschema ./person.avro
{"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"}} ]
}
[root@localhost avro]$ java -jar avro-tools-1.7.4.jar tojson ./person.avro
{"name":"hncscwc","age":20,"skill":["hadoop","flink","spark","kafka"],"other":{"interests":"basketball"}}
{"name":"tom","age":18,"skill":["java","scala"],"other":{}}

4.小结

本文对 avro 的格式定义、编码方式、以及实际存储的文件格式进行了详细说明,最后也以一个实际例子进行了对照说明。另外, 在官网中还涉及 rpc 的使用、mapreduce 的使用,这里就没有展开说明,有兴趣的可移步官网进行查阅。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/219731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

three.js(一)

文章目录 three.js环境搭建正文补充 示例效果知识点补充1:一个标准的html知识点补充2:原生的前端框架和Vue框架的区别原生的前端框架Vue框架声明式编程和响应式编程 three.js环境搭建 正文 搭建 Three.js 的环境通常包括以下几个步骤: 1.创建项目目录&#xff1a…

初级数据结构(三)——栈

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;二&#xff09;——链表 | 初级数据结构&#xff08;四&#xff09;——队列 下一篇-> 1、栈的特性 1.1、函数栈帧简述 即使是刚入门几天的小白&#xff0c;对栈这个字…

基于YOLOv8深度学习的吸烟/抽烟行为检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

基于SSM实现的精品课程网站

一、系统架构 前端&#xff1a;jsp | js | css | jquery | bootstrap 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.7 | mysql | maven | tomcat 二、代码及数据库 三、功能介绍 01. 登录页 02. web端-首页 03. web端-视频教程 04. web端-资料…

RK3568全国产化多网口板卡带poe供电,支持鸿蒙麒麟系统

信迈XM-3568-01主板采用瑞芯微RK3568四核Cortex-A55 处理器&#xff0c;主频最高可达2.0GHz&#xff0c;效能有大幅提升最高可配8GB内存容量&#xff0c;频率高达1600MHz&#xff1b;支持全链路ECC&#xff0c;让数据更安全可靠配置双千兆自适应RJ45以太网口&#xff0c;并扩展…

stm32---串口使用

### 串口数据发送 #include <string.h> //先引用这个字符串操作库。char str[]" HALLO WORD "&#xff1b; //定义这个数组字符串。HAL_UART_Transmit(&huart2, str, strlen(str), 100); //&huart2,这里他是一个指针&#xff0c;所以要用取地址符…

在WPF窗口中增加水印效果

** 原理&#xff1a; ** 以Canvas作为水印显示载体&#xff0c;在Canvas中创建若干个TextBlock控件用来显示水印文案&#xff0c;如下图所示 然后以每一个TextBlock的左上角为中心旋转-30&#xff0c;最终效果会是如图红线所示&#xff1a; 为了达到第一行旋转后刚好与窗口…

App防止恶意截屏功能的方法:iOS、Android和鸿蒙系统的实现方案

防止应用被截图是一个比较常见的需求&#xff0c;主要是出于安全考虑。下面将分别为iOS&#xff08;苹果系统&#xff09;、Android&#xff08;安卓系统&#xff09;及HarmonyOS&#xff08;鸿蒙系统&#xff09;提供防止截屏的方法和示例代码。 在企业内部使用的应用中&…

深入解析Freemarker模板引擎及其在Spring Boot中的高级整合

目录 引言1. Freemarker1.1.什么是Freemarker1.2 Freemarker模板组成部分1.3.优点 2. Spring Boot整合Freemarker2.1 配置2.2 数据类型 3. 案例总结 引言 Freemarker作为一款强大的模板引擎&#xff0c;与Spring Boot的整合能够极大地提升Web应用的开发效率和灵活性。本篇博客…

探索 Vim:一个强大的文本编辑器

引言&#xff1a; Vim&#xff08;Vi IMproved&#xff09;是一款备受推崇的文本编辑器&#xff0c;拥有强大的功能和高度可定制性&#xff0c;提供丰富的编辑和编程体验。本文将探讨 Vim 的基本概念、使用技巧以及为用户带来的独特优势。 简介和发展 1. Vim 的简介和历史 V…

发布jar包到maven中央仓库

1. 环境 在网上找的很多文章中写得都有很多问题&#xff0c;这里记录一下最近一次成功地发布jar包到maven中央仓库的过程。并附带上每一个步骤官方的指导链接。 系统&#xff1a;mac&#xff08;windows系统在下载辅助工具时不太一样&#xff0c;在配置上和mac系统没有区别&…

docker部署go gin框架 Linux环境

目录 文章目的是什么 环境介绍 Linux 环境下 docker 部署 go gin 详细步骤 部署 gin 文章目的是什么 假设我们学习了 go 语言&#xff0c;在 Linux 上安装了 go 相关的程序&#xff0c;也能直接运行&#xff0c;使用以下命令&#xff1a; go run main.go 假如代码是这样的…

算法中的最优化方法课程复习

算法中的最优化方法课程复习 单模函数、拟凸函数、凸函数证明证明一个线性函数与一个凸函数的和也是凸的 梯度线性规划标准形式以及如何标准化标准形式常见标准化方法线性化技巧 单纯形法二次规划无约束优化Nelder-Mead线搜索FR共轭梯度法例题 优化算法的选择、停止准则算法选择…

electron命令下载失败,手动安装教程

现象&#xff1a;pnpm i electron, 一直卡在提示错误node install.js 一 、下载需要的electron版本 地址 二、下载完毕&#xff0c;解压压缩包&#xff0c; 进入项目的node_modules/electron文件夹&#xff0c;创建dist文件夹&#xff0c;将下载的zip包里的文件复制到dist…

链路追踪详解(四):分布式链路追踪的事实标准 OpenTelemetry 概述

目录 OpenTelemetry 是什么&#xff1f; OpenTelemetry 的起源和目标 OpenTelemetry 主要特点和功能 OpenTelemetry 的核心组件 OpenTelemetry 的工作原理 OpenTelemetry 的特点 OpenTelemetry 的应用场景 小结 OpenTelemetry 是什么&#xff1f; OpenTelemetry 是一个…

DevEco Studio 鸿蒙(HarmonyOS)项目结构

DevEco Studio 鸿蒙&#xff08;HarmonyOS&#xff09;项目结构 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、项目结构 创建简单的Hello World移动应用项目结构如下图 由上到下说明各个文件夹的作用 .hvigor&#xff1a;存…

阅读笔记——《UTOPIA: Automatic Generation of Fuzz Driverusing Unit Tests》

【参考文献】Jeong B, Jang J, Yi H, et al. UTOPIA: automatic generation of fuzz driver using unit tests[C]//2023 IEEE Symposium on Security and Privacy (SP). IEEE, 2023: 2676-2692.【注】本文仅为作者个人学习笔记&#xff0c;如有冒犯&#xff0c;请联系作者删除。…

智慧储能数字孪生:能源未来的智慧引擎

随着社会对清洁能源的需求不断增加&#xff0c;智能储能技术成为能源转型的关键驱动力。在这一领域中&#xff0c;数字孪生技术的应用为智慧储能带来了全新的可能性。数字孪生是指数字化、实时、可视化的模拟系统&#xff0c;通过复制现实世界中的对象或过程&#xff0c;为智能…

SpeechGPT领航:创新的130亿参数跨模态AI模型

引言 在人工智能的最新进展中&#xff0c;SpeechGPT以其130亿参数的规模和跨模态会话能力引起了业界的广泛关注。这一由复旦大学邱锡鹏教授团队开发的模型&#xff0c;不仅在技术层面上取得了重大突破&#xff0c;也为多模态人工智能&#xff08;AI&#xff09;的未来发展指明…

Selenium库自动化测试入门

前言 为什么要学selenium&#xff1f;&#xff1f;前面已经学了requests库我们会发现 对于绝大多数动态渲染的网页来说&#xff0c;用requests进行爬虫比较繁琐。 所以我们还是要学习一下selenium库&#xff0c;以帮助我们更高效的爬取网页。 环境&#xff1a; pychar 202…