• Hive面试题整理(一) ---阿善有用


    Hive面试题整理(一)

    1、Hive表关联查询,如何解决数据倾斜的问题?(☆☆☆☆☆)

      1)倾斜原因:map输出数据按key Hash的分配到reduce中,由于key分布不均匀、业务数据本身的特、建表时考虑不周、等原因造成的reduce 上的数据量差异过大。
      (1)key分布不均匀;
      (2)业务数据本身的特性;
      (3)建表时考虑不周;
      (4)某些SQL语句本身就有数据倾斜;
      如何避免:对于key为空产生的数据倾斜,可以对其赋予一个随机值。
      2)解决方案
      (1)参数调节:
        hive.map.aggr = true
        hive.groupby.skewindata=true
      有数据倾斜的时候进行负载均衡,当选项设定位true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个Reduce中),最后完成最终的聚合操作。
      (2)SQL 语句调节:
      ① 选用join key分布最均匀的表作为驱动表。做好列裁剪和filter操作,以达到两表做join 的时候,数据量相对变小的效果。
      ② 大小表Join:
        使用map join让小的维度表(1000 条以下的记录条数)先进内存。在map端完成reduce。
      ③ 大表Join大表:
        把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null 值关联不上,处理后并不影响最终结果。
      ④ count distinct大量相同特殊值:
        count distinct 时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

    2、Hive的HSQL转换为MapReduce的过程?(☆☆☆☆☆)

    HiveSQL ->AST(抽象语法树) -> QB(查询块) ->OperatorTree(操作树)->优化后的操作树->mapreduce任务树->优化后的mapreduce任务树

     

     

      过程描述如下:
        SQL Parser:Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
        Semantic Analyzer:遍历AST Tree,抽象出查询的基本组成单元QueryBlock
        Logical plan:遍历QueryBlock,翻译为执行操作树OperatorTree;
        Logical plan optimizer: 逻辑层优化器进行OperatorTree变换合并不必要的ReduceSinkOperator,减少shuffle数据量;
        Physical plan:遍历OperatorTree,翻译为MapReduce任务;
        Logical plan optimizer:物理层优化器进行MapReduce任务的变换,生成最终的执行计划。

    3、Hive底层与数据库交互原理?(☆☆☆☆☆)

      由于Hive的元数据可能要面临不断地更新、修改和读取操作,所以它显然不适合使用Hadoop文件系统进行存储。目前Hive将元数据存储在RDBMS中,比如存储在MySQL、Derby中。元数据信息包括存在的表、表的列、权限和更多的其他信息。

     

    4、Hive的两张表关联,使用MapReduce怎么实现?(☆☆☆☆☆)

      如果其中有一张表为小表,直接使用map端join的方式(map端加载小表)进行聚合。
      如果两张都是大表,那么采用联合key联合key的第一个组成部分是join on中的公共字段第二部分是一个flag0代表表A,1代表表B由此让Reduce区分客户信息和订单信息;在Mapper中同时处理两张表的信息,将join on公共字段相同的数据划分到同一个分区中,进而传递到一个Reduce中,然后在Reduce中实现聚合。

    5、请谈一下Hive的特点,Hive和RDBMS有什么异同?

      hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析,但是Hive不支持实时查询。
      Hive与关系型数据库的区别:

     

    6、请说明hive中 Sort By,Order By,Cluster By,Distrbute By各代表什么意思?

      order by:会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)。只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
      sort by:不是全局排序,其在数据进入reducer前完成排序。
      distribute by:按照指定的字段对数据进行划分输出到不同的reduce中。
    cluster by:除了具有 distribute by 的功能外还兼具 sort by 的功能。

    7、写出hive中split、coalesce及collect_list函数的用法(可举例)?

      split将字符串转化为数组,即:split(‘a,b,c,d’ , ‘,’) ==> [“a”,“b”,“c”,“d”]。
      coalesce(T v1, T v2, …) 返回参数中的第一个非空值;如果所有值都为 NULL,那么返回NULL
      collect_list列出该字段所有的值,不去重 => select collect_list(id) from table。

    8、Hive有哪些方式保存元数据,各有哪些特点?

      Hive支持三种不同的元存储服务器,分别为:内嵌式元存储服务器、本地元存储服务器、远程元存储服务器,每种存储方式使用不同的配置参数。
      内嵌式元存储主要用于单元测试,在该模式下每次只有一个进程可以连接到元存储,Derby是内嵌式元存储的默认数据库。
      在本地模式下,每个Hive客户端都会打开到数据存储的连接并在该连接上请求SQL查询。
      在远程模式下,所有的Hive客户端都将打开一个到元数据服务器的连接,该服务器依次查询元数据,元数据服务器和客户端之间使用Thrift协议通信。 


    11、所有的Hive任务都会有MapReduce的执行吗?

      不是,从Hive0.10.0版本开始,对于简单的不需要聚合的类似SELECT from

    LIMIT n语句,不需要起MapReduce job,直接通过Fetch task获取数据。

     

     

    12、Hive的函数:UDF、UDAF、UDTF的区别?

      UDF:单行进入,单行输出
      UDAF:多行进入,单行输出
      UDTF:单行输入,多行输出

    13、说说对Hive桶表的理解?

      桶表是对数据进行哈希取值,然后放到不同文件中存储。
    数据加载到桶表时,会对字段取hash值然后与桶的数量取模。把数据放到对应的文件中。物理上,每个桶就是表(或分区)目录里的一个文件,一个作业产生的桶(输出文件)和reduce任务个数相同
      桶表专门用于抽样查询,是很专业性的,不是日常用来存储数据的表,需要抽样查询时,才创建和使用桶表。

    Hive面试题整理(二)

    1、Fetch抓取

      Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台。
      在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

    2、本地模式

      大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际job的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。
      用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。

    表的优化

    3、小表、大表Join

      将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率再进一步,可以使用Group让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce。
      实际测试发现:新版的hive已经对小表JOIN大表和大表JOIN小表进行了优化。小表放在左边和右边已经没有明显区别。

    4、大表Join大表

    1)空KEY过滤
      有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤例如key对应的字段为空
    2)空key转换
      有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的reducer上。

    5、Group By

      默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。
      并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合最后在Reduce端得出最终结果。
    1)开启Map端聚合参数设置
        (1)是否在Map端进行聚合,默认为True
          hive.map.aggr = true
        (2)在Map端进行聚合操作的条目数目
          hive.groupby.mapaggr.checkinterval = 100000
        (3)有数据倾斜的时候进行负载均衡(默认是false)
          hive.groupby.skewindata = true
      当选项设定为 true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。

    6、Count(Distinct) 去重统计

      数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换

    7、笛卡尔积

      尽量避免笛卡尔积,join的时候不加on条件,或者无效的on条件,Hive只能使用1个reducer来完成笛卡尔积

    8、行列过滤

      列处理:在SELECT中,只拿需要的列,如果有,尽量使用分区过滤,少用SELECT *
      行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤。

    数据倾斜

    9、 Map数

    1)通常情况下,作业会通过input的目录产生一个或者多个map任务。
      主要的决定因素有:input的文件总个数,input的文件大小,集群设置的文件块大小。
    2)是不是map数越多越好?
      答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。
    3)是不是保证每个map处理接近128m的文件块,就高枕无忧了?
      答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。
      针对上面的问题2和3,我们需要采取两种方式来解决:即减少map数和增加map数;

    10、小文件进行合并

      在map执行前合并小文件,减少map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能。
      set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

    11、复杂文件增加Map数

      当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。
      增加map的方法为:根据computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M公式,调整maxSize最大值。让maxSize最大值低于blocksize可以增加map的个数。

    12、Reduce数

    1)调整reduce个数方法一
      (1)每个Reduce处理的数据量默认是256MB
        hive.exec.reducers.bytes.per.reducer=256000000
      (2)每个任务最大的reduce数,默认为1009
        hive.exec.reducers.max=1009
      (3)计算reducer数的公式
        N=min(参数2,总输入数据量/参数1)
    2)调整reduce个数方法二
      在hadoop的mapred-default.xml文件中修改
      设置每个job的Reduce个数
      set mapreduce.job.reduces = 15;
    3)reduce个数并不是越多越好
      (1)过多的启动和初始化reduce也会消耗时间和资源;
      (2)另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;
      在设置reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的reduce数;使单个reduce任务处理数据量大小要合适。

    **==========================**

    13、并行执行

      Hive会将一个查询转化成一个或者多个阶段。这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能需要的其他阶段。默认情况下,Hive一次只会执行一个阶段。不过,某个特定的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整个job的执行时间缩短。不过,如果有更多的阶段可以并行执行,那么job可能就越快完成。
      通过设置参数hive.exec.parallel值为true,就可以开启并发执行。不过,在共享集群中,需要注意下,如果job中并行阶段增多,那么集群利用率就会增加。

  • 相关阅读:
    排序
    分治算法-二分查找
    分治算法-归并排序
    MySQL触发器-条件触发器语法
    Hadoop MapReduce例子-新版API多表连接Join之模仿订单配货
    Leetcode-169 Majority Element
    Leetcode-122 Best Time to Buy and Sell Stock II
    Leetcode-204 Count Primes
    Leetcode-121 Best Time to Buy and Sell Stock
    Leetcode-104 Maximum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/shan13936/p/13841582.html
Copyright © 2020-2023  润新知