1.概述
当进程在进行远程通信时,彼此可以发送各种类型的数据,无论是什么类型的数据都会以二进制序列的形式在网络上传送。发送方需要把对象转化为字节序列才可在网络上传输,称为对象序列化;接收方则需要把字节序列恢复为对象,称为对象的反序列化。Hive的反序列化是对key/value反序列化成hive table的每个列的值。Hive可以方便的将数据加载到表中而不需要对数据进行转换,这样在处理海量数据时可以节省大量的时间。
2. SerDe使用
用户在建表时可以用自定义的SerDe或使用Hive自带的SerDe,SerDe能为表指定列,且对列指定相应的数据。
创建指定SerDe表时,使用row format row_format参数。
编写序列化类TestDeserializer。实现Deserializer接口的三个函数:
a)初始化:initialize(Configuration conf, Properties tb1)。
b)反序列化Writable类型返回Object:deserialize(Writable blob)。
c)获取deserialize(Writable blob)返回值Object的inspector:getObjectInspector()。
3. 示例
import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.serde2.Deserializer; import org.apache.hadoop.hive.serde2.SerDeException; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory.ObjectInspectorOptions; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Writable; public class TestDeserializer implements Deserializer { private static List Field Names = new ArrayList(); private static List Field NamesObjectInspectors = new ArrayList(); static { Field Names.add("time "); Field NamesObjectInspectors.add(ObjectInspectorFactory .getReflectionObjectInspe ctor(Long.class , ObjectInspectorOptions.JAVA)); Field Names.add("userid "); Field NamesObjectInspectors.add(ObjectInspectorFactory .getReflectionObjectInspe ctor(Integer.class , ObjectInspectorOptions.JAVA)); Field Names.add("host "); Field NamesObjectInspectors.add(ObjectInspectorFactory .getReflectionObjectInspe ctor(String.class , ObjectInspectorOptions.JAVA)); Field Names.add("path "); Field NamesObjectInspectors.add(ObjectInspectorFactory .getReflectionObjectInspe ctor(String.class , ObjectInspectorOptions.JAVA)); } @Override public Object deserialize(Writable blob) { try { if (blob instanceof Text) { String line = ((Text) blob).toString(); if (line == null ) return null ; String[] field = line.split("/t "); if (field .length != 3) { return null ; } Listresult = new ArrayList(); URL url = new URL(field [2]); Long time = Long.valueOf(field [0]); Integer userid = Integer.valueOf(field [1]); result.add(time); result.add(userid); result.add(url.getHost()); result.add(url.getPath()); return result; } } catch (MalformedURLException e) { e.printStackTrace(); } return null ; } @Override public ObjectInspector getObjectInspector() throws SerDeException { return ObjectInspectorFactory.getStandardStructObjectI nspector( Field Names, Field NamesObjectInspectors); } @Override public void initialize(Configuration arg0, Properties arg1) throws SerDeException { } } 4.总结
1、创建Hive表使用序列化时,需要自写一个实现Deserializer的类,并且选用create命令的row format参数。
2、在处理海量数据的时候,如果数据的格式与表结构吻合,可以用到Hive的反序列化而不需要对数据进行转换,可以节省大量的时间。