h5 { text-indent: 0.71cm; margin-top: 0.49cm; margin-bottom: 0.51cm; direction: ltr; color: #000000; line-height: 155%; text-align: justify; page-break-inside: avoid; orphans: 0; widows: 0 }
h5.western { font-family: "Times New Roman", serif; font-size: 14pt }
h5.cjk { font-family: "宋体"; font-size: 14pt }
h5.ctl { font-family: "Times New Roman", serif; font-weight: normal }
h4 { text-indent: 0.71cm; margin-top: 0.49cm; margin-bottom: 0.51cm; direction: ltr; color: #000000; line-height: 155%; text-align: justify; page-break-inside: avoid; orphans: 0; widows: 0 }
h4.western { font-family: "Arial", sans-serif; font-size: 14pt }
h4.cjk { font-family: "黑体"; font-size: 14pt }
h4.ctl { font-family: "Arial", sans-serif; font-size: 10pt; font-weight: normal }
h3 { text-indent: 0.71cm; margin-top: 0.46cm; margin-bottom: 0.46cm; direction: ltr; color: #000000; line-height: 172%; text-align: justify; page-break-inside: avoid; orphans: 0; widows: 0 }
h3.western { font-family: "Times New Roman", serif; font-size: 16pt }
h3.cjk { font-family: "宋体"; font-size: 16pt }
h3.ctl { font-family: "Times New Roman", serif; font-size: 10pt; font-weight: normal }
h2 { margin-top: 0.46cm; margin-bottom: 0.46cm; direction: ltr; color: #000000; line-height: 172%; text-align: justify; page-break-inside: avoid; orphans: 0; widows: 0 }
h2.western { font-family: "Arial", sans-serif; font-size: 16pt }
h2.cjk { font-family: "黑体"; font-size: 16pt }
h2.ctl { font-family: "Arial", sans-serif; font-size: 10pt; font-weight: normal }
p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; text-align: justify; orphans: 0; widows: 0 }
p.western { font-family: "Times New Roman", serif; font-size: 10pt }
p.cjk { font-family: "宋体"; font-size: 10pt }
p.ctl { font-family: "Times New Roman", serif; font-size: 10pt }
h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; text-align: justify; page-break-inside: avoid; orphans: 0; widows: 0 }
h1.western { font-family: "Times New Roman", serif; font-size: 22pt }
h1.cjk { font-family: "宋体" }
h1.ctl { font-family: "Times New Roman", serif; font-size: 10pt; font-weight: normal }
p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; text-align: justify; orphans: 0; widows: 0 }
p.western { font-family: "Times New Roman", serif; font-size: 10pt }
p.cjk { font-family: "宋体"; font-size: 10pt }
p.ctl { font-family: "Times New Roman", serif; font-size: 10pt }

Apache Avro# 1.8.2 Specification

3
数据序列化(Data
Serialization)

Avro数据总是用它的schema来序列化。存储Avro数据的文件应该总是在同一文件中包含数据对应的schema。基于Avro的RPC系统必须保证远端接收者有一份写入数据时所用的schema。

由于写入数据时所用的schema在读取时总是可以获取的,Avro数据本身不带有类型信息。解析数据时需要schema。

通常,序列化和反序列化都按照深度优先,从左到右的顺序遍历schema,当遇到基本类型时直接序列化。

3.1
编码

Avro指定两种序列化编码:二进制(binary)和JSON。大多数应用程序会使用二进制编码,因为它更小更快。但是,对于调试和基于web的应用程序,采用JSON编码有时是比较合适的。

3.2
二进制编码

3.2.1
基本类型

基本类型的二进制编码如下:

  • null写入0字节

  • boolean写入1字节,其值为0(false)或1(true)

  • int和long写入时使用变长的zig-zag编码。例如:

value

hex

0

00

-1

01

1

02

-2

03

2

04

...

-64

7f

64

80

...

  • float写入4字节。float被转换成32位整数,使用一种类似于java
    floatToIntBits的方法,再以little-endian格式编码。

  • double写入8字节。double被转换成64位整数,使用的方法类似于java的doubleToLongBits,然后以little-endian格式编码。

  • bytes被编码成一个long型值后面跟随多个字节的数据。

  • string被编码成一个long型值后面跟随多个字节的UTF-8编码的字符数据。

例如,3个字符的字符串"foo"
将被编码为long值3(编码为十六进制06)跟随UTF-8

编码的f
o和o(十六进制字节66
6f 6f)

3.2.2
复合类型

复合类型的二进制编码如下

3.2.2.1
Records

record按照声明时的顺序对字段的值进行编码。换句话说,record的编码正是与它的字段的编码是相关联的。字段值按照各自的schema编码。

例如,record的schema如下:

{

"type": "record",

"name": "test",

"fields" : [

{"name": "a", "type": "long"},

{"name": "b", "type": "string"}

]

}

这个schema的一个实例,其a字段的值为27(编码为十六进制36),b字段的值为"foo"(编码为十六进制的06
66 6f 6f),实例的编码只是这些字段的级联,即十六进制字节序列:

36 06 66 6f 6f

3.2.2.2
Enums

枚举用一个int来编码,表示symbol在schema中的位置(位置从0开始)

例如,考虑如下enum

{"type": "enum",
"name": "Foo", "symbols": ["A",
"B", "C", "D"] }

这将由一个在0到3之间取值的int值编码,0表示A,3表示D

3.2.2.3
Arrays

数组被编码成一系列的块。每个块包含一个long型计数值,后面跟随计数值个数组项。计数值为0的块指示数组的结束。每一项都按照数组项的schema进行编码。

如果块的计数是负数,则使用它的绝对值,计数后面紧跟一个long型的块大小(block
size),指示块的字节数。这个块大小允许快速跳过数据,例如将record投影到它的字段的一个子集时。

例如,数组的schema

{"type": "array",
"items": "long"}

一个包含3和27的数组可以编码为long值2(编码为十六进制04)紧跟long值3和27(编码为06
36),以0结束:

04 06 36 00

块形式的表示法允许读写超过内存缓冲区大小的数组,因为在不需要知道数组的完整长度的情况下就可以写入数组的项。

3.2.2.4
Maps

map被编码为一系列的块。每个块包含一个long型计数值,后面跟随计数值个key/value对。一个计数为0的块指示map的结束。每个项按照map值的schema进行编码。

如果块的计数值是负数,则使用它的绝对值,计数值后紧跟一个long型块大小指示块的字节数。这个块大小允许快速跳过数据,例如将record投影到它的字段的一个子集时。

块形式的表示法允许读写超过内存缓冲区大小的map,因为在不需要知道map的完整长度的情况下就可以写入map的项。

3.2.2.5
Unions

union被编码为:首先是一个long型值指示union值在其schema中的位置(从0开始计数)。然后根据union中指示位置处的schema编码union的值。

例如,union
schema ["null","string"] 将会编码为:

  • null 编码为0
    (null在union中的位置):

00

  • 字符串“a”编码为1(string在union中的位置,编码为十六进制02),随后是字符串的编码:

02 02 61

3.2.2.6
Fixed

Fixed实例使用schema中声明的字节数进行编码。

3.3.
JSON编码

除union外,JSON编码与用于字段默认值的编码相同。

union值被编码为JSON如下:

  • 如果它的类型是null,则它被编码为JSON
    null

  • 否则,它被编码为一个包含一个name/value对的JSON对象,name为类型的名称,

value是递归编码的值。对于Avro的命名类型(record
fixed enum)采用用户指定的名称,

对于其他类型采用类型的名称。

例如,union
schema ["null","string","Foo"],
Foo是一个record名,将会被编码为

  • null
    编码为null

  • 字符串"a"
    编码为{"string":"a"}

  • 一个Foo实例编码为{"Foo":{....}}
    , {....}指示Foo实例的JSON编码

注意,仍然需要一个schema来正确处理JSON编码的数据。例如,JSON编码不能区分int和long,float和double,records和maps,enums和字符串等。

3.4
单一对象编码(Single-object
encoding)

在某些情况下,一个单一Avro序列化的对象需要长期存储。一个常见的例子是将Avro
records储存在Apache
Kafka topic中几周。

当一个schema发生改变后的一段时间内,这种持久化系统将包含使用不同schema编码的记录。因此需要知道编码record使用了哪个schema来支持schema的演进。大多数情况下,schema大到无法包含在消息中,因此儿进制包装格式可以更有效的支持用例。

3.4.1.
单一对象编码规范

单一Avro对象编码如下:

  1. 一个两字节标记,C3
    01,表明消息是Avro和使用该单一记录(single-record)格式(版本1)

  1. 对象schema的8字节little-endian
    CRC-64-AVRO

  1. 使用Avro二进制编码的Avro对象。

使用2字节标记的实现来确定是否是AVRO。这个检查可以帮助避免当消息不是用Avro编码时所做的无效查找----通过指纹(fingerprint)决定schema

Apache Avro# 1.8.2 Specification (Avro 1.8.2规范)二的更多相关文章

  1. Apache Avro# 1.8.2 Specification (Avro 1.8.2规范)一

    h4 { text-indent: 0.71cm; margin-top: 0.49cm; margin-bottom: 0.51cm; direction: ltr; color: #000000; ...

  2. Flume的Avro Sink和Avro Source研究之一: Avro Source

    问题 : Avro Source提供了怎么样RPC服务,是怎么提供的? 问题 1.1 Flume Source是如何启动一个Netty Server来提供RPC服务. 由GitHub上avro-rpc ...

  3. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十四)定义一个avro schema使用comsumer发送avro字符流,producer接受avro字符流并解析

    参考<在Kafka中使用Avro编码消息:Consumer篇>.<在Kafka中使用Avro编码消息:Producter篇> 在了解如何avro发送到kafka,再从kafka ...

  4. Apache Avro总结

    参考 Apache Avro™ 1.9.0 Specification Avro介绍 小而巧的数字压缩算法:zigzag   原始类型(Primitive Types) 类型名 描述 描述 二进制编码 ...

  5. Apache Avro 与 Thrift 比较

    http://www.tbdata.org/archives/1307 Avro和Thrift都是跨语言,基于二进制的高性能的通讯中间件. 它们都提供了数据序列化的功能和RPC服务. 总体功能上类似, ...

  6. Apache Avro & Avro Schema简介

    为什么需要schema registry? 首先我们知道: Kafka将字节作为输入并发布 没有数据验证 但是: 如果Producer发送了bad data怎么办? 如果字段被重命名怎么办? 如果数据 ...

  7. 一文解析Apache Avro数据

    摘要:本文将演示如果序列化生成avro数据,并使用FlinkSQL进行解析. 本文分享自华为云社区<[技术分享]Apache Avro数据的序列化.反序列&&FlinkSQL解析 ...

  8. Avro基础

    一.Avro的基本功能 1.定义了数据模式文件的语法,一般使用json文件.以及一些数据基本类型与复杂类型. 2.定义了数据序列化到文件后的数据格式,此格式可供各种语言进行读取. 3.为部分语言定义了 ...

  9. Avro基础 分类: C_OHTERS 2015-02-14 19:56 310人阅读 评论(0) 收藏

    一.Avro的基本功能 1.定义了数据模式文件的语法,一般使用json文件.以及一些数据基本类型与复杂类型. 2.定义了数据序列化到文件后的数据格式,此格式可供各种语言进行读取. 3.为部分语言定义了 ...

随机推荐

  1. WebVR认识

    什么是WebVR WebVR是一种开放标准,可以在浏览器中体验VR,目标是让每个人都能轻松进入虚拟现实体验.

  2. weex 环境搭建

    最近为了项目需要(实际上是为了年底KPI),领导要求用3天时间,学习并使用weex开发一个页面,说实话,压力山大.在这之前压根儿就没听说过啊,一脸懵逼 无奈之余只能Google了,惊喜的发现weex的 ...

  3. 【读书笔记】《Effective Java》——创建和销毁对象

    Item 1. 考虑用静态工厂方法替代构造器 获得一个类的实例时我们都会采取一个共有的构造器.Foo x = new Foo(): 同时我们应该掌握另一种方法就是静态工厂方法(static facto ...

  4. P1629 邮递员送信

    题目描述: 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间.这个邮递员 ...

  5. php命令执行脚本

    php -f jiaoben.php &  读入并解释指明的文件.

  6. Ubuntu 16.04 安装wine QQ

    1.进入 http://www.ubuntukylin.com/application/show.php?lang=cn&id=279下载Wine QQ 2.解压压缩包 3.将文件夹中三个de ...

  7. 记一次高并发场景下.net监控程序数据上报的性能调优

    最近在和小伙伴们做充电与通信程序的架构迁移.迁移前的架构是,通信程序负责接收来自充电集控设备的数据实时数据,通过Thrift调用后端的充电服务,充电服务收到响应后放到进程的Queue中,然后在管理线程 ...

  8. JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

    JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...

  9. WinCE的C#编程,对float型进行四舍五入保留两位小数,小数进行四舍五入操作,Math.Round的应用案例。

    private  float ConvertFloat4Se5Ru(float flotValue) {              int iValue = (int)Math.Round(flotV ...

  10. Unity打包android的apk与数据包.obb分离和apk签名

    那么,通过以上图片.我相信大多数人已经知道怎么创建了,apk签名比較简单,假设之前没有签名文件.那么选择图中的Create New Keystore然后在以下两个password框中输入passwor ...