Hadoop阶段面试题
HDFS
MapReduce
1.介绍一下 MR 的工作原理
MapTask的工作机制
read:通过RecordReader
,从输入的InputSplit
中解析出一个个kv
假设待处理文件/user/input/ss.txt为200m(hadoop默认切片与分块大小为128M)
切片大小实现:
computeSplitSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M
客户端在提交submit前现获取待处理数据的信息,然后根据参数配置,形成一个切片的规划0-128M,128-200M两个切片。
客户端向Yarn的ResourceManager提交提交job任务,向HDFS提交需要处理的数据。提交的信息包括任务的划分(Job.split,Job.xml)文件和待执行MR程序的jar包。
ResouceManager
收到客户端提交的任务后,启动一个AppMastr
进程到HDFS
下载客户端上传的切片文件信息
所需要的创建的MapTask
个数,然后向RM申请资源,在container
容器运行任务默认使用TextInputFormat的LineRecordReader方法读取文件,将解析的kv交给map处理
map:将解析的kv交给map
方法,做业务逻辑,输出新的kv
处理完传给context.write上下文的输出方法
数据传入环形缓冲区进入shuffle阶段
进入shuffle阶段
collect:OutputCollector.collect()
函数内部实现分区,并写入一个环形缓冲区
环形缓冲区默认是100M,当数据到了80M时开始用Lock锁锁住这一部分,在init方法设置了分区和排序算法,实现对分区内排序。
Spill溢写:当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作。
利用快速排序算法对缓存区数据排序,排序需要实现
WritableComprater
接口只对分区内进行排序,同一分区对key进行排序
按照分区编号由小到大一次将每个分区中的数据写入任务工作目录的临时文件
output/spilN.out(N表示当前溢写的次数)
中。如果重写了Combiner类(继承Reducer类实现,map阶段的分区聚合),则写入文件之前,会对每个分区中的数据进行一次聚合操作操作。将分区数据的元数据信息写到内存的索引数据结构
SpillRecord
中,其中每个分区的元信息包括在临时文件中的偏移量、压缩前数据大小和压缩后数据大小。如果当前内存索引大小超过1MB,则将内存索引写到文件output/spillN.out.index
中。
combine:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。
当所有数据处理完后,MapTask会将所有临时文件合并成一个大文件,并保存到文件output/file.out中,同时生成相应的索引文件output/file.out.index。
在进行文件合并过程中,MapTask以分区为单位进行合并。对于某个分区,它将采用多轮递归合并的方式。每轮合并io.sort.factor(默认10)个文件,并将产生的文件重新加入待合并列表中,对文件排序后,重复以上过程,直到最终得到一个大文件。
让每个MapTask最终只生成一个数据文件,可避免同时打开大量文件和同时读取大量小文件产生的随机读取带来的开销。
ReduceTask的工作机制
copy:每个ReduceTask
从各个MapTask输出的文件
拷贝一份所分配的分区的数据到内存,如果内存中的分区数据量大于mapreduce.reduce.shuffle.merge.percent
设置的值,则溢写到磁盘
merge:拷贝数据的同时,开启两个线程对内存和磁盘上的文件进行合并,防止内存或磁盘使用过多
sort:对合并的文件进行归并排序
reduce:用户自己实现业务逻辑,将计算结果写到hdfs
2.MapTask和ReduceTask并行度决定机制
MapTask并行度如何确定?
- 数据块:Block是HDFS物理上把数据分成一块一块。
- 数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。
hadoop数据切片大小默认与hdfs块大小相同为128M,避免MR程序读取数据时,出现跨节点读取。
ReduceTask并行度如何确定?
-
可以直接在代码里设置,也可以在配置文件中设置默认值。
-
ReduceTask不应该小于分区的个数
-
设置为0表示输出文件数等于MapTask个数
-
需要全局汇总则可能需要只设置一个reduce
-
16个works节点 8GHZ 2G 1G的数据 MapTask16个
3.mapreduce为什么不适合实时数据处理?
-
MR处理的是储存在磁盘的数据,并且会将计算中间的结果持久化到磁盘,而不是内存中
-
MR任务调度开销大,MR是并行的并且是为离线批处理设计的,组成的作业每个任务其运行时间长达数分钟之久,极端情况下延时非常高
hadoop使用周期心跳消息向工作节点分配任务,这个周期默认为3s,延时一般会有5-10s,对于即席查询是不够的
-
主要用于静态数据(死数据)的计算,无法适应流式计算
-
难以进行DAG(有向图)的串行计算
Yarn
1.yarn组成架构
主要由RecourceManager、NodeManager、ApplicationMaster、container组成
-
RM:
负责处理client端请求,对各个NM资源和管理调度,给AppMastr分配空闲的container并监控运行状况。主要由
调度器
和应用程序管理器
构成调度器只负责分配资源,不负责监控程序的状态
程序管理器管理yarn上运行的所有程序,包括
提交
、向调度器申请资源
、启动监控和重启AppMastr
-
NM:
是每个节点的资源任务管理器,会定时向RM发送节点资源和container的情况。以及接收AppMastr和container的启动停止请求。
-
AppMastr:
用户提交的一个任务都包含一个
AppMastr
,负责应用的监控和跟踪状态、重启失败任务
。 -
Container:
虚拟的的资源容器,包含某节点的多维度资源,如内存,cpu,磁盘,网络等。AppMastr向NM申请资源时,返回的就是container容器。
2.yarn工作流
yarn的调度器及工作原理
-
FIFO Scheduler
- 按任务提交顺序执行的队列,先进先出。不适合多任务共享资源的集群。如果当前是较大的任务会占据较多的资源,导致后面的任务阻塞等待。
-
Capacity Scheduler(容器调度)
- **层次化设计:**子队列可以使用父队列全部资源。
- **容量保证:**适合多组织共享一个大集群的资源,可以为每个组织分配专属的队列
- **安全性:**可以设置访问权限,每个组织只能向自己队列里提交任务。
- **弹性分配:**空闲资源可以分配给其他队列。资源争抢时,会按照比例分配
- **多用户使用:**每个队列内部还能垂直划分,这样同组织的多个成员就能共享队列资源,每个队列会对同一用户提交的任务资源进行限制,防止单用户占大量资源的情况
- **可操作性:**支持动态修改容量、权限的分配,可以在运行时直接修改。可以添加队列和暂停队列,如果队列被设置成stopped就不能提交任务。
- ??如果是并行需求,没有指定队列,调度器会计算队列队列所有资源 / 任务数,找到最闲的队列放入任务**?**
-
Fair Scheduler(公平调度)
实际上就是对容器调度的平均化资源分配
Fair Scheduler将整个Yarn的可用资源划分成多个资源池,每个资源池中可以配置最小和最大的可用资源(内存和CPU)、最大可同时运行Application数量、权重、以及可以提交和管理Application的用户等。
(1)根据用户名来分配资源池
(2)根据权重获得额外的空闲资源
在每个资源池的配置项中,有个weight属性(默认为1),标记了资源池的权重,当资源池中有任务等待,并且集群中有空闲资源时候,每个资源池可以根据权重获得不同比例的集群空闲资源
(3)最小资源保证
在每个资源池中,允许配置该资源池的最小资源,这是为了防止把空闲资源共享出去还未回收的时候,该资源池有任务需要运行时候的资源保证
(4)动态更新资源配额
Fair Scheduler除了需要在yarn-site.xml文件中启用和配置之外,还需要capacity-scheduler.xml
文件来配置资源池以及配额,而该XML中每个资源池的配额可以动态更新,之后使用命令:yarn rmadmin –refreshQueues
来使得其生效即可,不用重启Yarn集群最大最小公平调度算法分有权重和无权重的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ZTDQuIu-1618730499000)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20210418131716587.png)]