Hadoop big data technologies (the Yarn & Hadoop data compression resource scheduler) four & five

4.1 Overview

Compression Overview

 

Compression strategy and principles

 

4.2 MR supported compression coding

Table 4-7 

Compression format

hadoop comes?

algorithm

File name extension

Whether segmentation

After compression format replaced the original program needs to be modified

DEFLATE

Is directly

DEFLATE

.deflate

no

And text processing, requiring no modification

Gzip

Is directly

DEFLATE

.gz

no

And text processing, requiring no modification

bzip2

Is directly

bzip2

.bz2

Yes

And text processing, requiring no modification

VOC

No need to install

VOC

.lzo

Yes

Need to build the index, also need to specify the input format

Snappy

No need to install

Snappy

.snappy

no

And text processing, requiring no modification

To support a variety of compression / decompression algorithms, the Hadoop introduced encoder / decoder, as shown below.

Table 4-8

Compression format

Corresponding encoder / decoder

DEFLATE

org.apache.hadoop.io.compress.DefaultCodec

gzip

org.apache.hadoop.io.compress.GzipCodec

bzip2

org.apache.hadoop.io.compress.BZip2Codec

VOC

com.hadoop.compression.lzo.LzopCodec

Snappy

org.apache.hadoop.io.compress.SnappyCodec

Compression performance comparison

Table 4-9

Compression algorithm

The original file size

Compressed file size

Compression speed

Decompression speed

gzip

8.3GB

1.8GB

17.5MB/s

58MB/s

bzip2

8.3GB

1.1GB

2.4MB/s

9.5MB/s

VOC

8.3GB

2.9GB

49.3MB/s

74.6MB/s

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.

4.3 压缩方式选择

4.3.1 Gzip压缩

4.3.2 Bzip2压缩

4.3.3 Lzo压缩

4.3.4 Snappy压缩

4.4 压缩位置选择

压缩可以在MapReduce作用的任意阶段启用,如图4-22所示。

图4-22 MapReduce数据压缩

4.5 压缩参数配置

要在Hadoop中启用压缩,可以配置如下参数:

表4-10 配置参数

参数

默认值

阶段

建议

io.compression.codecs  

(在core-site.xml中配置)

org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec

 

输入压缩

Hadoop使用文件扩展名判断是否支持某种编解码器

mapreduce.map.output.compress(在mapred-site.xml中配置)

false

mapper输出

这个参数设为true启用压缩

mapreduce.map.output.compress.codec(在mapred-site.xml中配置)

org.apache.hadoop.io.compress.DefaultCodec

mapper输出

企业多使用LZOSnappy编解码器在此阶段压缩数据

mapreduce.output.fileoutputformat.compress(在mapred-site.xml中配置)

false

reducer输出

这个参数设为true启用压缩

mapreduce.output.fileoutputformat.compress.codec(在mapred-site.xml中配置)

org.apache.hadoop.io.compress. DefaultCodec

reducer输出

使用标准工具或者编解码器,如gzipbzip2

mapreduce.output.fileoutputformat.compress.type(在mapred-site.xml中配置)

RECORD

reducer输出

SequenceFile输出使用的压缩类型:NONEBLOCK

4.6 压缩实操案例

4.6.1 数据流的压缩和解压缩

测试一下如下压缩方式:

表4-11

DEFLATE

org.apache.hadoop.io.compress.DefaultCodec

gzip

org.apache.hadoop.io.compress.GzipCodec

bzip2

org.apache.hadoop.io.compress.BZip2Codec

package com.newbies.mapreduce.compress;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionCodecFactory;
import org.apache.hadoop.io.compress.CompressionInputStream;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.util.ReflectionUtils;

public class TestCompress {

	public static void main(String[] args) throws Exception {
		compress("e:/hello.txt","org.apache.hadoop.io.compress.BZip2Codec");
//		decompress("e:/hello.txt.bz2");
	}

	// 1、压缩
	private static void compress(String filename, String method) throws Exception {
		
		// (1)获取输入流
		FileInputStream fis = new FileInputStream(new File(filename));
		
		Class codecClass = Class.forName(method);
		
		CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, new Configuration());
		
		// (2)获取输出流
		FileOutputStream fos = new FileOutputStream(new File(filename + codec.getDefaultExtension()));
		CompressionOutputStream cos = codec.createOutputStream(fos);
		
		// (3)流的对拷
		IOUtils.copyBytes(fis, cos, 1024*1024*5, false);
		
// (4)关闭资源
		cos.close();
		fos.close();
fis.close();
	}

	// 2、解压缩
	private static void decompress(String filename) throws FileNotFoundException, IOException {
		
		// (0)校验是否能解压缩
		CompressionCodecFactory factory = new CompressionCodecFactory(new Configuration());

		CompressionCodec codec = factory.getCodec(new Path(filename));
		
		if (codec == null) {
			System.out.println("cannot find codec for file " + filename);
			return;
		}
		
		// (1)获取输入流
		CompressionInputStream cis = codec.createInputStream(new FileInputStream(new File(filename)));
		
		// (2)获取输出流
		FileOutputStream fos = new FileOutputStream(new File(filename + ".decoded"));
		
		// (3)流的对拷
		IOUtils.copyBytes(cis, fos, 1024*1024*5, false);
		
		// (4)关闭资源
		cis.close();
		fos.close();
	}
}

4.6.2 Map输出端采用压缩

即使你的MapReduce的输入输出文件都是未压缩的文件,你仍然可以对Map任务的中间结果输出做压缩,因为它要写在硬盘并且通过网络传输到Reduce节点,对其压缩可以提高很多性能,这些工作只要设置两个属性即可,我们来看下代码怎么设置。

1.给大家提供的Hadoop源码支持的压缩格式有:BZip2Codec DefaultCodec

package com.newbies.mapreduce.compress;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.BZip2Codec;	
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountDriver {

	public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {

		Configuration configuration = new Configuration();

		// 开启map端输出压缩
	configuration.setBoolean("mapreduce.map.output.compress", true);
		// 设置map端输出压缩方式
	configuration.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);

		Job job = Job.getInstance(configuration);

		job.setJarByClass(WordCountDriver.class);

		job.setMapperClass(WordCountMapper.class);
		job.setReducerClass(WordCountReducer.class);

		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);

		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));

		boolean result = job.waitForCompletion(true);

		System.exit(result ? 1 : 0);
	}
}

2.Mapper保持不变

package com.newbies.mapreduce.compress;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{

Text k = new Text();
	IntWritable v = new IntWritable(1);

	@Override
	protected void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException {

		// 1 获取一行
		String line = value.toString();

		// 2 切割
		String[] words = line.split(" ");

		// 3 循环写出
		for(String word:words){
k.set(word);
			context.write(k, v);
		}
	}
}

3.Reducer保持不变

package com.newbies.mapreduce.compress;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{

	IntWritable v = new IntWritable();

	@Override
	protected void reduce(Text key, Iterable<IntWritable> values,
			Context context) throws IOException, InterruptedException {
		
		int sum = 0;

		// 1 汇总
		for(IntWritable value:values){
			sum += value.get();
		}
		
        v.set(sum);

        // 2 输出
		context.write(key, v);
	}
}

4.6.3 Reduce输出端采用压缩

基于WordCount案例处理。

1.修改驱动

package com.newbies.mapreduce.compress;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.BZip2Codec;
import org.apache.hadoop.io.compress.DefaultCodec;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.io.compress.Lz4Codec;
import org.apache.hadoop.io.compress.SnappyCodec;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountDriver {

	public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
		
		Configuration configuration = new Configuration();
		
		Job job = Job.getInstance(configuration);
		
		job.setJarByClass(WordCountDriver.class);
		
		job.setMapperClass(WordCountMapper.class);
		job.setReducerClass(WordCountReducer.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
		
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		// 设置reduce端输出压缩开启
		FileOutputFormat.setCompressOutput(job, true);
		
		// 设置压缩的方式
	    FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class); 
//	    FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class); 
//	    FileOutputFormat.setOutputCompressorClass(job, DefaultCodec.class); 
	    
		boolean result = job.waitForCompletion(true);
		
		System.exit(result?1:0);
	}
}

2.Mapper和Reducer保持不变(详见4.6.2

第5章 Yarn资源调度器

Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而MapReduce等运算程序则相当于运行于操作系统之上的应用程序

5.1 Yarn基本架构

       YARN主要由ResourceManagerNodeManagerApplicationMasterContainer等组件构成,如图4-23所示。

图4-23 Yarn基本架构

5.3 Yarn工作机制

1.Yarn运行机制,如图4-24所示。

图4-24  Yarn工作机制

 

2.工作机制详解

       1MR程序提交到客户端所在的节点。

       2YarnRunnerResourceManager申请一个Application

       3RM将该应用程序的资源路径返回给YarnRunner

       4)该程序将运行所需资源提交到HDFS上。

       5)程序资源提交完毕后,申请运行mrAppMaster

       6RM将用户的请求初始化成一个Task

       7)其中一个NodeManager领取到Task任务。

       8)该NodeManager创建容器Container,并产生MRAppmaster

       9ContainerHDFS上拷贝资源到本地。

       10MRAppmasterRM 申请运行MapTask资源。

       11RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。

       12MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTaskMapTask对数据分区排序。

13MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask

       14ReduceTaskMapTask获取相应分区的数据。

       15)程序运行完毕后,MR会向RM申请注销自己。

5.4 作业提交全过程

1.作业提交过程之YARN,如图4-25所示。

图4-25 作业提交过程之Yarn

 

 

作业提交全过程详解

1)作业提交

1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。

2步:ClientRM申请一个作业id

3步:RMClient返回该job资源的提交路径和作业id

4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。

5步:Client提交完资源后,向RM申请运行MrAppMaster

2)作业初始化

6步:当RM收到Client的请求后,将该job添加到容量调度器中。

7步:某一个空闲的NM领取到该Job

8步:该NM创建Container并产生MRAppmaster

9步:下载Client提交的资源到本地。

3)任务分配

10步:MrAppMasterRM申请运行多个MapTask任务资源。

11步:RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。

4)任务运行

12步:MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTaskMapTask对数据分区排序。

13步:MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask

14步:ReduceTaskMapTask获取相应分区的数据。

15步:程序运行完毕后,MR会向RM申请注销自己。

5)进度和状态更新

YARN中的任务将其进度和状态(包括counter)返回给应用管理器, 客户端每秒(通过mapreduce.client.progressmonitor.pollinterval设置)向应用管理器请求进度更新, 展示给用户。

6)作业完成

除了向应用管理器请求作业进度外, 客户端每5秒都会通过调用waitForCompletion()来检查作业是否完成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。作业完成之后, 应用管理器和Container会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查。

2.作业提交过程之MapReduce,如图4-26所示

图4-26 作业提交过程之MapReduce

5.5 资源调度器

目前,Hadoop作业调度器主要有三种:FIFOCapacity SchedulerFair SchedulerHadoop2.7.2默认的资源调度器是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>

1.先进先出调度器(FIFO),如图4-27所示

       图4-27 FIFO调度器

2.容量调度器(Capacity Scheduler),如图4-28所示

图4-28容量调度器

 

3.公平调度器(Fair Scheduler),如图4-29所示

图4-29公平调度器

 

5.6 任务的推测执行

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)特殊任务,比如任务向数据库中写数据。

5.算法原理,如图4-20所示

图4-30 推测执行算法原理

 

 

 
发布了299 篇原创文章 · 获赞 45 · 访问量 10万+

Guess you like

Origin blog.csdn.net/qq_31784189/article/details/104561642