转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/9900129

所有源码在github上,https://github.com/lastsweetop/styhadoop

兼容条件

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

下面图示说明:

record兼容

在hadoop的实际应用中,更多是以record的形式进行交互,接下来我们重点讲解下record的兼容。
首先从读写schema的角度取考虑,读写schema的不同无外乎就两种,读的schema比写的schema多了一个field,读的schema比写的schema少了一个field,这两种情况处理起来都很简单。
先看下写的schema:
{
"type":"record",
"name":"com.sweetop.styhadoop.StringPair",
"doc":"A pair of strings",
"fields":[
{"name":"left","type":"string"},
{"name":"right","type":"string"}
]
}

增加了field的情况

增加了field后的schema
{
"type":"record",
"name":"com.sweetop.styhadoop.StringPair",
"doc":"A pair of strings",
"fields":[
{"name":"left","type":"string"},
{"name":"right","type":"string"},
{"name":"description","type":"string","default":""}
]
}
用增加了field的schema取读数据。new GenericDatumReader<GenericRecord>(null, newSchema),第一个参数为写的schema,第二个参数为读的schema,
由于读的是avro datafile,schema已经在文件的头部指定,所以写的schema可以忽略掉。
    @Test
public void testAddField() throws IOException {
//将schema从newStringPair.avsc文件中加载
Schema.Parser parser = new Schema.Parser();
Schema newSchema = parser.parse(getClass().getResourceAsStream("/addStringPair.avsc")); File file = new File("data.avro");
DatumReader<GenericRecord> reader = new GenericDatumReader<GenericRecord>(null, newSchema);
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, reader);
for (GenericRecord record : dataFileReader) {
System.out.println("left=" + record.get("left") + ",right=" + record.get("right") + ",description="
+ record.get("description"));
}
}

输出结果为

left=L,right=R,description=
left=L,right=R,description=

description用默认值空字符串代替

减少了field的情况

减少了field的schema
{
"type":"record",
"name":"com.sweetop.styhadoop.StringPair",
"doc":"A pair of strings",
"fields":[
{"name":"left","type":"string"}
]
}

用减少了field的schema取读取

    @Test
public void testRemoveField() throws IOException {
//将schema从StringPair.avsc文件中加载
Schema.Parser parser = new Schema.Parser();
Schema newSchema = parser.parse(getClass().getResourceAsStream("/removeStringPair.avsc")); File file = new File("data.avro");
DatumReader<GenericRecord> reader = new GenericDatumReader<GenericRecord>(null, newSchema);
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, reader);
for (GenericRecord record : dataFileReader) {
System.out.println("left=" + record.get("left"));
}
}

输出结果为:

left=L
left=L

删除的field被忽略掉

新旧版本schema

如果从新旧版本的角度取考虑。
新版本schema比旧版本schema增加了一个字段
1.新版本取读旧版本的数据,使用新版本schema里新增field的默认值
2.旧版本读新版本的数据,新版本schema里新增field被旧版本的忽略掉
新版本schema比旧版半schema较少了一个字段
1.新版本读旧版本的数据,减少的field被新版本忽略掉
2.旧版本读新版本的数据,旧版本的schema使用起被删除field的默认值,如果没有就会报错,那么升级旧版本

别名

别名是另一个用于schema兼容的方法,可以将写的schema的field名字转换成读的schema的field,记住并不是加了aliases字段。
而是将写的filed的name属性变为aliases,读的时候只认name属性。
来看下加了别名的schema
{
"type":"record",
"name":"com.sweetop.styhadoop.StringPair",
"doc":"A pair of strings",
"fields":[
{"name":"first","type":"string","aliases":["left"]},
{"name":"second","type":"string","aliases":["right"]}
]
}

使用别名schema去读数据,这里不能再用left,right,而要用first,second

    @Test
public void testAliasesField() throws IOException {
//将schema从StringPair.avsc文件中加载
Schema.Parser parser = new Schema.Parser();
Schema newSchema = parser.parse(getClass().getResourceAsStream("/aliasesStringPair.avsc")); File file = new File("data.avro");
DatumReader<GenericRecord> reader = new GenericDatumReader<GenericRecord>(null, newSchema);
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, reader);
for (GenericRecord record : dataFileReader) {
System.out.println("first=" + record.get("first")+",second="+record.get("second"));
}
}

输出结果

first=L,second=R
first=L,second=R

hadoop深入研究:(十八)——Avro schema兼容的更多相关文章

  1. hadoop深入研究:(十六)——Avro序列化与反序列化

    转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/9773233 所有源码在github上,https://github.com/l ...

  2. 菜鸟玩云计算之十八:Hadoop 2.5.0 HA 集群安装第1章

    菜鸟玩云计算之十八:Hadoop 2.5.0 HA 集群安装第1章 cheungmine, 2014-10-25 0 引言 在生产环境上安装Hadoop高可用集群一直是一个需要极度耐心和体力的细致工作 ...

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

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

  4. COS访谈第十八期:陈天奇

    COS访谈第十八期:陈天奇 [COS编辑部按] 受访者:陈天奇      采访者:何通   编辑:王小宁 简介:陈天奇,华盛顿大学计算机系博士生,研究方向为大规模机器学习.他曾获得KDD CUP 20 ...

  5. NET运用String的十八层境界

    古往今来,文本处理一直是所有编程语言的最基础的功能,也是最核心最重要的功能.任何初学者,如果想学一门编程语言,都要面对大量的文本处理.而或许有一天,即使你成了大师级的人物,也不敢说自己驾驭文本处理的能 ...

  6. hadoop深入研究:(七)——压缩

    转载请标明出处:hadoop深入研究:(七)——压缩 文件压缩主要有两个好处,一是减少了存储文件所占空间,另一个就是为数据传输提速.在hadoop大数据的背景下,这两点尤为重要,那么我现在就先来了解下 ...

  7. JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用

    JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据 ...

  8. Android进阶(十八)AndroidAPP开发问题汇总(二)

    Android进阶(十八)AndroidAPP开发问题汇总(二) 端口被占用解决措施: Android使用SimpleAdapter更新ListView里面的Drawable元素: http://ww ...

  9. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

随机推荐

  1. 鼠标事件之鼠标滑过事件MOUSEOVER

    来源地址:http://www.g2room.com/jquery/index.php?p=example%2Fevent%2Fmouseover.html&n=%E9%BC%A0%E6%A0 ...

  2. c++对象模型之Data布局

    Data语意学 class X{}; class Y : publicvirtual X {}; class Z : publicvirtual X {}; class A : publicY, pu ...

  3. 双slave的server_uuid同样问题

    早上做数据迁移,部署完slave2,发现3台机子的日志狂刷: 旧slave: 2014-05-29 14:35:35 996 [Note] Slave: received end packet fro ...

  4. linux下mysql5.5的安装

    #rpm –qa|grep –i mysql查看已安装的mysql版本 如果有已存在的mysql版本则删除 安装服务端和客户端,去Oracle官网下载: # rpm -ivh MySQL-serve ...

  5. Arduino 数码管LED屏驱动

    今天測试数码管LED屏驱动,用某产品的一个共阴极的LED屏,依据电路图做数码管LED屏的检測. 代码写得有些冗长,有好几种驱动的方法,这里仅仅是当中一种最直接的方案,抽出时间要做个更有效率的调用和驱动 ...

  6. [转] 为什么医疗咨询服务公司Evolent Health仅用4年就华丽上市?

    让医疗主体,即医院和医生担任保险角色,完全控制保费,实现医疗机构的利益最大化.美国公司EvolentHealth帮助所有医院实现这一梦想. 不觉间,已步入2015的下半年.当国内还在讨论商业保险何时能 ...

  7. Android -- Messager与Service

    如果你需要你的service和其他进程通信,那么你可以使用一个Messenger来提供这个接口. 这种方法允许你在不使用 AIDL的情况下,进行跨进程通信IPC. 实现步骤 下面是一个如何使用 Mes ...

  8. nginx 3.nginx+fastcgi

    死磕nginx 3.nginx+fastcgi 互联网服务器有个非常典型的架构lamp(linux+apache+mysql+php),由于其开源和强大的兼容性而风靡一时,不过随着nginx的横空出世 ...

  9. 在Github上面搭建Hexo博客(一):部署到Github

    什么是Hexo Hexo是一个基于Node.js的静态博客程序,可以方便的生成静态网页托管在Github和Heroku上.并且有很多人为其制作了很多优秀的主题(theme),你可以根据自己的喜好进行设 ...

  10. CodeSMART for VS.NET插件工具

    今天无聊,想起以前看过的微软的Visual Studio的插件,所以就找了找. 微软的Visual Studio本身就非常强大了,但是仍然有不足的地方,比如下面要介绍的我喜欢的代码格式化功能的这个插件 ...