IT虾米网

Hive(五)hive的高级应用详解

admin 2018年06月05日 大数据 473 0

一、视图

视图:享用基本表的数据,不会生成另外一份数据
创建视图:

create view view_name as select * from carss;
create view carss_view as select * from carss limit 500;

查看视图:

desc view_name
desc carss_view

删除视图:

drop view view_name
drop view carss_view

使用视图:

create view sogou_view as select * from sogou_table where rank > 3 ;
select count(distinct uid) from sogou_view;

二、hive特殊分隔符处理

补充: hive 读取数据的机制:
(1) 首先用 InputFormat<默认是: org.apache.hadoop.mapred.TextInputFormat >的一个具体实 现类读入文件数据,返回一条一条的记录(可以是行,或者是你逻辑中的“行”)
(2) 然后利用 SerDe<默认: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe>的一个具体 实现类,对上面返回的一条一条的记录进行字段切割
Hive 对文件中字段的分隔符默认情况下只支持单字节分隔符,如果数据文件中的分隔符是多字符的,如下所示:

01||huangbo
02||xuzheng
03||wangbaoqiang

可用以下方式处理:

1、使用 RegexSerDe 通过正则表达式来抽取字段

create table t_bi_reg(id string,name string)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties('input.regex'='(.*)\\|\\|(.*)','output.format.string'='%1$s %2$s')               如果三个字段,再加上一个%3$s
stored as textfile;

hive>load data local inpath '/root/hivedata/bi.dat' into table t_bi_reg;
hive>select * from t_bi_reg;

2、通过自定义 InputFormat 解决特殊分隔符问题

其原理是在 inputformat 读取行的时候将数据中的“多字节分隔符”替换为 hive 默认的 分隔符( ctrl+A 亦即 \001)或用于替代的单字符分隔符,以便 hive 在 serde 操作时按照 默认的单字节分隔符进行字段抽取

修改com.ghgj.hive.delimit2. BiDelimiterInp
      com.ghgj.hive.delimit2. BiRecordReader

把自定义的类(修改的源代码)打包    上传包 在mv xx.jar apps/apa...../lib/       重启hive , 建表时引用自己定义的类  (复杂查询时还要 add jar 包)

三、数据倾斜

   1、什么是数据倾斜

     由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点。

   2、 Hadoop 框架的特性

   A、 不怕数据大,怕数据倾斜。
   B、 Jobs 数比较多的作业运行效率相对比较低,如子查询比较多。
   C、 sum,count,max,min 等聚集函数,不会有数据倾斜问题  

  3、 容易数据倾斜情况
   A、 group by 不和聚集函数搭配使用的时候。
   B、 count(distinct ),在数据量大的情况下,容易数据倾斜,因为 count(distinct)是按 group by 字段分组,按 distinct 字段排序。
   C、 小表关联超大表

4、 产生数据倾斜的原因:
A: key 分布不均匀
B:业务数据本身的特性
C:建表考虑不周全
D:某些 HQL 语句本身就存在数据倾斜

5、 主要表现:
任务进度长时间维持在 99%或者 100%的附近, 查看任务监控页面,发现只有少量 reduce子任务未完成, 因为其处理的数据量和其他的 reduce 差异过大。
单一 reduce 处理的记录数和平均记录数相差太大,通常达到好几倍之多,最长时间远大 于平均时长。(耗时长)

6、业务场景

A: 空值产生的数据倾斜
场景说明: 在日志中,常会有信息丢失的问题, 比如日志中的 user_id,如果取其中的 user_id 和用户表中的 user_id 相关联,就会碰到数据倾斜的问题。

解决方案 1: user_id 为空的不参与关联

select * from log a join user b on a.user_id is not null and a.user_id = b.user_id union all
select * from log c where c.user_id is null;

解决方案 2: 赋予空值新的 key 值
select * from log a left outer join user b on case when a.user_id is null then
concat(‘hive’,rand()) else a.user_id end = b.user_id
总结: 方法 2 比方法 1 效率更好, 不但 IO 少了,而且作业数也少了,方案 1 中, log 表 读了两次, jobs 肯定是 2,而方案 2 是 1。 这个优化适合无效 id(比如-99, ’’, null)产 生的数据倾斜, 把空值的 key 变成一个字符串加上一个随机数,就能把造成数据倾斜的 数据分到不同的 reduce 上解决数据倾斜的问题。

B:不同数据类型关联产生数据倾斜
场景说明: 用户表中 user_id 字段为 int, log 表中 user_id 为既有 string 也有 int 的类型, 当按照两个表的 user_id 进行 join 操作的时候,默认的 hash 操作会按照 int 类型的 id 进 行分配,这样就会导致所有的 string 类型的 id 就被分到同一个 reducer 当中
解决方案: 把数字类型 id 转换成 string 类型的 id

select * from user a left outer join log b on b.user_id = cast(a.user_id as string)

 



 

 





 

发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Hive(六)hive执行过程实例分析与hive优化策略详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。