Hive中自定义序列化器(带编码)
hive SerDe的简介
https://www.jianshu.com/p/afee9acba686
问题
数据文件为文本文件,每一行为固定格式,每一列的长度都是定长或是有限制范围,考虑采用hive提供的RegexSerDe来实现记录解析,使用后发现hive查询出的数据中文字段乱码
解决过程
serialization.encoding=GBK
Hadoop中文件默认utf8编码,hive序列化操作时,默认按照utf8来解析,所以肯定会乱码,从网上查了下,解决方案是建表是指定serde的"serialization.encoding"="GBK",然而并没有解决我的问题
源码
Hive建表格式为ROW FORMAT,不指定SerDe时,默认用的是org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,继承了org.apache.hadoop.hive.serde2.AbstractEncodingAwareSerDe,而该类确实可以通过设置"serialization.encoding"="GBK"来解决hive读取gbk文件乱码的问题,代码如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.apache.hadoop.hive.serde2;
import com.google.common.base.Charsets;
import java.nio.charset.Charset;
import java.util.Properties;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.io.Writable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractEncodingAwareSerDe extends AbstractSerDe {
private static final Logger LOG = LoggerFactory.getLogger(AbstractEncodingAwareSerDe.class);
protected Charset charset;
public AbstractEncodingAwareSerDe() {
}
/** @deprecated */
@Deprecated
public void initialize(Configuration conf, Properties tbl) throws SerDeException {
this.charset = Charset.forName(tbl.getProperty("serialization.encoding", "UTF-8"));
if (this.charset.equals(Charsets.ISO_8859_1) || this.charset.equals(Charsets.US_ASCII)) {
LOG.warn("The data may not be properly converted to target charset " + this.charset);
}
}
public final Writable serialize(Object obj, ObjectInspector objInspector) throws SerDeException {
Writable result = this.doSerialize(obj, objInspector);
if (!this.charset.equals(Charsets.UTF_8)) {
result = this.transformFromUTF8(result);
}
return result;
}
protected abstract Writable transformFromUTF8(Writable var1);
protected abstract Writable doSerialize(Object var1, ObjectInspector var2) throws SerDeException;
public final Object deserialize(Writable blob) throws SerDeException {
if (!this.charset.equals(Charsets.UTF_8)) {
blob = this.transformToUTF8(blob);
}
return this.doDeserialize(blob);
}
protected abstract Writable transformToUTF8(Writable var1);
protected abstract Object doDeserialize(Writable var1) throws SerDeException;
}
继续查看org.apache.hadoop.hive.serde2.RegexSerDe,发现并没有用到serialization.encoding,难怪设置了也没有用,源码就不贴了
解决
解决方法也很简单,自定义类EncodingAwareRegexSerDe继承RegexSerDe,实现转UTF8的功能,代码如下:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.serde2.RegexSerDe;
import org.apache.hadoop.hive.serde2.SerDeException;
import org.apache.hadoop.hive.serde2.SerDeSpec;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
@SerDeSpec(
schemaProps = {"columns", "columns.types", "input.regex", "input.regex.case.insensitive","serialization.encoding"}
)
public class EncodingAwareRegexSerDe extends RegexSerDe {
public static final Logger LOG = LoggerFactory.getLogger(EncodingAwareRegexSerDe.class.getName());
protected String charsetName;
public EncodingAwareRegexSerDe(){
super();
}
@Override
public void initialize(Configuration conf, Properties tbl) throws SerDeException {
super.initialize(conf, tbl);
this.charsetName = tbl.getProperty("serialization.encoding", "UTF-8").trim();
}
@Override
public Object deserialize(Writable blob) throws SerDeException {
Text rowText = (Text) blob;
Text utf8Text = transformTextToYTF8(rowText,this.charsetName);
return super.deserialize(utf8Text);
}
private Text transformTextToYTF8(Text text,String encoding){
String value = "";
try{
value = new String(text.getBytes(),0,text.getLength(),encoding);
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return new Text(value);
}
}
使用自定义序列化器
将上述自定义的类打成jar包后,即可使用
操作hive shell
hive> add jar /home/dw_hbkal/przhang/hive-custom-serdes-1.0-SNAPSHOT.jar;
CREATE EXTERNAL TABLE IF NOT EXISTS test_tooldb.ind01acoma_tmp(
acq_ins_id_cd STRING,
fwd_settle_at DECIMAL(12, 0),
repl_at DECIMAL(12, 0),
......
card_accptr_nm_addr STRING,
resv5 STRING
)PARTITIONED BY(ins_id_cd STRING, hp_settle_dt STRING)
ROW FORMAT SERDE 'com.unionpay.bigdataTest.hive.serdes.EncodingAwareRegexSerDe'
with serdeproperties (
"input.regex"="(.{11}) (.{11}) (.{6}) (.{10}) (.{19}) (.{12}) (.{12}) (.{12}) (.{4}) (.{6}) (.{4}) (.{8}) (.{15}) (.{12}) (.{2}) (.{6}) (.{11}) (.{6}) (.{2}) (.{3}) (.{12}) (.{12}) (.{12}) (.{1}) (.{3}) (.{1}) (.{1}) (.{10}) (.{11}) (.{1}) (.{2}) (.{2}) (.{12}) (.{1})(.{2})(.{1})(.{1})(.{2})(.{1})(.{1})(.{2})(.{1})(.{2}) (.{11}) (.{11}) (.{1}) (.{1}) (.{4}) (.{2}) (.{1,40}) (.{3}) (.{9}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{11}) (.{9}) (.{9}) (.{9}) (.{9}) (.{19}) (.{2}) (.{40}) (.{4}) (.{1}) (.{2}) (.{10}) (.{6}) (.{1}) (.{12}) (.{193})",
"serialization.encoding"="GBK"
)
STORED AS TEXTFILE
LOCATION '/user/dw_hbkal/db/test_tooldb/ind01acoma_tmp';
load data local inpath '/home/dw_hbkal/przhang/IND18071032ACOMA' overwrite into table test_tooldb.ind01acoma_tmp partition(ins_id_cd='01055800',hp_settle_dt='20180710');
Hive中自定义序列化器(带编码)的更多相关文章
- DRF中的序列化器
DRF中的序列化器详细应用 视图的功能:说白了就是接收前端请求,进行数据处理 (这里的处理包括:如果前端是GET请求,则构造查询集,将结果返回,这个过程为序列化:如果前端是POST请求,假如要对数 ...
- kafka自定义序列化器
<kafka权威指南> Customer.java public class Customer { private int customId; private String custome ...
- Hive中自定义函数
Hive的自定义的函数的步骤: 1°.自定义UDF extends org.apache.hadoop.hive.ql.exec.UDF 2°.需要实现evaluate函数,evaluate函数支持重 ...
- Django REST framework 中的序列化器
在此之前定义一个序列化工具: views中的的代码 from rest_framework.viewsets import ModelViewSet from .models import B ...
- Spring MVC中自定义拦截器的简单示例
1. 引言 拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似于Servlet的Filter. 我们可以让普通的Bean实现HandlerIntercpetor接口或继承 ...
- Hive中自定义Map/Reduce示例 In Java
Hive支持自定义map与reduce script.接下来我用一个简单的wordcount例子加以说明. 如果自己使用Java开发,需要处理System.in,System,out以及key/val ...
- hive中修改序列化格式分隔符
标签: hadoophivealtertable 2014-11-19 10:45 4219人阅读 评论(0) 收藏 举报 分类: hadoop(6) 版权声明:本文为博主原创文章,未经博主允许不 ...
- Hive中自定义Map/Reduce示例 In Python
Hive支持自定义map与reduce script.接下来我用一个简单的wordcount例子加以说明.使用Python开发(如果使用Java开发,请看这里). 开发环境: python:2.7.5 ...
- [转]hive中自定义函数(UDAF)实现多行字符串拼接为一行
函数如何使用: hive> desc concat_test;OKa intb string hive> select * from concat_test;OK1 ...
随机推荐
- php(tp5) 生成二维码
phpqrcode类库官网下载地址:https://sourceforge.net/projects/phpqrcode/ 1.我们先看看php是怎么生成二维码的 1.首先我们先下载一下 phpqr ...
- tp5 跨域问题
只需要三行代码,写到入口文件public/index.php处即可解决 header("Access-Control-Allow-Origin:*"); header(" ...
- Hadoop大数据平台搭建之前期配置(1)
环境:CentOS 7.4 (1708 DVD) 工具:VMware.MobaXterm 一. 网络配置 1. 在VMware中安装虚拟机,此步骤不作赘述. 2. 镜像文件保留在固定目录下,网络适配 ...
- 看阿里P7讲MyBatis:从MyBatis的理解以及配置和实现全帮你搞懂
前言 MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL.存储过程以及高级映`射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结 ...
- 苹果电脑不安装flash的话怎么看直播
直播这种娱乐方式的兴起,让很多游戏玩家.脱口秀演员.歌手等拥有了一个更加宽广的舞台,可以更好地展现自己的才能.大部分的直播都是采取视频影像的方式直播,只有少部分才会采用纯音频的方式. 由于很多直播网站 ...
- 需要登录才能下载的文件可以用Folx下载吗
用苹果电脑的小伙伴有没有发现,有时候文件即时有下载链接也还是要先登录才能下载,那这样的文件用下载器Folx还能下载码?下面小编将在Mac系统平台上,通过一篇教程教大家利用Folx 5的密码管理来保存网 ...
- 二 HTML文档基本结构
2.1 HTML5文档结构: HTML5文档结构包括头部(head).主体(body)两大部分. 2.1.1<!DOCTYPE>声明 引用官方的DTD文件,在HTML5之前版本,如xHTM ...
- Kafka 内存管理类BufferPool
基本上每个成熟的框架或者工具都有一套内存管理机制 BufferPool 是Kafka 用来管理内存的工具类 BufferPool内存管理包含2个部分,已用空间+可用空间(未申请空间+ ...
- P3287 [SCOI2014]方伯伯的玉米田
首先可以证明,一定存在一种最优解,每次选择的区间结尾都是 \(n\).因为如果某一个区间结尾不是 \(n\),将其替换成 \(n\) 仍然保持单调不下降.接着都按这个策略拔高玉米. 令 \(f_{i, ...
- 初探Lerna
1.简介 首先是关于Monorepo(一篇不错的介绍Monorepo的文章),它是管理项目代码的一种方式,主要手段是通过在一个项目仓库中管理多个模块/仓库包.而Multirepo是传统的仓库管理方法, ...