转载请写明来源地址: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. VMware Ubuntu安装详细过程

    参考链接: http://blog.csdn.net/u013142781/article/details/50529030

  2. DTN学习的一些有用链接

    1.DTN研究组,该网站提供了一些代码,有NS2上的实现,也有用java实现的源码. http://www.dtnrg.org/wiki/Code 2.DTN实现的另一个版本,与ONE比较,目前还没用 ...

  3. 在JAVA中 System.getProperty 和 System.setProperty 方法.

    今天着手研究TOMCAT源码. 在刚開始的时候Startup类中init方法中调用非常多次System.getProperty和System.setProperty的方法. 后来经过网上搜索才得知,这 ...

  4. laravel实现数据库读写分离配置或者多读写分离配置

    config\database.php里 读写分离:'mysql' => array( 'read' => array( 'host' => '192.168.1.1', ), 'w ...

  5. ios AFNetworking 有用篇

    在寻常开发中,af是个非常好用的东西.非常喜欢.可是网上的af找了好多都不太全面,不有用.所以我今天做了一个demo.有上传下载的. 比較有用.希望大家可以用到. 去我github下载demo git ...

  6. 关于虚拟继承类的大小问题探索,VC++ 和 G++ 结果是有区别的

    昨天笔试遇到个 关于类占用的空间大小的问题,以前没怎么重视,回来做个试验,还真发现了问题,以后各位笔试考官门,出题时请注明是用什么编译器. vc6/vc8 cl 和 Dev-C 的g++ 来做的测试: ...

  7. spring03autowire属性

    1.创建需要的实体类 public class Student { //学生实体类 private String name; //姓名 private Integer age; //年龄 privat ...

  8. (转)HTML特殊字符

    HTML 原始码 显示结果 描述 < < 小於号或显示标记 > > 大於号或显示标记 & & 可用於显示其它特殊字符 " " 引号 ® ® ...

  9. 排序算法之奇偶排序 JAVA奇偶排序算法

    奇偶排序法的思路是在数组中重复两趟扫描.第一趟扫描选择所有的数据项对,a[j]和a[j+1],j是奇数(j=1, 3, 5……).如果它们的关键字的值次序颠倒,就交换它们.第二趟扫描对所有的偶数数据项 ...

  10. UFLDL课程学习(一)

    章节地址:http://ufldl.stanford.edu/tutorial/supervised/LinearRegression/ 章节名称:线性回归 (Linear Regression) 第 ...