Hive面试题

1. 什么是数据倾斜, 如何处理

  • 什么是数据倾斜
    大量相同的key被partition到一台机器, 造成这台机器计算任务量极大, 而其他机器计算量任务极小
  • 即使数据倾斜, UDAF函数也可能不产生效率低下的问题?
    像sum, max, min, count等UDAF不怕数据倾斜, 因为会在map端进行一次数据聚合
  • count(distinct)最受数据倾斜影响?
    因为count(distinct)要先按照group by分组, 再按distinct排序. 不会产生map端的聚合. 一般这中语句是很倾斜的;
    比如男uv,女uv,淘宝一天30亿的pv,如果按性别分组,分配2个reduce,每个reduce处理15亿数据。
  • 如何处理
    1. key上加上随机数打散, 然后最后计算结果时恢复成原来的key
    2. 过滤空值, 或者将空值变成一个字符串并加上随机前缀, 由于随机的key找不到相同的而执行失败
    3. 倾斜的key拿出来单独处理, 最后和其它结果union all在一起(不去重不排序)
    4. 开启参数hive.groupby.skewindata=true
      这会生成2个任务:
      1. 第一个任务: map的输出结果随机的分配到reduce上, 每个reduce按照key做第一次聚合
      2. 第二个任务: 将相同的key分布到同一个partition上, 再做第二次聚合
    5. count(distinct)替换成sum() group by

2. 如何调整mapper个数

mapper个数受一系列参数的影响, 最终由这些参数计算出一个表达式

  • mapred.map.tasks : map任务的期望值, 默认为2
  • default_mapper_num : 通过1个mapper处理1个block块的数据, 来计算一个mapper个数
    total_input_size : 输入文件的总大小   
    dfs.block.size : hdfs一个block块的大小  
    default_mapper_num : 为2个参数的商
    
  • splitNumber : 通过把一个block块划分多个split, 每个mapper处理一个split的方式计算mapper个数
    mapred.min.split.size : split的最小size(默认值1B)
    mapred.max.split.size : split的最大size(默认值64MB) 
    split_size = max(mapred.min.split.size, min(mapred.max.split.size, dfs.block.size));   
    
    split_num = total_input_size / split_size 
    

因此 :

  • 只有把mapred.min.split.size的值设置的比dfs.block.size大, 才能达到1个mapper读取大于1个block块的目的
  • 只有把mapred.max.split.size设置的比dfs.block.size小, 才能达到1个block块被多个mapper处理的目的 .

最终得到mapper的个数计算公式为:
mapper\_num = MIN(split\_num, MAX(default\_mapper\_num, mapred.map.tasks))
由于 mapred.max.split.size默认为64M, 所以Hive每个map任务默认处理64M的数据(1个split)

3. 如何调整reduce个数

reducer的个数, 决定了job最后生成的文件个数, 这个数可以被用户直接指定; 若没有指定, hive会通过一个公司计算出来

  • mapred.reduce.tasks : 直接指定reducer个数
  • 公式推算
    hive.exec.reducers.bytes.per.reducer : 每个reducer处理的最大数据量   
    hive.exec.reducers.max : 最大的reducer个数   
    
    最终计算得出reducer_num = MIN(total_input_size / reducers.bytes.per.reducer, reducers.max)
    

4. 什么时候需要合并文件

  • 什么时候会出现小文件
    1. 动态分区插入数据,产生大量的小文件,从而导致map数量剧增。
    2. reducer数量太多
    3. 数据源本身就包含大量的小文件
  • 输入时合并文件 : 通过控制split大小控制mapper个数
    mapred.min.split.size : split的最小size(默认值1B)
    mapred.max.split.size=256000000;  
    mapred.min.split.size.per.node=100000000 : 一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
    mapred.min.split.size.per.rack=100000000 : 执行Map前进行小文件合并(100M)
    
  • 输出合并文件控制 :
    hive.merge.mapfiles : 设置为true, 在mapped-only任务的输出进行合并
    hive.merge.mapredfiles : 设置为true, 在map-reduce任务的输出进行合并  
    
    hive.merge.size.smallfiles.avgsize : 指定输出文件的均值大小, 当输出文件小于这个值时, 开启一个任务对小文件进行合并
    

5. 什么是严格模式?

严格模式下, hive会阻止用户进行三种类型的sql与

  • 对分区表的查询, wher条件中没有指定分区列的值
  • 产生笛卡尔积的join操作
  • 使用了order by 却没有使用limit

6. 谈谈hive的优化

  • 1. mapper个数和reducer个数的优化
  • 2. 对于count(distinct) 语法的优化
    使用count() group by进行优化
    因为这个语法在mapper端group by后, 会开启mapper端聚合减少reduce端的输入量;  
    而count(distinct) 计算全都压倒reduer, 把key分散到reducer后还要在每个reducer上对key进行排序去重
    
  • 3. 对于order by 语法的优化
    order by是全局排序, 只会生成1个reducer来处理所有mapper的输出. 但是往往我们并不需要在某个字段上完全的全局有序, 而是希望局部上有序, 所以可是使用其他字段先进行distribute by,再在原字段上sort by
select uid,upload_time,event_type,record_data f
from calendar_record_log
where day_p between '20190101' and '20190131'
order by upload_time desc,event_type desc;   

-- 这个语句在数据量很大时无法计算, 可以做如下改写

select uid,upload_time,event_type,record_data
from calendar_record_log
where day_p between '20190101' and '20190131'
distribute by uid
sort by upload_time desc,event_type desc;
  • 4. 对于join语法的优化
    1. 使用map join
      当使用join时, 如果发现其中某个表很小, 可以完全放进内存的时候, 就可以将这张表指定成map join分发的表. 有2中方法指定

      1. 手动指定:
      select /*+MAPJOIN(b)*/ a.a1,a.a2,b.b2 from tablea a JOIN tableb b ON a.a1=b.b1
      

      缓存多张小表:

      select /*+MAPJOIN(b,c)*/ a.a1,a.a2,b.b2 
         from tablea a 
      JOIN tableb b 
      ON a.a1=b.b1 
      JOIN tbalec c 
      on a.a1=c.c1
      
      1. 在Hive0.11后,Hive默认启动该优化
        可以通过以下两个属性来设置该优化的触发时机
        1. hive.auto.convert.join: 默认值为true,自动开户MAPJOIN优化
        2. hive.mapjoin.smalltable.filesize: 默认值为2500000(25M), 如果表的大小小于此值就会被加载进内存中

      此外, 使用使用MAPJOIN时,需要注意:
      * LEFT OUTER JOIN的左表必须是大表;
      * RIGHT OUTER JOIN的右表必须是大表;

    2. 调整map个数和reduce个数

7. 内部表和外部表?

内部表数据由Hive自身管理,外部表数据由HDFS管理;删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除。

8. 分区表和分桶表的区别

  • 分区表: Hive 数据表可以根据某些字段进行分区操作,细化数据管理,让部分查询更快,不同分区对应不同的目录;
  • 分桶表:表和分区也可以进一步被划分为桶,分桶是相对分区进行更细粒度的划分。分桶将整个数据内容按照某列属性值的hash值进行区分,不同的桶对应不同的文件。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352