转载请写明来源地址: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. 如何给DropDownList控件设置样式(ASP.NET MVC)

    前话: 应学校领导要求,要给后台管理系统添加一个搜索功能,提供可选择选项.我选择使用DropDownList去实现,熟悉.net控件的都知道,DropDownList的样子非常丑,不论是边框长宽还是里 ...

  2. javascript 数组 排除null, undefined, 和不存在的元素

    The most common way to loop through the elements of an array is with a for loop: var o = [1,2,3,4,5] ...

  3. 计算两点距离 ios

    //计算两点距离 -(float)distanceBetweenTwoPoint:(CGPoint)point1 point2:(CGPoint)point2 { ) + powf(point1.y ...

  4. Apache Shiro 使用手冊 链接文件夹整理

    1.Apache Shiro 使用手冊(一)Shiro架构介绍 2.Apache Shiro 使用手冊(二)Shiro 认证 3.Apache Shiro 使用手冊(三)Shiro 授权 4.Apac ...

  5. 要缩小通过两个触摸点的观点(iOS)

    于AppDelegate.m档,创建一个视图控制器 #import "MAYAppDelegate.h" #import "MAYViewController.h&quo ...

  6. Maven实战——生命周期和插件

    Maven的构建过程包含:初始化.编译.測试.打包.集成測试.部署 Maven拥有三套相互独立的生命周期:clean(清理项目).default(构建项目).site(建立项目网站) 每一个生命周期包 ...

  7. 【经典面试题】实现平方根函数sqrt

    本文将从一道经典的面试题说起:实现平方根函数,不得调用其它库函数. 函数原型声明例如以下: double Sqrt(double A); 二分法 二分法的概念 求,等价于求方程的非负根(解).求解方程 ...

  8. SWFObject文件上传使用记录

    SWFObject文件上传使用方法记录,该插件使用起来相当强大也很灵活,与uploadify各有千秋. 值得一说的是,如果要设置button_image_url这个参数,该参数是按钮的背景图,但是一定 ...

  9. JavaScript arguments类数组

    1. 什么是类数组 arguments 是一个类数组对象.代表传给一个function的参数列表.  我们来传一个实例. function printArgs() { console.log(argu ...

  10. SQLServer 工具技巧

    SQLServerProfiler 的使用 http://www.jikexueyuan.com/course/1712.html