Multithreading Mapreduce作业是否使用多重读取
我很好奇mapreduce作业是否在一台机器中使用多线程。例如,我在hadoop集群中有10台服务器,默认情况下,如果输入文件足够大,将有10个映射器。单个映射器是否在一台机器中使用多线程?请参阅 应用程序可能会覆盖run(Context)方法,以对地图处理施加更大的控制,例如多线程映射器等 此外,还有一个问题。我从来没有用过这个 单个映射器是否在一台机器中使用多线程 是的。Mapreduce作业可以使用多线程映射器(运行Multithreading Mapreduce作业是否使用多重读取,multithreading,hadoop,mapreduce,Multithreading,Hadoop,Mapreduce,我很好奇mapreduce作业是否在一台机器中使用多线程。例如,我在hadoop集群中有10台服务器,默认情况下,如果输入文件足够大,将有10个映射器。单个映射器是否在一台机器中使用多线程?请参阅 应用程序可能会覆盖run(Context)方法,以对地图处理施加更大的控制,例如多线程映射器等 此外,还有一个问题。我从来没有用过这个 单个映射器是否在一台机器中使用多线程 是的。Mapreduce作业可以使用多线程映射器(运行map方法的多线程或线程池)。 我已经为仅映射Hbase作业使用了更好的
map
方法的多线程或线程池)。
- 我已经为仅映射Hbase作业使用了更好的CPU利用率
非常适合于CPU密集型操作,可以提高速度multi-threadedmapper
org.apache.hadoop.mapreduce.lib.map.multi-threadedmapper
,而不是常规的org.apache.hadoop.mapreduce.mapper
多线程apper
具有不同的run()实现
方法。如下图所示
run(org.apache.hadoop.mapreduce.Mapper.Context context)
使用线程池运行应用程序的映射。
您可以在multi-threadedapper
中设置映射器中的线程数
multi-threadedMapper.setNumberOfThreads(n)
或者您可以在从属性文件加载时设置属性mapred.map.multi-threadedrunner.threads=n
并使用上述setter方法(基于每个作业)来控制cpu密集度较低的作业
这样做的影响,您可以在mapreduce计数器中看到,特别是与CPU相关的计数器
:
import org.apache.hadoop.fs.Path;
导入org.apache.hadoop.io.LongWritable;
导入org.apache.hadoop.io.Text;
导入org.apache.hadoop.mapreduce.Job;
导入org.apache.hadoop.mapreduce.Mapper;
导入org.apache.hadoop.mapreduce.Reducer;
导入org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
导入org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
导入org.apache.hadoop.mapreduce.lib.map.MultithreadedMapper;
导入org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
导入org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
导入org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
导入java.io.IOException;
导入java.util.regex.Pattern;
公共类多线程字计数{
//类应该是线程安全的
公共静态类WordCountMapper扩展了映射器{
公共静态枚举PREPOST{SETUP,CLEANUP}
@覆盖()
受保护的void设置(Mapper.Context Context)抛出java.io.IOException、java.lang.InterruptedException{
//将被多次呼叫
getCounter(PREPOST.SETUP).increment(1);
}
@凌驾
受保护的无效映射(可长写键、文本值、,
上下文)抛出IOException、InterruptedException{
String[]words=value.toString().toLowerCase().split([\\p{Blank}[\\p{Punct}]]+”;
for(字符串字:字){
写(新文本(单词),新长可写(1));
}
}
@覆盖()
受保护的无效清理(Mapper.Context Context)抛出java.io.IOException、interruptedeexception{
//将被多次呼叫
getCounter(PREPOST.CLEANUP).increment(1);
}
}
公共静态类WordCountReducer扩展了Reducer{
@凌驾
受保护的void reduce(文本键、Iterable值、上下文
)抛出IOException、InterruptedException{
长和=0;
for(可长写值:值){
sum+=value.get();
}
write(key,新的LongWritable(sum));
}
}
公共静态void main(字符串[]args)引发IOException、ClassNotFoundException、InterruptedException{
作业=新作业();
job.setJarByClass(WordCount.class);
addInputPath(作业,新路径(args[0]);
setOutputPath(作业,新路径(args[1]);
多线程Mapper.setMapperClass(作业,多线程WordCount.WordCountMapper.class);
多线程apper.setNumberOfThreads(作业,10);
setMapperClass(多线程apper.class);
setCombinerClass(多线程WordCount.WordCountReducer.class);
setReducerClass(多线程WordCount.WordCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
/*开始默认值*/
setInputFormatClass(TextInputFormat.class);
setOutputFormatClass(TextOutputFormat.class);
/*结束默认值*/
job.waitForCompletion(true);
}
}
每个映射程序都会在自己的JVM中运行。@二进制程序不完全是个呆子。映射器不拥有JVM。这取决于一台服务器中部署了多少hadoop实例。我想说的是,一个hadoop实例拥有一个jvm,而不是在它自己的jvm中运行的每个任务,这意味着一个映射器就是一个jvm进程。我们可以在另一个线程中讨论jvm问题。这是离题的。mapper在自己的jvm中有多线程吗?@Robinson:我提到了我使用的情况。请检查。它可以,我同意你的看法。默认情况下,我认为映射程序是一个单线程进程。
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.map.MultithreadedMapper;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import java.io.IOException;
import java.util.regex.Pattern;
public class MultithreadedWordCount {
// class should be thread safe
public static class WordCountMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
public static enum PREPOST { SETUP, CLEANUP }
@Override()
protected void setup(Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws java.io.IOException, java.lang.InterruptedException {
// will be called several times
context.getCounter(PREPOST.SETUP).increment(1);
}
@Override
protected void map(LongWritable key, Text value,
Context context) throws IOException, InterruptedException {
String[] words = value.toString().toLowerCase().split("[\\p{Blank}[\\p{Punct}]]+");
for (String word : words) {
context.write(new Text(word), new LongWritable(1));
}
}
@Override()
protected void cleanup(Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws java.io.IOException, InterruptedException {
// will be called several times
context.getCounter(PREPOST.CLEANUP).increment(1);
}
}
public static class WordCountReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context
) throws IOException, InterruptedException {
long sum = 0;
for (LongWritable value: values) {
sum += value.get();
}
context.write(key, new LongWritable(sum));
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Job job = new Job();
job.setJarByClass(WordCount.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
MultithreadedMapper.setMapperClass(job, MultithreadedWordCount.WordCountMapper.class);
MultithreadedMapper.setNumberOfThreads(job, 10);
job.setMapperClass(MultithreadedMapper.class);
job.setCombinerClass(MultithreadedWordCount.WordCountReducer.class);
job.setReducerClass(MultithreadedWordCount.WordCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
/* begin defaults */
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
/* end defaults */
job.waitForCompletion(true);
}
}