第四章数据编码和更新-part2,designing Data-Intensive Applications 中文翻译摘要

Avro

Avro是2009年发起的一个hadoop的子项目,他也是一种二进制的编码方式,但是和Thrift和Protocol Buffer不尽相同,它诞生之初就是因为Thrift在Hadoop编解码是不是很好用。他同样是用schema的形式定义编解码的数据结构,他有两种描述语言(IDL),一种给人看的,另外一种是机器更好生成和解析。
还是之前的经典,如果是Avro的IDL就长这样

人类版
record Person {
  string userName;
  union { null, long } favoriteNumber = null;
  array<string> interests;
}
机器版
{
  "type": "record",
  "name": "Person",
  "fields": [
    {"name": "userName", "type": "string"},
    {"name": "favoriteNumber", "type": ["null", "long"], "default": null},
    {"name": "interests", "type": {"type": "array", "items": "string"}}
  ]
}

值得注意的是,Avro没有一个数字表示Field tag,之前的例子用Avro编码只有32字节,是目前讲过的最省空间的一种,具体的编码格式如Figure 4-5。如果你看编码内容,你会发现这里面没有地方标记属性名和属性类型的。字节流就是把所有内容拼在了一起。辅以一些参数,比如string的长度等等。当你需要解析的时候,你就根据schema里面字段的顺序和字段的类型依次进行解析。这就有一个要求,就是你解析时候用的schema必须和写这个数据时的schema完全一致。如果有不一致数据解码就有问题了。


写入schema和读取schema

但是Avro这种操作那数据schema如何更新呢?这就跟写入和读取的schema相关了。当写入数据的时候,应用可以用他知道的任何一个版本的schema进行编码。我们管这个称作写入schema。那在解码的时候,他需要数据按照某种格式进行解析,我们管这个叫读取schema。Avro的核心点在于读取schema和写入schema不需要相同,他们只需要兼容就可以了。当解码数据的时候,Avro库自动处理写入schema和读取schema的不同,将数据从写入schema的格式转换成读取schema。Avro文档详细讲述了这步是如何工作的。一个简单的例子如Figure 4-6。

如果是读写schema之间字段的顺序不一样,那Avro转换程序会根据名字进行映射,如果发现写入schema有一个字段但是读取的没有,那这个字段就被忽略掉了。反过来,如果发现读取schema有一个字段但是写入没有,那这个字段会赋一个默认值。

schema修改原则

对于Avro来说,向前兼容就意味着你可以用新版schema写并且用老版schema读,向后兼容就意味着你可以用老版schema写用新版schema读。为了保证兼容性,就要求只能增删有默认值的属性。例如你加了一个字段,新版的读程序在读到老数据时,因为数据中没有这个字段会给他一个默认值,这样就可以向后兼容。如果删一个字段,同样老版读程序在读到新数据时,也会给他一个默认值,就做到向前兼容。

有些程序语言NULL可以作为所有类型的默认值,但是Avro不可以。他必须用类型union { null, long, string }表示他可以是null.虽然比直接给所有类型一个默认值要麻烦,但是它可以有效的帮助你避免bug

改变数据类型也是可以的,Avro的库会自动帮你进行类型转换,另外改属性名也可以,但是有些问题。读取schema可以对属性设定一些别名,这样新老版本的数据就可以转换了。 但是他只能向后兼容而不能向前兼容了。给一个union type加一个类型也是,可以向后,但不能向前兼容。

写入schema是从哪来的?

我们之前讨论的很热闹,但是可能已经发现这个问题,读取程序从哪能够拿到写入的schema呢?我们不能把schema写入每条数据中,因为这货太大了。具体的解决方法跟Avro的使用场景有关,主要分成3种。

  • 文件
    Avro的使用场景一般都是一个大文件中包含上百万条数据,尤其是在hadoop中。一个文件中的数据用的都是一个schema。这个时候写入程序就需要把写入schema写在这个文件的头部就可以了。
  • 数据库
    数据库中往往会有多种数据版本共存的情况,这种情况解决方法是给数据一个版本号,然后把每个版本号对应的schema存下来。解码程序根据版本号去找对应的schema进行解码。
  • 网络
    当两个进程网络通信的时候,他们可以在连接建立之初发送自己用到的schema,在整个连接当中,schema是不会变的,如果变了就需要重起程序或重新连接。Avro RPC 就是这么工作了。

动态生成schema

Avro和Thrift 与 Protocol Buffer相比他不再需要一个数字作为属性的唯一标记。但是这么做的好处是什么呢?或者说维护一个数字和属性的映射的问题是什么呢?这个好处在于你可以动态的去生成你数据的schema,比如你有一个关系数据库,你希望把他转成二进制格式写入文件中。如果用Avro,你可以直接把数据库中每个表作为一个对象,表名就是对象名,列名作为属性名生成schema。利用这个schema把数据写到文件中。

如果你的数据库格式变了,比如加了一列,你完全不用改任何东西,还是用刚才的方法直接搞。虽然新的schema属性数量,顺序可能变了,但是读取程序使用属性名作为映射关系,所以他还是可以正常解码。但如果你用的是Protocol Buffer就麻烦了。你必须人工维护一个列名到tag的映射表,一旦数据库结构变了,你就得人工去保证他们的tag数字和之前的一样。这个就很麻烦了。虽然也可以用程序来搞,但是怎么都没有Avro方便,因为Thrift和Protocol Buffer在设计的时候就没有考虑过动态生成schema的问题。

schema的长处

有人会觉得json,xml就已经挺好的了,为什么还要有诸如Thrift,protocol Buffer这种带schema的编码格式呢?因为他们有以下优点

  • 更小,因为他们不需要存储key的内容,所以编码后的内容比json,或者BJson要小
  • schema是一个很好的文档,因为你要用他来解析数据,所以永远不用担心会出现老版本不更新的问题
  • 新功能上线前,schema可以帮助你检查数据是否能够做到前向兼容和后向兼容
  • 对于静态语言的开发者而言,它可以自动生成代码,帮助你进行类型检查,拼写检查。在json中经常出现key拼错了,或者把int写成了string这种情况。
    总的来说,非结构化数据库的那些灵活性,schema也可以做到差不多。同时它还能更好的保证你的数据(数据类型一致,字段名一直),以及更方便的工具(类型检查,拼写检查)。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容