Hive基础(十四):面试题

1、hive组成

Hive基础(十四):面试题

2、与mysql区别 

              hive                      mysql

               数据量                          大                                    小

      速度                       大 =》 快                        小 =》 快

                                              查询                                 增删改查

3、内部表和外部表区别

  元数据、原始数据
  删除数据时:
  内部表:元数据、原始数据 全删除
  外部表:元数据 只删除
  在公司生产环境下,什么时候创建内部表,什么时候创建外部表?
  在公司中绝大多数场景都是外部表。
  自己使用的临时表,才会创建内部表;

4、4个by

  order by 全局排序
  sort by   排序
  distribute By 分区  sort + d => 分区内排序
  cluster By 排序和分区字段相同时使用
  在生产环境order by用的多吗? 京东 oom 40-50t内存
  s+d 在生产环境用的最多。分区内排序
  c 比较少

5、系统函数

  日 date_add date_sub
  周 next_day
  月 date_format last_day
  解析json get_json_object

6、自定义函数

  UDF/UDTF(hive)、UDAF(spark)
  1)在项目中用UDF解析公共字段
  2)在项目中使用UDTF解析的是事件字段
  3)如果项目中不用自定义UDF、UDTF能解析吗?
    可以用系统函数get_json_object
  4)用系统函数能解决,为什么还要自定义?
    自定义函数更灵活,方便调试bug
  5)自定义UDF步骤?
    定义类,继承UDF,重新里面evaluate方法
  6)自定义UDTF步骤
    定义类,继承G...UDTF ,重写3个方法 初始化、process、关闭
    打包=》上传到集群=》在hive里面创建永久函数

7、窗口函数

          rank   over 

          手写topN

8、优化

        1)mapjoin默认打开,不要关闭;

        2)行列过滤   join  where =>where  join  

        1 亿 join 1 亿 条 where 1 条

        3)创建分区表(天); 分桶(对数据不太清楚 ,采样)

   4)小文件

      (1)CombineHiveInputformart 减少切片,进而减少Maptask
      (2)开启JVM重用
      (3)merge maponly任务,默认功能打开
          MapReduce任务,需要打开merge功能。
          执行完任务之后,会将小于16m的文件,合并到256m(hive的块大小)

        5)压缩 好处:减少磁盘空间,减少网络传输;  坏处:增加了解压缩计算

   6)采用列式存储orc、parquet 提高查询效率;提高压缩的比例 100g=>10g 5-6g
      id name age
      1 zs 18
      2 lisi 19
      3 wangwu 20
      行 1 zs 18 2 lisi 19 3 wangwu 20
      select age from user 随机读写
      列 1 2 3 zs lisi wangwu 18 19 20
      select age from user 顺序读写:18 19 20

        7)替换引擎:

              mr   基于磁盘          可靠性高          效率低

                      数据量大,计算时间长  周、月、年

              tez 基于内存         可靠性差            效率高

                       临时调试代码,即席查询

             spark 基于内存+磁盘         可靠性居中            效率居中

                      每天定时任务

        8)在map端开启combiner(不影响最终业务逻辑)

        9)合理设置map个数和reduce个数;

      map个数怎么设置? 切片 max(0,min(块大小,Long的最大值))

      128m数据对应1g内存

9、数据倾斜

1)数据倾斜长啥样?

 Hive基础(十四):面试题

 

 

2)怎么产生的数据倾斜?

不同数据类型关联产生数据倾斜

情形:比如用户表中user_id字段为int,log表中user_id字段既有string类型也有int类型。当按照user_id进行两个表的Join操作时。

后果:处理此特殊值的reduce耗时;只有一个reduce任务
默认的Hash操作会按int型的id来进行分配,这样会导致所有string类型id的记录都分配到一个Reducer中。

解决方式:把数字类型转换成字符串类型

select * from users a

left outer join logs b

on a.usr_id = cast(b.user_id as string)

bug 记录: https://www.jianshu.com/p/2181e00d74dc

3)解决数据倾斜的方法?

(1)group by

注:group by 优于distinct group

解决方式:采用sum() group by的方式来替换count(distinct)完成计算。

(2)mapjoin

(3)开启数据倾斜时负载均衡

set hive.groupby.skewindata=true;

思想:就是先随机分发并处理,再按照key group by来分发处理。

操作:当选项设定为true,生成的查询计划会有两个MRJob。

第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;

第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的原始GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。

点评:它使计算变成了两个mapreduce,先在第一个中在 shuffle 过程 partition 时随机给 key 打标记,使每个key 随机均匀分布到各个 reduce 上计算,但是这样只能完成部分计算,因为相同key没有分配到相同reduce上。

所以需要第二次的mapreduce,这次就回归正常 shuffle,但是数据分布不均匀的问题在第一次mapreduce已经有了很大的改善,因此基本解决数据倾斜。因为大量计算已经在第一次mr中随机分布到各个节点完成。

(4)控制空值分布

将为空的key转变为字符串加随机数或纯随机数,将因空值而造成倾斜的数据分不到多个Reducer。

注:对于异常值如果不需要的话,最好是提前在where条件里过滤掉,这样可以使计算量大大减少

实践中,可以使用case when对空值赋上随机值。此方法比直接写is not null更好,因为前者job数为1,后者为2.

使用case when实例1:

select userid, name from user_info a

join (
select case when userid is null  then  cast (rand(47)* 100000 as int )
else userid end from user_read_log
) b  on a.userid = b.userid

使用case when实例2:

select  '${date}' as thedate,
    a.search_type,
    a.query,
    a.category,
    a.cat_name,
    a.brand_id,
    a.brand_name,
    a.dir_type,
    a.rewcatid,
    a.new_cat_name,
    a.new_brand_id,
    f.brand_name as new_brand_name,
    a.pv,
    a.uv,
    a.ipv,
    a.ipvuv,
    a.trans_amt,
    a.trans_num,
    a.alipay_uv
from fdi_search_query_cat_qp_temp a
left outer join brand f
on  f.pt='${date}000000' and case when a.new_brand_id is null then concat('hive',rand() ) else a.new_brand_id end = f.brand_id;

如果上述的方法还不能解决,比如当有多个JOIN的时候,建议建立临时表,然后拆分HIVE SQL语句。

10、杂七杂八

1) Hive里边字段的分隔符用的什么?为什么用\t?有遇到过字段里边有\t的情况吗,怎么处理的?

 

  hive 默认的字段分隔符为ascii码的控制符\001(^A),建表的时候用fields terminated by '\001'

 

  遇到过字段里边有\t的情况,自定义InputFormat,替换为其他分隔符再做后续处理

2)MYSQL元数据备份

   mysql 实现高可用

3) MySQL 超过字节数问题

   将utf8修改为utf8mb4

4) union与union all

union 去重

union all 不去重

 

上一篇:【转】Netty系列之Netty可靠性分析


下一篇:pflua:用Lua编写的高性能网络包过滤工具箱