续上一篇
四、Hadoop数据压缩
1、概述
压缩技术能够有效减少底层存储系统(HDFS)读写字节数。压缩提高了网络带宽和磁盘空间的效率。在Hadoop下,尤其是数据规模很大和工作负载密集的情况下,使用数据压缩显得非常重要。在这种情况下,I/O操作和网络数据传输要花大量的时间。还有,Shuffle与Merge过程同样也面临着巨大的I/O压力。
鉴于磁盘I/O和网络带宽是Hadoop的宝贵资源,数据压缩对于节省资源、最小化磁盘I/O和网络传输非常有帮助。不过,尽管压缩与解压操作的CPU开销不高,其性能的提升和资源的节省并非没有代价。
如果磁盘I/O和网络带宽影响了MapReduce作业性能,在任意MapReduce阶段启用压缩都可以改善端到端处理时间并减少I/O和网络流量。
压缩Mapreduce的一种优化策略:通过压缩编码对Mapper或者Reducer的输出进行压缩,以减少磁盘IO,提高MR程序运行速度(但相应增加了cpu运算负担)。
注意:压缩特性运用得当能提高性能,但运用不当也可能降低性能。
基本原则:
(1)运算密集型的job,少用压缩
(2)IO密集型的job,多用压缩
2、MR支持的压缩编码
为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器,如下表所示
压缩性能的比较
参考:http://google.github.io/snappy/
On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.
压缩方式选择
3、Gzip压缩
优点:压缩率比较高,而且压缩/解压速度也比较快;hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样;大部分linux系统都自带gzip命令,使用方便。
缺点:不支持split。
应用场景:当每个文件压缩之后在130M以内的(1个块大小内),都可以考虑用gzip压缩格式。例如说一天或者一个小时的日志压缩成一个gzip文件,运行mapreduce程序的时候通过多个gzip文件达到并发。hive程序,streaming程序,和java写的mapreduce程序完全和文本处理一样,压缩之后原来的程序不需要做任何修改。
4、Bzip2压缩
优点:支持split;具有很高的压缩率,比gzip压缩率都高;hadoop本身支持,但不支持native(java和c互操作的API接口);在linux系统下自带bzip2命令,使用方便。
缺点:压缩/解压速度慢;不支持native。
应用场景:适合对速度要求不高,但需要较高的压缩率的时候,可以作为mapreduce作业的输出格式;或者输出之后的数据比较大,处理之后的数据需要压缩存档减少磁盘空间并且以后数据用得比较少的情况;或者对单个很大的文本文件想压缩减少存储空间,同时又需要支持split,而且兼容之前的应用程序(即应用程序不需要修改)的情况。
5、Lzo压缩
优点:压缩/解压速度也比较快,合理的压缩率;支持split,是hadoop中最流行的压缩格式;可以在linux系统下安装lzop命令,使用方便。
缺点:压缩率比gzip要低一些;hadoop本身不支持,需要安装;在应用中对lzo格式的文件需要做一些特殊处理(为了支持split需要建索引,还需要指定inputformat为lzo格式)。
应用场景:一个很大的文本文件,压缩之后还大于200M以上的可以考虑,而且单个文件越大,lzo优点越越明显。
6、Snappy压缩
优点:高速压缩速度和合理的压缩率。
缺点:不支持split;压缩率比gzip要低;hadoop本身不支持,需要安装;
应用场景:当Mapreduce作业的Map输出的数据比较大的时候,作为Map到Reduce的中间数据的压缩格式;或者作为一个Mapreduce作业的输出和另外一个Mapreduce作业的输入。
7、压缩位置选择
压缩可以在MapReduce作用的任意阶段启用。
8、压缩配置参数
要在Hadoop中启用压缩,可以配置如下参数:
五、Yarn
1、Hadoop1.x和Hadoop2.x架构区别
在Hadoop1.x时代,Hadoop中的MapReduce同时处理业务逻辑运算和资源的调度,耦合性较大。
在Hadoop2.x时代,增加了Yarn。Yarn只负责资源的调度,MapReduce只负责运算
2、Yarn概述
Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而MapReduce等运算程序则相当于运行于操作系统之上的应用程序。
3、Yarn基本架构
YARN主要由ResourceManager、NodeManager、ApplicationMaster和Container等组件构成。
4、Yarn工作机制
5、名词解释:
资源:在 YARN 的语境下,资源特指计算资源,包括 CPU 和内存。计算机的每个进程都会占用一定的 CPU 和内存,任务需要先向 RM 申请到资源后才能获准在 NM 上启动自己的进程。
队列:YARN 将整个集群的资源划分为队列,每个用户的任务必须提交到指定队列。同时限制每个队列的大小,防止某个用户的任务占用整个集群,影响了其他用户的使用。
Vcore & Mem:逻辑 CPU 和逻辑内存,每个 NM 会向 RM 汇报自己有多少 vcore 和内存可用,具体数值由集群管理员配置。比如一台48核,128G内存的机器,可以配置40vcore,120G内存,意为可以对外提供这么多资源。具体数值可能根据实际情况有所调整。每个 NM 的逻辑资源加起来,就是整个集群的总资源量。
MinResources & MaxResources:为了使每个队列都能得到一定的资源,同时又不浪费集群的空闲资源,队列的资源设置都是“弹性”的。每个队列都有 min 和 max 两个资源值,min 表示只要需求能达到,集群一定会提供这么多资源;如果资源需求超过了 min 值而同时集群仍有空闲资源,则仍然可以满足;但又限制了资源不能无限申请以免影响其他任务,资源的分配不会超过 max 值。
Container:任务申请到资源后在 NM 上启动的进程统称 Container。比如在 MapReduce 中可以是 Mapper 或 Reducer,在 Spark 中可以是 Driver 或 Executor。
6、工作机制简化版
用户使用客户端向 RM 提交一个任务job,同时指定提交到哪个队列和需要多少资源。用户可以通过每个计算引擎的对应参数设置,如果没有特别指定,则使用默认设置。
RM 在收到任务提交的请求后,先根据资源和队列是否满足要求选择一个 NM,通知它启动一个特殊的 container,称为 ApplicationMaster(AM),后续流程由它发起。
AM 向 RM 注册后根据自己任务的需要,向 RM 申请 container,包括数量、所需资源量、所在位置等因素。
如果队列有足够资源,RM 会将 container 分配给有足够剩余资源的 NM,由 AM 通知 NM 启动 container。
container 启动后执行具体的任务,处理分给自己的数据。NM 除了负责启动 container,还负责监控它的资源使用状况以及是否失败退出等工作,如果 container 实际使用的内存超过申请时指定的内存,会将其杀死,保证其他 container 能正常运行。
各个 container 向 AM 汇报自己的进度,都完成后,AM 向 RM 注销任务并退出,RM 通知 NM 杀死对应的 container,任务结束。
container设置多少资源合适?
如果 container 内存设置得过低,而实际使用的内存较多,则可能会被 YARN 在运行过程中杀死,无法正常运行。而如果 container 内部线程并发数较多而 vcore 设置的较少,则可能会被分配到一个 load 已经比较高的机器上,导致运行缓慢。所以需要预估单个 container 处理的数据量对应的内存,同时 vcore 数设置的不应该比并发线程数低。
7、Yarn复杂运行机制
2)工作机制详解
(0)Mr程序提交到客户端所在的节点。
(1)Yarnrunner向Resourcemanager申请一个Application。
(2)rm将该应用程序的资源路径返回给yarnrunner。
(3)该程序将运行所需资源提交到HDFS上。
(4)程序资源提交完毕后,申请运行mrAppMaster。
(5)RM将用户的请求初始化成一个task。
(6)其中一个NodeManager领取到task任务。
(7)该NodeManager创建容器Container,并产生MRAppmaster。
(8)Container从HDFS上拷贝资源到本地。
(9)MRAppmaster向RM 申请运行maptask资源。
(10)RM将运行maptask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。
(11)MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动maptask,maptask对数据分区排序。
(12)MrAppMaster等待所有maptask运行完毕后,向RM申请容器,运行reduce task。
(13)reduce task向maptask获取相应分区的数据。
(14)程序运行完毕后,MR会向RM申请注销自己。
8、作业提交全过程
作业提交全过程详解
(1)作业提交
第0步:client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。
第1步:client向RM申请一个作业id。
第2步:RM给client返回该job资源的提交路径和作业id。
第3步:client提交jar包、切片信息和配置文件到指定的资源提交路径。
第4步:client提交完资源后,向RM申请运行MrAppMaster。
(2)作业初始化
第5步:当RM收到client的请求后,将该job添加到容量调度器中。
第6步:某一个空闲的NM领取到该job。
第7步:该NM创建Container,并产生MRAppmaster。
第8步:下载client提交的资源到本地。
(3)任务分配
第9步:MrAppMaster向RM申请运行多个maptask任务资源。
第10步:RM将运行maptask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。
(4)任务运行
第11步:MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动maptask,maptask对数据分区排序。
第12步:MrAppMaster等待所有maptask运行完毕后,向RM申请容器,运行reduce task。
第13步:reduce task向maptask获取相应分区的数据。
第14步:程序运行完毕后,MR会向RM申请注销自己。
(5)进度和状态更新
YARN中的任务将其进度和状态(包括counter)返回给应用管理器, 客户端每秒(通过mapreduce.client.progressmonitor.pollinterval设置)向应用管理器请求进度更新, 展示给用户。
(6)作业完成
除了向应用管理器请求作业进度外, 客户端每5分钟都会通过调用waitForCompletion()来检查作业是否完成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。作业完成之后, 应用管理器和container会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查。
9、资源调度器
资源调度器
目前,Hadoop作业调度器主要有三种:FIFO、Capacity Scheduler和Fair Scheduler。目前默认的资源调度器是Capacity Scheduler。
具体设置详见:yarn-default.xml文件
<property>
<description>The class to use as the resource scheduler.</description>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
先进先出调度器(FIFO)
优点:调度算法简单,JobTracker(job提交任务后发送得地方)工作负担轻。
缺点:忽略了不同作业的需求差异。例如如果类似对海量数据进行统计分析的作业长期占据计算资源,那么在其后提交的交互型作业有可能迟迟得不到处理,从而影响到用户的体验。
容量调度器(Capacity Scheduler)===>Yahoo开发
1.多队列支持,每个队列采用FIFO
2.为了防止同一个用户的作业独占队列中的资源,该调度器会对同一个用户提交多的作业所占资源量进行限定
3.首先,计算每个队列中正在运行的任务数与其应该分得的计算资源之间的比值,选择一个该比值最小的队列
4.其次,根据作业的优先级和提交时间顺序,同时考虑用户资源量限制和内存限制对队列内任务排序
5.三个队列同时按照任务的先后顺序依次执行,比如,job1,job21和job31分别排在队列最前面,是最先运行,也是同时运行
该调度默认情况下不支持优先级,但是可以在配置文件中开启此选项,如果支持优先级,调度算法就是带有优先级的FIFO。
不支持优先级抢占,一旦一个作业开始执行,在执行完之前它的资源不会被高优先级作业所抢占。
对队列中同一用户提交的作业能够获得的资源百分比进行了限制以使同属于一用户的作业不能出现独占资源的情况。
3)公平调度器(Fair Scheduler)===>Facebook开发
1.支持多队列多用户,每个队列中的资源量可以配置,同一个队列中的作业公平共享队列中所有资源
2.比如有三个队列A,B,C.每个队列中的job按照优先级分配资源,优先级越高分配的资源越多,但是每个job都分配到资源以确保公平。在资源有限的情况下,每个job理想情况下,获得的计算资源与实际获得的计算资源存在一种差距,这个差距叫做缺额。同一个队列,job的资源缺额越大,越先获得的资源优先执行,作业是按照缺额的高低来先后执行的,而且可以看到上图有多个作业同时运行
10、任务的推测执行
推测执行(Speculative Execution)是指在集群环境下运行MapReduce,可能是程序Bug,负载不均或者其他的一些问题,导致在一个JOB下的多个TASK速度不一致,比如有的任务已经完成,但是有些任务可能只跑了10%,根据木桶原理,这些任务将成为整个JOB的短板,如果集群启动了推测执行,这时为了最大限度的提高短板,Hadoop会为该task启动备份任务,让speculative task与原始task同时处理一份数据,哪个先运行完,则将谁的结果作为最终结果,并且在运行完成后Kill掉另外一个任务。
1)作业完成时间取决于最慢的任务完成时间
一个作业由若干个Map任务和Reduce任务构成。因硬件老化、软件Bug等,某些任务可能运行非常慢。
典型案例:系统中有99%的Map任务都完成了,只有少数几个Map老是进度很慢,完不成,怎么办?
2)推测执行机制:
发现拖后腿的任务,比如某个任务运行速度远慢于任务平均速度。为拖后腿任务启动一个备份任务,同时运行。谁先运行完,则采用谁的结果。
3)执行推测任务的前提条件
(1)每个task只能有一个备份任务;
(2)当前job已完成的task必须不小于0.05(5%)
(3)开启推测执行参数设置,mapred-site.xml文件中默认是打开的。
<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
<description>If true, then multiple instances of some map tasks may be executed in parallel.</description>
</property>
<property>
<name>mapreduce.reduce.speculative</name>
<value>true</value>
<description>If true, then multiple instances of some reduce tasks
may be executed in parallel.</description>
</property>
4)不能启用推测执行机制情况
(1)任务间存在严重的负载倾斜;
(2)特殊任务,比如任务向数据库中写数据。