Hadoop-简单的MapReduce案例

分析MapReduce执行过程

    MapReduce运行的时候,会通过Mapper运行的任务读取HDFS中的数据文件,然后调用自己的方法,处理数据,最后输出。Reducer任务会接收Mapper任务输出的数据,作为自己的输入数据,调用自己的方法,最后输出到HDFS的文件中。整个流程如图:

image

Mapper任务的执行过程详解

每个Mapper任务是一个java进程,它会读取HDFS中的文件,解析成很多的键值对,经过我们覆盖的map方法处理后,转换为很多的键值对再输出。整个Mapper任务的处理过程又可以分为以下几个阶段,如图所示。

image

在上图中,把Mapper任务的运行过程分为六个阶段。

  1. 第一阶段是把输入文件按照一定的标准分片(InputSplit),每个输入片的大小是固定的。默认情况下,输入片(InputSplit)的大小与数据块(Block)的大小是相同的。如果数据块(Block)的大小是默认值64MB,输入文件有两个,一个是32MB,一个是72MB。那么小的文件是一个输入片,大文件会分为两个数据块,那么是两个输入片。一共产生三个输入片。每一个输入片由一个Mapper进程处理。这里的三个输入片,会有三个Mapper进程处理。

  2. 第二阶段是对输入片中的记录按照一定的规则解析成键值对。有个默认规则是把每一行文本内容解析成键值对。“键”是每一行的起始位置(单位是字节),“值”是本行的文本内容。

  3. 第三阶段是调用Mapper类中的map方法。第二阶段中解析出来的每一个键值对,调用一次map方法。如果有1000个键值对,就会调用1000次map方法。每一次调用map方法会输出零个或者多个键值对。

  4. 第四阶段是按照一定的规则对第三阶段输出的键值对进行分区。比较是基于键进行的。比如我们的键表示省份(如北京、上海、山东等),那么就可以按照不同省份进行分区,同一个省份的键值对划分到一个区中。默认是只有一个区分区的数量就是Reducer任务运行的数量。默认只有一个Reducer任务。

  5. 第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对于键相同的键值对,按照值进行排序。比如三个键值对<2,2>、<1,3>、<2,1>,键和值分别是整数。那么排序后的结果是<1,3>、<2,1>、<2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到本地的linux文件中。

  6. 第六阶段是对数据进行归约处理,也就是reduce处理。键相等的键值对会调用一次reduce方法。经过这一阶段,数据量会减少。归约后的数据输出到本地的linxu文件中。本阶段默认是没有的,需要用户自己增加这一阶段的代码

Reducer任务的执行过程详解

每个Reducer任务是一个java进程。Reducer任务接收Mapper任务的输出,归约处理后写入到HDFS中,可以分为如下图所示的几个阶段。

image

  1. 第一阶段是Reducer任务会主动从Mapper任务复制其输出的键值对。Mapper任务可能会有很多,因此Reducer会复制多个Mapper的输出。

  2. 第二阶段是把复制到Reducer本地数据,全部进行合并,即把分散的数据合并成一个大的数据。再对合并后的数据排序。

  3. 第三阶段是对排序后的键值对调用reduce方法。键相等的键值对调用一次reduce方法,每次调用会产生零个或者多个键值对。最后把这些输出的键值对写入到HDFS文件中。

在整个MapReduce程序的开发过程中,我们最大的工作量是覆盖map函数和覆盖reduce函数。

键值对的编号

在对Mapper任务、Reducer任务的分析过程中,会看到很多阶段都出现了键值对,读者容易混淆,所以这里对键值对进行编号,方便大家理解键值对的变化情况,如下图所示。

image

在上图中,对于Mapper任务输入的键值对,定义为key1和value1。在map方法中处理后,输出的键值对,定义为key2和value2。reduce方法接收key2和value2,处理后,输出key3和value3。在下文讨论键值对时,可能把key1和value1简写为<k1,v1>,key2和value2简写为<k2,v2>,key3和value3简写为<k3,v3>。

以上内容来自:http://www.superwu.cn/2013/08/21/530/


-----------------------分------------------割----------------线-------------------------


例子:求每年最高气温

在HDFS中的根目录下有以下文件格式: /input.txt

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2014010114
2014010216
2014010317
2014010410
2014010506
2012010609
2012010732
2012010812
2012010919
2012011023
2001010116
2001010212
2001010310
2001010411
2001010529
2013010619
2013010722
2013010812
2013010929
2013011023
2008010105
2008010216
2008010337
2008010414
2008010516
2007010619
2007010712
2007010812
2007010999
2007011023
2010010114
2010010216
2010010317
2010010410
2010010506
2015010649
2015010722
2015010812
2015010999
2015011023

    比如:2010012325表示在2010年01月23日的气温为25度。现在要求使用MapReduce,计算每一年出现过的最大气温。

    在写代码之前,先确保正确的导入了相关的jar包。我使用的是maven,可以到http://mvnrepository.com去搜索这几个artifactId。

    此程序需要以Hadoop文件作为输入文件,以Hadoop文件作为输出文件,因此需要用到文件系统,于是需要引入hadoop-hdfs包;我们需要向Map-Reduce集群提交任务,需要用到Map-Reduce的客户端,于是需要导入hadoop-mapreduce-client-jobclient包;另外,在处理数据的时候会用到一些hadoop的数据类型例如IntWritable和Text等,因此需要导入hadoop-common包。于是运行此程序所需要的相关依赖有以下几个:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< dependency >
     < groupId >org.apache.hadoop</ groupId >
     < artifactId >hadoop-hdfs</ artifactId >
     < version >2.4.0</ version >
</ dependency >
< dependency >
     < groupId >org.apache.hadoop</ groupId >
     < artifactId >hadoop-mapreduce-client-jobclient</ artifactId >
     < version >2.4.0</ version >
</ dependency >
< dependency >
     < groupId >org.apache.hadoop</ groupId >
     < artifactId >hadoop-common</ artifactId >
     < version >2.4.0</ version >
</ dependency >

    包导好了后, 设计代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package  com.abc.yarn;
 
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.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.output.FileOutputFormat;
 
public  class  Temperature {
     /**
      * 四个泛型类型分别代表:
      * KeyIn        Mapper的输入数据的Key,这里是每行文字的起始位置(0,11,...)
      * ValueIn      Mapper的输入数据的Value,这里是每行文字
      * KeyOut       Mapper的输出数据的Key,这里是每行文字中的“年份”
      * ValueOut     Mapper的输出数据的Value,这里是每行文字中的“气温”
      */
     static  class  TempMapper  extends
             Mapper<LongWritable, Text, Text, IntWritable> {
         @Override
         public  void  map(LongWritable key, Text value, Context context)
                 throws  IOException, InterruptedException {
             // 打印样本: Before Mapper: 0, 2000010115
             System.out.print( "Before Mapper: "  + key +  ", "  + value);
             String line = value.toString();
             String year = line.substring( 0 4 );
             int  temperature = Integer.parseInt(line.substring( 8 ));
             context.write( new  Text(year),  new  IntWritable(temperature));
             // 打印样本: After Mapper:2000, 15
             System.out.println(
                     "======"  +
                     "After Mapper:"  new  Text(year) +  ", "  new  IntWritable(temperature));
         }
     }
 
     /**
      * 四个泛型类型分别代表:
      * KeyIn        Reducer的输入数据的Key,这里是每行文字中的“年份”
      * ValueIn      Reducer的输入数据的Value,这里是每行文字中的“气温”
      * KeyOut       Reducer的输出数据的Key,这里是不重复的“年份”
      * ValueOut     Reducer的输出数据的Value,这里是这一年中的“最高气温”
      */
     static  class  TempReducer  extends
             Reducer<Text, IntWritable, Text, IntWritable> {
         @Override
         public  void  reduce(Text key, Iterable<IntWritable> values,
                 Context context)  throws  IOException, InterruptedException {
             int  maxValue = Integer.MIN_VALUE;
             StringBuffer sb =  new  StringBuffer();
             //取values的最大值
             for  (IntWritable value : values) {
                 maxValue = Math.max(maxValue, value.get());
                 sb.append(value).append( ", " );
             }
             // 打印样本: Before Reduce: 2000, 15, 23, 99, 12, 22, 
             System.out.print( "Before Reduce: "  + key +  ", "  + sb.toString());
             context.write(key,  new  IntWritable(maxValue));
             // 打印样本: After Reduce: 2000, 99
             System.out.println(
                     "======"  +
                     "After Reduce: "  + key +  ", "  + maxValue);
         }
     }
 
     public  static  void  main(String[] args)  throws  Exception {
         //输入路径
         String dst =  "hdfs://localhost:9000/intput.txt" ;
         //输出路径,必须是不存在的,空文件加也不行。
         String dstOut =  "hdfs://localhost:9000/output" ;
         Configuration hadoopConfig =  new  Configuration();
         
         hadoopConfig.set( "fs.hdfs.impl"
             org.apache.hadoop.hdfs.DistributedFileSystem. class .getName()
         );
         hadoopConfig.set( "fs.file.impl" ,
             org.apache.hadoop.fs.LocalFileSystem. class .getName()
         );
         Job job =  new  Job(hadoopConfig);
         
         //如果需要打成jar运行,需要下面这句
         //job.setJarByClass(NewMaxTemperature.class);
 
         //job执行作业时输入和输出文件的路径
         FileInputFormat.addInputPath(job,  new  Path(dst));
         FileOutputFormat.setOutputPath(job,  new  Path(dstOut));
 
         //指定自定义的Mapper和Reducer作为两个阶段的任务处理类
         job.setMapperClass(TempMapper. class );
         job.setReducerClass(TempReducer. class );
         
         //设置最后输出结果的Key和Value的类型
         job.setOutputKeyClass(Text. class );
         job.setOutputValueClass(IntWritable. class );
         
         //执行job,直到完成
         job.waitForCompletion( true );
         System.out.println( "Finished" );
     }
}

上面代码中,注意Mapper类的泛型不是java的基本类型,而是Hadoop的数据类型Text、IntWritable。我们可以简单的等价为java的类String、int。

代码中Mapper类的泛型依次是<k1,v1,k2,v2>。map方法的第二个形参是行文本内容,是我们关心的。核心代码是把行文本内容按照空格拆分,把每行数据中“年”和“气温”提取出来,其中“年”作为新的键,“温度”作为新的值,写入到上下文context中。在这里,因为每一年有多行数据,因此每一行都会输出一个<年份, 气温>键值对。

下面是控制台打印结果:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Before Mapper:  0 2014010114 ======After Mapper: 2014 14
Before Mapper:  11 2014010216 ======After Mapper: 2014 16
Before Mapper:  22 2014010317 ======After Mapper: 2014 17
Before Mapper:  33 2014010410 ======After Mapper: 2014 10
Before Mapper:  44 2014010506 ======After Mapper: 2014 6
Before Mapper:  55 2012010609 ======After Mapper: 2012 9
Before Mapper:  66 2012010732 ======After Mapper: 2012 32
Before Mapper:  77 2012010812 ======After Mapper: 2012 12
Before Mapper:  88 2012010919 ======After Mapper: 2012 19
Before Mapper:  99 2012011023 ======After Mapper: 2012 23
Before Mapper:  110 2001010116 ======After Mapper: 2001 16
Before Mapper:  121 2001010212 ======After Mapper: 2001 12
Before Mapper:  132 2001010310 ======After Mapper: 2001 10
Before Mapper:  143 2001010411 ======After Mapper: 2001 11
Before Mapper:  154 2001010529 ======After Mapper: 2001 29
Before Mapper:  165 2013010619 ======After Mapper: 2013 19
Before Mapper:  176 2013010722 ======After Mapper: 2013 22
Before Mapper:  187 2013010812 ======After Mapper: 2013 12
Before Mapper:  198 2013010929 ======After Mapper: 2013 29
Before Mapper:  209 2013011023 ======After Mapper: 2013 23
Before Mapper:  220 2008010105 ======After Mapper: 2008 5
Before Mapper:  231 2008010216 ======After Mapper: 2008 16
Before Mapper:  242 2008010337 ======After Mapper: 2008 37
Before Mapper:  253 2008010414 ======After Mapper: 2008 14
Before Mapper:  264 2008010516 ======After Mapper: 2008 16
Before Mapper:  275 2007010619 ======After Mapper: 2007 19
Before Mapper:  286 2007010712 ======After Mapper: 2007 12
Before Mapper:  297 2007010812 ======After Mapper: 2007 12
Before Mapper:  308 2007010999 ======After Mapper: 2007 99
Before Mapper:  319 2007011023 ======After Mapper: 2007 23
Before Mapper:  330 2010010114 ======After Mapper: 2010 14
Before Mapper:  341 2010010216 ======After Mapper: 2010 16
Before Mapper:  352 2010010317 ======After Mapper: 2010 17
Before Mapper:  363 2010010410 ======After Mapper: 2010 10
Before Mapper:  374 2010010506 ======After Mapper: 2010 6
Before Mapper:  385 2015010649 ======After Mapper: 2015 49
Before Mapper:  396 2015010722 ======After Mapper: 2015 22
Before Mapper:  407 2015010812 ======After Mapper: 2015 12
Before Mapper:  418 2015010999 ======After Mapper: 2015 99
Before Mapper:  429 2015011023 ======After Mapper: 2015 23
Before Reduce:  2001 12 10 11 29 16 , ======After Reduce:  2001 29
Before Reduce:  2007 23 19 12 12 99 , ======After Reduce:  2007 99
Before Reduce:  2008 16 14 37 16 5 , ======After Reduce:  2008 37
Before Reduce:  2010 10 6 14 16 17 , ======After Reduce:  2010 17
Before Reduce:  2012 19 12 32 9 23 , ======After Reduce:  2012 32
Before Reduce:  2013 23 29 12 22 19 , ======After Reduce:  2013 29
Before Reduce:  2014 14 6 10 17 16 , ======After Reduce:  2014 17
Before Reduce:  2015 23 49 22 12 99 , ======After Reduce:  2015 99
Finished

    执行结果:

对分析的验证

    从打印的日志中可以看出:

  • Mapper的输入数据(k1,v1)格式是:默认的按行分的键值对<0, 2010012325>,<11, 2012010123>...

  • Reducer的输入数据格式是:把相同的键合并后的键值对:<2001, [12, 32, 25...]>,<2007, [20, 34, 30...]>...

  • Reducer的输出数(k3,v3)据格式是:经自己在Reducer中写出的格式:<2001, 32>,<2007, 34>...

    其中,由于输入数据太小,Map过程的第1阶段这里不能证明。但事实上是这样的。

    结论中第一点验证了Map过程的第2阶段“键”是每一行的起始位置(单位是字节),“值”是本行的文本内容。

    另外,通过Reduce的几行

?
1
2
3
4
5
6
7
8
Before Reduce:  2001 12 10 11 29 16 , ======After Reduce:  2001 29
Before Reduce:  2007 23 19 12 12 99 , ======After Reduce:  2007 99
Before Reduce:  2008 16 14 37 16 5 , ======After Reduce:  2008 37
Before Reduce:  2010 10 6 14 16 17 , ======After Reduce:  2010 17
Before Reduce:  2012 19 12 32 9 23 , ======After Reduce:  2012 32
Before Reduce:  2013 23 29 12 22 19 , ======After Reduce:  2013 29
Before Reduce:  2014 14 6 10 17 16 , ======After Reduce:  2014 17
Before Reduce:  2015 23 49 22 12 99 , ======After Reduce:  2015 99

    可以证实Map过程的第4阶段:先分区,然后对每个分区都执行一次Reduce(Map过程第6阶段)。

    对于Mapper的输出,前文中提到:如果没有Reduce过程,Mapper的输出会直接写入文件。于是我们把Reduce方法去掉(注释掉第95行即可)。

    再执行,下面是控制台打印结果: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Before Mapper:  0 2014010114 ======After Mapper: 2014 14
Before Mapper:  11 2014010216 ======After Mapper: 2014 16
Before Mapper:  22 2014010317 ======After Mapper: 2014 17
Before Mapper:  33 2014010410 ======After Mapper: 2014 10
Before Mapper:  44 2014010506 ======After Mapper: 2014 6
Before Mapper:  55 2012010609 ======After Mapper: 2012 9
Before Mapper:  66 2012010732 ======After Mapper: 2012 32
Before Mapper:  77 2012010812 ======After Mapper: 2012 12
Before Mapper:  88 2012010919 ======After Mapper: 2012 19
Before Mapper:  99 2012011023 ======After Mapper: 2012 23
Before Mapper:  110 2001010116 ======After Mapper: 2001 16
Before Mapper:  121 2001010212 ======After Mapper: 2001 12
Before Mapper:  132 2001010310 ======After Mapper: 2001 10
Before Mapper:  143 2001010411 ======After Mapper: 2001 11
Before Mapper:  154 2001010529 ======After Mapper: 2001 29
Before Mapper:  165 2013010619 ======After Mapper: 2013 19
Before Mapper:  176 2013010722 ======After Mapper: 2013 22
Before Mapper:  187 2013010812 ======After Mapper: 2013 12
Before Mapper:  198 2013010929 ======After Mapper: 2013 29
Before Mapper:  209 2013011023 ======After Mapper: 2013 23
Before Mapper:  220 2008010105 ======After Mapper: 2008 5
Before Mapper:  231 2008010216 ======After Mapper: 2008 16
Before Mapper:  242 2008010337 ======After Mapper: 2008 37
Before Mapper:  253 2008010414 ======After Mapper: 2008 14
Before Mapper:  264 2008010516 ======After Mapper: 2008 16
Before Mapper:  275 2007010619 ======After Mapper: 2007 19
Before Mapper:  286 2007010712 ======After Mapper: 2007 12
Before Mapper:  297 2007010812 ======After Mapper: 2007 12
Before Mapper:  308 2007010999 ======After Mapper: 2007 99
Before Mapper:  319 2007011023 ======After Mapper: 2007 23
Before Mapper:  330 2010010114 ======After Mapper: 2010 14
Before Mapper:  341 2010010216 ======After Mapper: 2010 16
Before Mapper:  352 2010010317 ======After Mapper: 2010 17
Before Mapper:  363 2010010410 ======After Mapper: 2010 10
Before Mapper:  374 2010010506 ======After Mapper: 2010 6
Before Mapper:  385 2015010649 ======After Mapper: 2015 49
Before Mapper:  396 2015010722 ======After Mapper: 2015 22
Before Mapper:  407 2015010812 ======After Mapper: 2015 12
Before Mapper:  418 2015010999 ======After Mapper: 2015 99
Before Mapper:  429 2015011023 ======After Mapper: 2015 23
Finished

    再来看看执行结果:

    结果还有很多行,没有截图了。

    由于没有执行Reduce操作,因此这个就是Mapper输出的中间文件的内容了。

    从打印的日志可以看出:

  • Mapper的输出数据(k2, v2)格式是:经自己在Mapper中写出的格式:<2010, 25>,<2012, 23>...

    从这个结果中可以看出,原数据文件中的每一行确实都有一行输出,那么Map过程的第3阶段就证实了。

    从这个结果中还可以看出,“年份”已经不是输入给Mapper的顺序了,这也说明了在Map过程中也按照Key执行了排序操作,即Map过程的第5阶段

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: HadoopMapReduce实战案例有很多,以下是一些常见的案例: 1. WordCount:统计文本中单词出现的次数。 2. TopN:找出文本中出现次数最多的前N个单词。 3. 求平均值:计算文本中一列数字的平均值。 4. 倒排索引:将文本中的单词与出现的文档建立索引,方便快速查找。 5. 关联规则挖掘:通过分析大量数据,找出其中的关联规则,如购物篮分析。 6. 图像处理:通过MapReduce处理大量图像数据,如图像分类、图像识别等。 7. 推荐系统:通过分析用户行为数据,为用户推荐相关的产品或服务。 8. 日志分析:通过MapReduce处理大量日志数据,如网站访问日志、服务器日志等,分析用户行为、系统性能等。 以上是一些常见的HadoopMapReduce实战案例,实际应用中还有很多其他的案例。 ### 回答2: Hadoop是一个开源的分布式存储和处理大数据的解决方案,而MapReduceHadoop中的一种计算框架。其实战案例很多,下面就列举一些经典的案例。 1. 单词计数:在一个大文本文件中统计每个单词出现的次数,是Hadoop入门案例MapReduceMap函数进行分割文本并将每个单词都映射到(key,value)对上,reduce函数对同一个key的value进行合并并输出。 2. 网页排名:Google使用了PageRank算法对网页搜索结果进行排序,而这个排序算法的实现就是MapReduce模型。Map函数将网页信息和链接信息映射到(key,value)对上,reduce函数计算网页的排名并输出。 3. 日志分析:大型网站的日志通常非常庞大,Hadoop可应用于实时分析与处理这些日志。MapReduceMap函数解析日志并提取重要信息,reduce函数进行计数统计或者聚合操作。 4. 图像处理MapReduce模型常用于图像识别、处理和分析。Map函数把处理的图像块分配到不同的机器上,在不同的机器上并行化地处理。而reduce函数通常用于汇总结果并输出。 这些案例只是MapReduceHadoop中的应用之一,Hadoop还可以通过Hive、Pig等组件来对数据进行高层次的查询、脚本处理和数据分析。Hadoop大数据领域的应用日益广泛,如商业智能、金融风控、医疗健康等,在数据收集、存储和处理中扮演着重要的角色。 ### 回答3: Hadoop是一个大数据处理平台,而MapReduce是其中最主要的一种分布式计算框架。MapReduce的核心思想是将一个大数据集拆分成多个子集,然后通过并行计算将这些子集进行处理得到最终结果。 在实际应用中,人们利用HadoopMapReduce处理各种各样的大数据问题。下面我们来介绍一些MapReduce的实战案例: 1.单词统计 这是一个最简单却也最典型的案例。它的思路是读入一个大文本文件,然后将文件中每个单词逐个拆分出来,统计每个单词出现的频次,并将结果输出。这个过程可以通过MapReduce的"map"和"reduce"函数来实现。其中"map"函数负责将文本文件拆分成单词,将每个单词与1这个数字配对,并将结果输出。而"reduce"函数负责将配对结果按照单词将其分组,然后将每组中所有数字进行累加,得到每个单词的频次。 2. 声明式流媒体处理 MapReduce不仅仅是用来处理静态的大数据,还可以用来处理流媒体数据。具体来说,就是将流媒体数据流中的元素分割成小块,逐块对其进行MapReduce运算处理,得到最终结果。例如,在一个音乐流媒体应用中,我们可以通过MapReduce对歌曲库进行快速索引,以便用户能够快速检索和播放他们喜爱的歌曲。同时,在流媒体数据处理过程中,MapReduce还能够根据所处理的数据类型,自动调整MapReduce算法的参数和并行度,以确保处理效率和质量。 3.处理图形数据 图形处理是一个非常关键的应用领域。通过MapReduce计算框架,我们能够处理极大规模的图形数据集,例如在社交网络中对用户关系进行建模或者对搜索引擎中的网页链接关系进行分析。具体操作过程是,我们首先通过MapReduce的"map"函数将每个节点的邻居节点列表作为输出键值,将每个节点的ID作为输出值。然后通过MapReduce的"reduce"函数将具有相同邻居节点的节点交给同一个处理器进行处理。最终,我们得到的结果是每个节点及其所有邻居节点的详细信息。 总之,以上三个案例充分展示了MapReduce大数据处理过程中的应用价值。作为一种分析大规模数据和自动化处理复杂问题的工具,MapReduce框架不仅使我们能够更好地管理和分析数据,而且还推动了数据处理领域的创新和发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值