文章目录
  1. 1. schema定义
  2. 2. 基本类型
  3. 3. 复杂类型
    1. 3.1. records
    2. 3.2. enums
    3. 3.3. arrays
    4. 3.4. Maps
    5. 3.5. Unions
    6. 3.6. Fixed
  4. 4. schema兼容
    1. 4.1. record兼容
    2. 4.2. 读写schema的角度
    3. 4.3. 新旧版本schema
    4. 4.4. 别名
  5. 5. 参考

Avro依赖于模式(Schema)。通过模式定义各种数据结构,只有确定了模式才能对数据进行解释,所以在数据的序列化和反序列化之前,必须先确定模式的结构。正是模式的引入,使得数据具有了自描述的功能,同时能够实现动态加载,另外与其他的数据序列化系统如Thrift相比,数据之间不存在其他的任何标识,有利于提高数据处理的效率。下面我们就介绍一下Avro中的schema。

schema定义

AVRO的Schema是用JSON的格式表示的,Schema可以用

  1. JSON String 来命名一个定义的类型
  2. JSON 对象,形式如:

    {"type": "typeName" ...attributes...}
    

    typeName可以是一个原生类型或者下面将要定义的衍生类型。这篇文档没有定义JSON对象中的属性,这些属性可以成为meta data,但是不能影响序列化数据的格式。

  3. JSON 数组,代表内嵌类型的并集(union)。

基本类型

总共8种原生类型 null,boolean,int,long,float,double,bytes,string.

  1. 原生类型不需要attributes
  2. 可以通过type指定 “string” 和 {”type”:”string”}是等同的

复杂类型

总共6种复合类型 records,enums,arrays,maps,unions,fixed

records

records一般是序列化数据的最终展现单元,而且可以自己嵌套

{
  "type": "record", 
  "name": "LongList",
  "aliases": ["LinkedLongs"],                      // old name for this
  "fields" : [
    {"name": "value", "type": "long"},             // each element has a long
    {"name": "next", "type": ["null", "LongList"]} // optional next element
  ]
}

enums

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

arrays

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

Maps

keys必须是string,所以这里只指定了values的类型

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

Unions

不能包含两个或者两个以上没有name属性的相同类型

["string", "null"]

Fixed

size指定每个值占用多少个字节

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

schema兼容

因为应用版本的问题经常遇到读和写的schema不相同的情况,幸运的是avro已经提供了相关的解决方案:

record兼容

实际应用中,更多是以record的形式进行交互,接下来我们重点讲解下record的兼容。

读写schema的角度

从读写schema的角度考虑,读写schema的不同无外乎就两种,读的schema比写的schema多了一个field,读的schema比写的schema少了一个field,这两种情况处理起来都很简单。

  1. 增加了field的情况:增加的fields用默认值空字符串代替;
  2. 减少了field的情况:删除的field被忽略掉

新旧版本schema

  1. 新版本schema比旧版本schema增加了一个字段

    新版本读旧版本的数据,使用新版本schema里新增field的默认值

    旧版本读新版本的数据,新版本schema里新增field被旧版本的忽略掉

  2. 新版本schema比旧版本schema少了一个字段

    新版本读旧版本的数据,减少的field被新版本忽略掉

    旧版本读新版本的数据,旧版本的schema使用被删除field的默认值,如果没有就会报错,那么升级旧版本

别名

别名是另一个用于schema兼容的方法,可以将写的schema的field名字转换成读的schema的field,记住并不是加了aliases字段。而是将写的filed的name属性变为aliases,读的时候只认name属性。

参考

  1. Apache Avro™ 1.7.7 Specification
文章目录
  1. 1. schema定义
  2. 2. 基本类型
  3. 3. 复杂类型
    1. 3.1. records
    2. 3.2. enums
    3. 3.3. arrays
    4. 3.4. Maps
    5. 3.5. Unions
    6. 3.6. Fixed
  4. 4. schema兼容
    1. 4.1. record兼容
    2. 4.2. 读写schema的角度
    3. 4.3. 新旧版本schema
    4. 4.4. 别名
  5. 5. 参考