【最新】2021 年 Hive 阶段最全面试真题 - 附答案
1、你处理过的最大的数据量?你是如何处理他们的?处理的结果。
1000 万条数据(10G);为了加快解析速度,使用 redis 作为缓存,MR 运行只与 redis 交互,解析完成后统一在 hbase 中持久化存储.
2、在处理大数据过程中,如何保证得到期望值?
对数据进行清洗,过滤和排序以达到期望值
3、如何让一个网络爬虫速度更快、抽取更好的信息以及更好总结数据从而得到一干净的数据库?
多个账号,多窗口操作;定向抽取数据需求数据
4、点击流数据应该是实时处理?为什么?哪部分应该实时处理?
点击流数据是用户浏览网站持续轨迹,是持续的行为(数据具有时效性?);
访问,浏览,点击行为应该实时处理
购物车,足迹,评论,收藏,订单数据采集到 kafka 后进行实时处理.
5、你最喜欢的编程语言是什么?为什么?
我认为编程语言是程序员得基本功,不论是 java,scala 还是 sql,只有熟练掌握才能够写出简洁高效的代码.
6、如何把非结构化的数据转换成结构化的数据?这是否真的有必要做这样的转换?把数据存成平面文本文件是否比存成关系数据库更好?
对源数据设置统一的切割符,清洗冗余数据,无效数据;
源数据没有结构化,不会直接应用使用,不利于分析,容易导致数据倾斜,转换后的数据便于后期的使用和开发;
文本文件不利于管理和维护,并且文件会占用存储空间
7、如何判别 mapreduce 过程有好的负载均衡?什么是负载均衡?
当有大文件或大量数据的时候,就会体现出 mapreduce 的负载均衡,其中 mapreduce 核心 shuffle 过程实现的负载均衡;
扩展网络设备和服务器的带宽,增加吞吐量,加强网络数据处理能力,增加网络的灵活性和可用性.
(这里可以通过 MR 的 shuffle,阐述 spark 的 shuffle,做一个对比,然后怎样调优)
8、Spark 和 Hive 的区别,以及 Spark 和 Hive 的数据倾斜调优问题?
区别:
spark 拥有 mapreduce 所具备的优点,但不同于 mapreduce 的是 job 中间输出结果保存在内存中,从而不再读写 hdfs.
hive 是基于 Hadoop 的工具,提供 sql 语句运行 mapreduce,核心为 mapreduce 处理数据,需要进行频繁的 io 操作.
hive 数据倾斜:
参数调节:
进行负载均衡
sql 语句调节:
选用 join key 分布最均匀的表作为驱动表.
使用 map join 让小的维度表先进内存.在 map 端完成 reduce
把空值加上随机数,把倾斜的数据分到不同的 reduce 上,null 值不影响最终的处理结果
countdistinct 大量相同特殊值:将值为空的单独处理,相同的不用处理直接过率,在最后结果中加 1;
还有其它计算,需要进行 group by,可以先将值为空的记录单独处理,在和其它计算结果进行 union]
spark 数据倾斜:
数据倾斜是由于少数 task 执行时间过长导致的,shuffle 过程出现此问题
distinct,groupByKey,reduceByKey,aggregateByKey,join,cogroup,repartition
数据倾斜原因:
key 本身分布不均匀
key 的设置不合理,(我之前公司的 key 是怎么设计的)
如果是其它情况具体情况具体分析
如果是业务导致的数据正常分布
spark 下:
spark 时的并发度不够
计算方式有误
解决:key 分布问题则清除无效的 key
如果是有效数据正常分布
隔离执行,将异常的 key 过滤出来单独处理,最后与正常数据的处理结果进行 union 操作
将 task 过多的 key 添加随机值,进行操作,去掉随机值,在进行操作
shuffle 问题,sparksql 和 dataframe 可以设置增加 shuffle 并行度;使用 map join 代替 reduce join
9、Hive 和 Hbase 的区别?
共同点:hbase 与 hive 都是架构在 Hadoop 上,都是用 hadoop 作为底层存储.
区别:
hive 是建立在 hadoop 上为了减少 mapreduce job 编写工作的批处理系统,HBase 是支持 hadoop 的实时操作的缺陷;
当操作 RMDB 数据库,如果是全表扫描,就用 Hive+hadoop,如果是索引访问采用 Hbase+hadoop;
hivequery mapreduce 从 5 分钟到数小时,hbase 是非常高效的,比 hive 快;
Hive 本身不存储数据和计算数据,完全依赖 HDFS 和 mapreduce,借用 mapreduce 完成命令执行,hive 表纯逻辑
hbase 是物理表,列存储,非逻辑表,提供大内存 hash 表,搜索引擎通过它来存储索引,方便查询操作.
hdfs 作为底层存储,是存放文件的系统,而 Hbase 负责组织文件.
hive 需要用到 hdfs 存储文件,需要用到 Mapreduce 计算框架.
10、MapReduce 的思想,以及 MapReduce 调优问题?
mapReduce 是一个分布式运算程序的编程框架,分而治之的思想,(阐述 mapreduce 的整个流程),
配置 mapred-site.xml 参数
默认开启的 reduce 数量,多台机器分担一台机器的压力,增加数量
环形缓冲区所占内存大小默认 100M,增加到 200M
环形缓冲区的阀值
ReduceTask 中合并小文件时,增加一次合并的文件数据
map 输出是否进行压缩,如果压缩就会多耗 cpu,但是减少传输时间,如果不压缩,就需要较多的传输带宽。
设置 http 传输的的并行数
以下的主要思想就是增加内存:
Map 阶段,增加 map 端的内存分配
增加 Map 端启用 JVM 所占用的内存
增加 reduce 阶段,reduce 端的内存分配
增加 reduce 端启用 JVM 所占用的内存
shuffle 调优:
调整缓冲区的大小,将缓冲区调大.
阈值降低到 60%,80%会刷磁盘浪费 io,达到减少 io 的效果
11、谈谈数据倾斜,它如何发生的,并给出优化方案!
首先谈一下什么是数据倾斜? 答:map /reduce 程序执行时,reduce 节点大部分执行完毕,但是有一个或者几个 reduce 节点运行很慢,导致整个程序的处理时间很长。现象是: 进度长时间维持在 99%(或 100%),查看任务监控页面,发现只有少量(1 个或几个)reduce 子任务未完成;查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过 10GB 可以认定为发生数据倾斜。
如何发生的?数据的倾斜主要是两个的数据相差的数量不在一个级别上 ,这是因为某一个 key 的条数比其他 key 多很多(有时是百倍或者千倍之多),这条 key 所在的 reduce 节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。
优化方案 :
方式一 :reduce 本身的计算需要以合适的内存作为支持,在硬件环境容许的情况下,增加 reduce 的 JVM 内存大小显然有改善数据倾斜的可能,这种方式尤其适合数据分布第一种情况,单个值有大量记录, 这种值的所有纪录已经超过了分配给 reduce 的内存,无论你怎么样分区这种情况都不会改变. 当然这种情况的限制也非常明显, 1.内存的限制存在,2.可能会对集群其他任务的运行产生不稳定的影响。
方式二 : 这个对于数据分布第二种情况有效,情况(一值较多,单个唯一值的记录数不会超过分配给 reduce 的内存). 如果发生了偶尔的数据倾斜情况,增加 reduce 个数可以缓解偶然情况下的某些 reduce 不小心分配了多个较多记录数的情况. 但是对于第一种数据分布无效。
方式三: 一种情况是某个领域知识告诉你数据分布的显著类型,比如<<hadoop 权威指南>> 里面的温度问题,一个固定的组合(观测站点的位置和温度) 的分布是固定的,对于特定的查询如果前面两种方式都没用,实现自己的 partitioner 也许是一个好的方式。
总结 : 数据倾斜没有一劳永逸的方式可以解决,了解你的数据集的分布情况,然后了解你所使用计算框架的运行机制和瓶颈,针对特定的情况做特定的优化,做多种尝试,观察是否有效。
12 、datanode 首次加入 cluster 的时候,如果 log 报告不兼容文件版本,那需要 namenode 执行格式化操作,这样处理的原因是?(可以当成工作中遇到的问题!) 这样处理是不合理的,因为那么 namenode 格式化操作,是对文件系统进行格式化,namenode 格式化时清空 dfs/name 下空两个目录下的所有文件,之后,会在目录 dfs.name.dir 下创建文件。文本不兼容,有可能时 namenode 与 datanode 的 数据里的 namespaceID、clusterID 不一致,找到两个 ID 位置,修改为一样即可解决。
13、简述 HDFS 数据存储机制?
HDFS 是解决海量数据存储问题的存储系统。具有高可靠,读写效率高等特点。通过将大文件拆分成一个一个 block 块,Hadoop2.x 默认是 128M,分布式的存储到各个 DataNode 节点中并且备份,通过横向扩展解决了纵向扩展的问题,大大提升了读写的效率和降低了成本。同时,通过设置 NameNode 主节点来记录每个 block 的元数据信息,包括块名,所在 DataNode 节点,备份所在位置,大小等等信息,实现文件的高可靠存储和高效率读取。而且在 Hadoop2.0 以上版本,通过 HA 解决了 NameNode 的单点故障问题,使得 HDFS 更为可靠。
14、 如何实现小文件的合并?
先将这些小文件保存到本地的一个路径中同一个文件中,通过 shell 脚本,可以设置这个新文件达到多大再上传,一般设置为 128M,上传到 HDFS 中,这样就实现了小文件上传之前的合并。还有,一般当天的日志和数据都存在一个 HDFS 路径中,如果没有达到上传大小,可以设置每天凌晨对前一天的本地文件路径的扫描,如果发现有文件,不管多大,都上传到前一天的 HDFS 文件目录下。
15、 Hadoop 的 Shuffer 过程
map ----> partition(分区默认,可修改) ----> sort(排序默认,可修改) -----> combiner(map 阶段排序,可选) -----> spill (溢写,默认不可改) -----> meger(合并文件,默认,不可改) -----> compress(压缩,可选) -----> Copy 阶段----->Merge 阶段----->Sort 阶段。这是整个 MapReduce 阶段, 而 Map 产生输出开始到 Reduce 取得数据作为输入之前的过程称 shuffle 阶段
1 . Collect 阶段 : 将 MapTask 的结果输出到默认大小为 100M 的环形缓冲区 . 保存的是 key/value ,Partition 分区信息等。
2 . Spill 阶段 : 当内存中的数据量达到一定的阈值的时候,就会将数据写入到本地磁盘 , 在将数据写入到磁盘之前需要对数据进行一次排序的操作。如果配置了 combiner,还会将相同分区号和 key 的数据进行排序。
3 . Merge 阶段 : 把所有的溢出的临时文件进行一次合并操作 , 以确保一个 MapTask 最终只产生一个中间数据文件。
4 . Copy 阶段 : ReduceTask 启动 Fetcher 线程到已经完成 MapTask 的节点上复制一份属于自己的数据 , 这些数据默认会保存到内存的缓冲区中 , 当内存的缓冲区达到一定的阈值的时候,就会将数据写到磁盘之上
5 . 在 reduceTask 远程复制数据的同时 , 会在后台开启两个线程对内存到本地的数据文件进行合并操作
6 . Sort 阶段 : 在对数据进行合并的同时 , 会进行排序操作 , 由于 MapTask 阶段已经对数据进行了局部的排序 , ReduceTask 只需要保证 Copy 的数据最终整体有效性即可。
Shuffer 中的缓冲区大小会影响到 MapReduce 程序的执行效率 , 原则上说 , 缓冲区越大 , 磁盘 IO 的次数越少,执行速度越快.
16、两个文件合并的问题
给定 a、b 两个文件,各存放 50 亿个 url,每个 url 各占用 64 字节,内存限制是 4G,如何找出 a、b 文件共同的 url?主要的思想是把文件分开进行计算,在对每个文件进行对比,得出相同的 URL,因为以上说是含有相同的 URL 所以不用考虑数据倾斜的问题。详细的解题思路为:可以估计每个文件的大小为 5G*64=300G,远大于 4G。所以不可能将其完全加载到内存中处理。考虑采取分而治之的方法。
遍历文件 a,对每个 url 求取 hash(url)%1000,然后根据所得值将 url 分别存储到 1000 个小文件(设为 a0,a1,...a999)当中。这样每个小文件的大小约为 300M。遍历文件 b,采取和 a 相同的方法将 url 分别存储到 1000 个小文件(b0,b1....b999)中。这样处理后,所有可能相同的 url 都在对应的小文件(a0 vs b0, a1 vs b1....a999 vsb999)当中,不对应的小文件(比如 a0 vs b99)不可能有相同的 url。然后我们只要求出 1000 对小文件中相同的 url 即可。 比如对于 a0 vs b0,我们可以遍历 a0,将其中的 url 存储到 hash_map 当中。然后遍历 b0,如果 url 在 hash_map 中,则说明此 url 在 a 和 b 中同时存在,保存到文件中即可。
如果分成的小文件不均匀,导致有些小文件太大(比如大于 2G),可以考虑将这些太大的小文件再按类似的方法分成小小文件即可。
17、当场 java 或者 scala 手写 word count。(会一种)
18、 YARN 的调度策略
FIFO: 先进先出. 小任务会被大任务阻塞
· Capacity: 容量调度器(默认).
按照你的队列的形式!给不同的队列划分不同的百分比,当然如果一个队列空闲!那么另外一个队列就会不断的“吞噬”剩下的资源直至达到(自己设定的最大“吞噬”量的百分比),如果这个时候被吞噬的资源又开始忙的话!那么就会释放资源!最终达到自己设定的那个动态的平衡点!
例子 :
Root
队列一 : prod 40% 剩余 25%
队列二 :env 60% 剩余 75%
队列二的子队列 : mapreduce 50%
队列二的子队列 : spark 50%
动态平衡点 : 队列一:40% 队列二占 60% 当队列一空闲 或者队列二空闲的时候 , 另外一个不空闲的队列最多吞噬到 75% 。
而队列二的子队列 的 50%+50% 等于队列二的 60%
· FAIR: 公平调度器
当第一个任务提交的时候,假如只有这一个任务,就会把集群所有资源给这一个任务。第二个任务提交的时候,RM 会分配给一半的资源给第二个任务。但是第二个任务从提交到执行会有一定的延迟,需要等待第一个任务释放了 container 容器。但有个好处就是,能够充分的让每一个任务利用集群的资源
· 默认调度器是 Capacity
· 1、容量调度器
· Vi yarn-site.xml 中配置
· <property>
· <name>yarn.resourcemanager.scheduler.class</name>
· <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
· </property>
· 然后在/etc/hadoop/capacity-scheduler.xml 中配置容量调度器的参数
· 1、
· Name:yarn.scheduler.capacity.maximum-applications
· Value:10000
· 集群或者队列中(all)同时处于等待和运行状态的应用程序数目上限,这是一个强限制,一旦集群中应用程序数目超过该上限,后续提交的应用程序将被拒绝,默认值为 10000
· 2、
· Name:yarn.scheduler.capacity.maximum-am-resource-percent
· Value:0.1
· 集群中可用于运行 application master 的资源比例上限,这通常用于限制并发运行的应用程序数目
· 3、
· Name:yarn.scheduler.capacity.resource-calculator
· Value:org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator
· 资源调度器 resourceManager 在做计算的时候,会考虑资源的调度。默认的方式只考虑到内存。如果使用 DominantResourceCalculator 则进行多维度比较:CPU,内存等
· 4、
· Name:yarn.scheduler.capacity.root.queues
· Value:default 或者 Q1,Q2,Q3(以,分割)
· 用来指定队列的。容量调度器预先给 root 开启了一个队列,如果是默认的话,就表示只有一个队列。可以指定当前 root 下有那些队列的,不指定就一个
· 5、
· Name:yarn.scheduler.capacity.root.default.capacity
· Value:100
· 指定默认队列的容量
· 如果要制定其他队列容量的话只需要:
· Name:yarn.scheduler.capacity.root.Q1.capacity
· Value:100
· 6、
· Name:yarn.scheduler.capacity.root.default.user-limit-factor
· Value:1
· 每个队列可使用的资源的限制
· 7、
· Name:yarn.scheduler.capacity.root.default.maximum-capacity
· Value:100
· Default 队列可使用的资源上限.
19、MR 相关的调优(结合自己的项目场景,记住三四个)
主要使用的硬件 :CPU+memory 如果当前进程是进行存储的 , 对 CPU 和内存要求并不是很高。如果当前进程是进行计算的,那么对 CPU 和 memory 的要求都是很高的 硬件的主要配置有:memory 当 CPU 不够的话:程序执行运算会慢一点,当内存不够的:会导致 heap 溢出,GC。因为在内存不够的时候,Yarn 里面有一个动态的线程就会检测到,然后就给你杀死了
20、hive 是怎样保存元数据的
保存元数据的方式有:内存数据库 Derby,特点 : 保存数据小,不稳定。本地MySQL数据库, 特点 :储存方式可以自己设定,持久化好,一般企业开发都用 mysql 做支撑。远程 mysql 数据库,但是本地的 mysql 数据用的比较多,因为本地读写速度都比较快。内置数据库不使用!
21、什么是 Hive 的内部表和外部表?
未被 external 修饰的是内部表,被 external 修饰的是外部表。内部表数据由 Hive 自身管理,外部表数据由 HDFS 管理。内部表数据存储的位置是 warehouse 的路径,外部表数据的存储文职由自己指定。删除内部表会直接删除元数据以及存储的数据,删除外部表仅仅会删除元数据,HDFS 上的文件并不会被删除。对内部表的修改会将修改直接同步给元数据,对外部表的表结构和分区进行修改的话,则需要修复:MSCK REPAIR TABLE 表名
22、Hive 的 sort by 和 order by 的区别
order by 会对输入做全局排序,因此只有一个 reducer(多个 reducer 无法保证全局有序)只有一个 reducer,会导致当输入规模较大时,需要较长的计算时间。
sort by 不是全局排序,其在数据进入 reducer 前完成排序.
因此,如果用 sort by 进行排序,并且设置 mapred.reduce.tasks>1, 则 sortby 只保证每个 reducer 的输出有序,不保证全局有序。
版权声明: 本文为 InfoQ 作者【大数据技术指南】的原创文章。
原文链接:【http://xie.infoq.cn/article/22f47d2f15aa99335c17b1527】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论