本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、压缩概述
和windows下的压缩类似,经过压缩的数据变小了,好处是其IO就会降低,读取和存储一个文件的数据量就变小了;但不可以直接使用数据,使用之前需要解压缩。
那么HDFS为什么需要压缩文件,因为集群的IO是很重要的评价标准,一般情况下,集群的IO是十分紧张的,采用压缩策略可以很大程度的缓解集群的IO压力,与之相对,当需要使用这份数据时,集群需要一份额外的操作:解压,但同时会对集群造成一部分的cpu运算负担,若运用不当,可能会降低性能。压缩的基本原则是:如果是运算密集型的job,少用压缩;对于IO密集型的job,多用压缩。IO密集型即对读写的需求很好,而运算能力要求相对不高。
hadoop最常用的压缩编码方式是Snappy,因为它的速度最快。
二、各种压缩方式对比
Gzip: linux系统自带,十分常见,缺点是不支持Split,可以用其作为输入源;
Bzip2: 速度特别慢,但是压缩率特别高,如果数据不想用,或者长时间不用,则可以使用此种压缩方式;
Lzo: 支持split,而且速度很快,比较常用的一种编码方式;
Snappy: 高速的压缩速度和合理的压缩率,不支持split,一般用在Shuffle阶段,在Shuffle阶段为了提高效率,一般使用Snappy。
三、在哪些位置使用压缩
压缩可以在MapReduce作用的任意阶段启用,在map输入端可以直接传一个压缩文件,集群可以自动识别;在Shuffle和Reduce端需要分别配置一些参数信息。
四、Yarn资源调度器
Yarn基本架构
RM和NM相互合作,共同管理集群上的所有资源(内存),默认情况下,Yarn只管理一种资源(内存),只要内存能够运行程序,就认为还有可用的资源。
NM负责管理自己一个节点的内存,所有NM管理的资源加起来,汇总到RM,就是整个集群所拥有的资源。
当client向RM提交任务时(申请资源),RM就会为job分配资源,RM会在集群中某个地方生成Container,资源以Container形式进行划分(默认1GB-8GB),用来执行AppMstr,之后AppMstr会向RM申请资源,RM向NM申请Container(两个),都完成之后会向RM进行汇报(归还资源)。
RM在container中执行AppMstr,AppMstr告诉Container运行MapTask和ReduceTask,总之,Container的生成和关闭是NM进行管理的,Container里面运行什么NM并不知晓,AppMstr是由RM启动的,AppMstr告诉Container,你去运行什么(MapTask,ReduceTask)。
Container的作用把资源调度框架和运行的程序隔离开,RM,NM只负责资源调度,通过Container容器的形式调度资源,调完资源Container里面做什么事情,是由AppMstr决定,根据提交程序的不同,有不同的AppMstr。目前提交的MapReduce程序,AppMstr全部叫做MapReduceAppMstr,如果提交spark,就会叫SparkAppMstr。
关闭集群检查虚拟内存超标的配置,只要物理内存溢出才会导致程序运行失败:
cd /opt/module/hadoop-3.1.3/etc/hadoop/
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
****xsync yarn-site.xml
重启yarn
Yarn提交任务全流程:
注意: 在这个流程中,RM和NM只负责Containe的开关,真正任务的执行推进是由AM负责的。
从客户端提交任务,会经过YarmRunner连接集群,连接成功以后,会向集群申请AM,RM返回AMID和资源的提交路径,之后客户端会向临时文件夹提交一些必要的文件,之后会向RM提交资源申请,申请AM,让AM帮我把任务完成,这个资源申请会被包装成一个Task,提交给Yarn,RM会将这个Task放到调度队列中进行调度,调度队列来决定哪些资源优先被响应,哪些资源之后响应。轮到AM执行,RM会让NM运行Container,容器里面运行AM,有了AM,任务就可以被进一步的推进了,AM会将job的资源下载到本地,来决定我使用多少资源,评估完成之后会向Yarn申请资源,资源的申请依然会被封装称为一个Task,放到调度队列中进行调度,轮到这个资源申请执行的时候,RM会让NM启动相应的Container,之后AM告诉新申请到的Container运行什么任务(MapTask),MapTask执行完成之后,生成0101二进制文件,回收Container,之后再申请资源执行ReduceTask,先申请容器之后执行ReduceTask,ReduceTask从MapTask处下载数据执行(AM会告诉ReduceTask去哪里拿数据),执行完成之后回收Container,程序执行完毕,AM会将自己的容器注销掉,到此为止,资源申请到注销的过程结束。
从Yarn的角度来说,RM不会在意Container中运行的是什么类型程序,只要NM申请资源,RM就会给予容器,至于Container内部运行什么由AM来负责。
资源调度器: 有很多程序向RM申请资源,RM通过资源调度器来决定先给谁分配资源, ****目前,Hadoop作业调度器主要有三种:FIFO、Capacity Scheduler和Fair Scheduler。Hadoop3.1.3默认的资源调度器是Capacity Scheduler。
先进先出调度器(FIFO): 先进先出,所有资源申请进入队列,按照到达时间排序,先到先服务;这种资源调度器客观来说很公平,有些时候绝对的公平更可能会造成不公平。使用的很少。
容量调度器: 如果存在一个大型的task且优先级不是很高,那么在先进先出调度其中就会被阻塞住,使得后面优先级高的任务不能够执行。容量调度器将多个FIFO调度器放在一起,紧急的任务提交到queueA,不紧急的任务提交到queueB,容量调度器中的每一个队列都可以配置所占集群资源的百分比,在某种程度上可以最大化利用集群的资源,可以并行运行很多个任务。
公平调度器: 也是一个多队列组成的调度器,每个队列也可以配置资源,优点是在一个队列中运行的所有任务都可以同时执行,比如这个队列共占20%资源,运行4个task,每个task占5%的资源。任务执行的并发度更高,理论上此种调度器希望分配所有的任务相同的资源,实际上每个任务会分配最小资源值,当小于最小资源值时,新来的任务不会被执行。拿上面的5%资源举例,实际上,每个任务并不是刚开始执行时就会获得5%的资源,而是随着时间的增加,所获得资源不断增加的这么一个过程,一开始可能只有1%,随着时间增加,其能获得5%的全部全部资源。5%称为额定容量,那么因之前资源不到位,与理想状况相差的部分称为缺额。
公平调度器的设计目标是在时间尺度上,所有作业获得公平的资源。某一时刻一个作业应获资源和实际资源的差距叫“缺额”。调度器会优先为缺额大的作业分配资源,可能会超过额定容量,这时就会产生“超额”,来弥补之前缺失的部分,有资源产生“超额”就会有资源“缺额”,正常情况下,执行完MapTask容器被回收,在以上情况中,旧容器不会被回收,给产生超额的task使用,新容器会分配给缺额大的task。如果有多个资源不满足最小资源值,会优先分配先到的任务。注意“缺额”部分的面积需要使用积分来计算。
总体来说,公平调度器是动态的公平,而非静态的公平。公平调度器可以比容量调度器更加充分的利用集群资源,一般使用容量调度器即可,如果集群比较大,一般使用公平调度器。
详细信息可以参考https://hadoop.apache.org/docs/r3.1.3/的Yarn - Fair Scheduler
配置多队列的容量调度器
使用notepad++连接远程服务器:
修改设置--首选项
点击插件--nppFTP--show nppFtpWindows--进入下图--点击齿轮--profileSettings
点击连接即可,进入/opt/module/hadoop-3.1.3/etc/hadoop/目录
将单队列变为多队列:修改此三处的值
将所有default的标签复制一份,54-142行,将复制出来的所有文件defalut改为新增队列的名字
在xshell中cat capacity-scheduler.xml查看是否配置成功
分发配置xsync capacity-scheduler.xml
在102重启yarn服务器stop-yarn.sh,start-yarn.sh
任务的推测执行
一个作业由若干个Map任务和Reduce任务构成。因硬件老化、软件Bug等,某些任务可能运行非常慢。当系统中有99%的Map任务都完成了,只有少数几个Map老是进度很慢,完不成,这时就有推测执行机制,发现拖后腿的任务,比如某个任务运行速度远慢于任务平均速度。为拖后腿任务启动一个备份任务,同时运行。谁先运行完,则采用谁的结果。
任务推测执行会产生额外的代价(会启动备份任务),好处是可能会加快任务的执行,用空间换时间。
执行推测任务的前提条件: 每个Task只会启动一个备份任务;当前Job已完成的Task必须不小于0.05(5%),开启推测执行参数设置。mapred-site.xml文件中默认是打开的。
不能启用推测执行机制情况: 任务间存在严重的负载倾斜;特殊任务,比如任务向数据库中写数据。