设为首页 收藏本站
查看: 1143|回复: 0

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

[复制链接]

尚未签到

发表于 2015-11-11 11:50:40 | 显示全部楼层 |阅读模式
转载请写明来源地址:http://blog.iyunv.com/lastsweetop/article/details/9773233

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



使用avro在很多情况下是对原有系统的改造,框架格式都已经定义好了,我们只能直接用avro对原有数据进行整合。(如果是新建系统,最好还是用avro的datafile,下一章讲datafile)

准备工作
将一下schema保存成文件StringPair.avsc,放在src/test/resources目录下
{
"type":"record",
"name":"StringPair",
"doc":"A pair of strings",
"fields":[
{"name":"left","type":"string"},
{"name":"right","type":"string"}
]
}引入最新版本的avro时要主要,最新的avro包为1.7.4,依赖org.codehaus.jackson:jackson-core-asl:1.8.8包,但是maven库中已经没有该版本所以要换成其他版本    <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.9</version>
</dependency>
如果你用的时1.0.4版本的hadoop(或者其他版本),依赖于jackson-mapper-asl,如果与jackson-core-asl版本不一致就会产生找不到方法等异常
你需要入引入相同版本            <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.9</version>
</dependency>generic方式
这一节我们用代码讲解package com.sweetop.styhadoop;
import junit.framework.Assert;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.*;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* User: lastsweetop
* Date: 13-8-5
* Time: 下午7:59
* To change this template use File | Settings | File Templates.
*/
public class TestGenericMapping {
@Test
public void test() throws IOException {
//将schema从StringPair.avsc文件中加载
Schema.Parser parser = new Schema.Parser();
Schema schema = parser.parse(getClass().getResourceAsStream(&quot;/StringPair.avsc&quot;));
//根据schema创建一个record示例
GenericRecord datum = new GenericData.Record(schema);
datum.put(&quot;left&quot;, &quot;L&quot;);
datum.put(&quot;right&quot;, &quot;R&quot;);

ByteArrayOutputStream out = new ByteArrayOutputStream();
//DatumWriter可以将GenericRecord变成edncoder可以理解的类型
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
//encoder可以将数据写入流中,binaryEncoder第二个参数是重用的encoder,这里不重用,所用传空
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
writer.write(datum,encoder);
encoder.flush();
out.close();
DatumReader<GenericRecord> reader=new GenericDatumReader<GenericRecord>(schema);
Decoder decoder=DecoderFactory.get().binaryDecoder(out.toByteArray(),null);
GenericRecord result=reader.read(null,decoder);
Assert.assertEquals(&quot;L&quot;,result.get(&quot;left&quot;).toString());
Assert.assertEquals(&quot;R&quot;,result.get(&quot;right&quot;).toString());
}
}
result.get返回的是utf-8格式,需要调用toString方法,才能和字符串一致。

specific方式
首先使用avro-maven-plugin生成代码,pom的配置  <plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.0</version>
<executions>
<execution>
<id>schemas</id>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<includes>
<include>StringPair.avsc</include>
</includes>
<sourceDirectory>src/test/resources</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
avro-maven-plugin插件绑定在generate-sources阶段,调用mvn generate-sources即可生成源代码,我们来看下生成的源代码package com.sweetop.styhadoop;
/**
* Autogenerated by Avro
* <p/>
* DO NOT EDIT DIRECTLY
*/
@SuppressWarnings(&quot;all&quot;)
/** A pair of strings */
public class StringPair extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse(&quot;{\&quot;type\&quot;:\&quot;record\&quot;,\&quot;name\&quot;:\&quot;StringPair\&quot;,\&quot;doc\&quot;:\&quot;A pair of strings\&quot;,\&quot;fields\&quot;:[{\&quot;name\&quot;:\&quot;left\&quot;,\&quot;type\&quot;:\&quot;string\&quot;,\&quot;avro.java.string\&quot;:\&quot;String\&quot;},{\&quot;name\&quot;:\&quot;right\&quot;,\&quot;type\&quot;:\&quot;string\&quot;}]}&quot;);
@Deprecated
public java.lang.CharSequence left;
@Deprecated
public java.lang.CharSequence right;
public org.apache.avro.Schema getSchema() {
return SCHEMA$;
}
// Used by DatumWriter.  Applications should not call.
public java.lang.Object get(int field$) {
switch (field$) {
case 0:
return left;
case 1:
return right;
default:
throw new org.apache.avro.AvroRuntimeException(&quot;Bad index&quot;);
}
}
// Used by DatumReader.  Applications should not call.
@SuppressWarnings(value = &quot;unchecked&quot;)
public void put(int field$, java.lang.Object value$) {
switch (field$) {
case 0:
left = (java.lang.CharSequence) value$;
break;
case 1:
right = (java.lang.CharSequence) value$;
break;
default:
throw new org.apache.avro.AvroRuntimeException(&quot;Bad index&quot;);
}
}
/**
* Gets the value of the 'left' field.
*/
public java.lang.CharSequence getLeft() {
return left;
}
/**
* Sets the value of the 'left' field.
*
* @param value the value to set.
*/
public void setLeft(java.lang.CharSequence value) {
this.left = value;
}
/**
* Gets the value of the 'right' field.
*/
public java.lang.CharSequence getRight() {
return right;
}
/**
* Sets the value of the 'right' field.
*
* @param value the value to set.
*/
public void setRight(java.lang.CharSequence value) {
this.right = value;
}
}
为了兼容之前的版本
生成了一组get,put方法,1.6.0后生成添加了getter/setter方法,还有一个与Builder的类,没什么用已经被我删掉

另外上一篇文章有点没讲到就是schama里的name里可以使用命名空间,如com.sweetop.styhadoop.StringPair,这样生成的源代码才会是带package的

那我们来看如果使用这个生成的类,和generic方式有什么不同:


package com.sweetop.styhadoop;
import junit.framework.Assert;
import org.apache.avro.Schema;
import org.apache.avro.io.*;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* User: lastsweetop
* Date: 13-8-6
* Time: 下午2:19
* To change this template use File | Settings | File Templates.
*/
public class TestSprecificMapping {
@Test
public void test() throws IOException {
//因为已经生成StringPair的源代码,所以不再使用schema了,直接调用setter和getter即可
StringPair datum=new StringPair();
datum.setLeft(&quot;L&quot;);
datum.setRight(&quot;R&quot;);
ByteArrayOutputStream out=new ByteArrayOutputStream();
//不再需要传schema了,直接用StringPair作为范型和参数,
DatumWriter<StringPair> writer=new SpecificDatumWriter<StringPair>(StringPair.class);
Encoder encoder= EncoderFactory.get().binaryEncoder(out,null);
writer.write(datum, encoder);
encoder.flush();
out.close();
DatumReader<StringPair> reader=new SpecificDatumReader<StringPair>(StringPair.class);
Decoder decoder= DecoderFactory.get().binaryDecoder(out.toByteArray(),null);
StringPair result=reader.read(null,decoder);
Assert.assertEquals(&quot;L&quot;,result.getLeft().toString());
Assert.assertEquals(&quot;R&quot;,result.getRight().toString());
}
}
不同点总结一下,schema->StringPair.class,      GenericRecord->StringPair  
  

   
版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-137864-1-1.html 上篇帖子: hadoop的内存heap大小的配置参数 下篇帖子: Hadoop distcp拷贝
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表