mapreduce原理

MapReduce是一种编程模型,用于大规模数据集的并行运算,其中包含 Map(映射)Reduce(归约) 两个阶段。

接下来以最经典的 Word Count 案例进行解析

在MapReduce整个过程可以概括为以下过程:

输入 --> map --> shuffle --> reduce -->输出

流程说明如下:

  1. 输入文件分片,每一片都由一个MapTask来处理

  2. Map输出的中间结果会先放在内存缓冲区中,这个缓冲区的大小默认是100M,当缓冲区中的内容达到80%时(80M)会将缓冲区的内容写到磁盘上。也就是说,一个map会输出一个或者多个这样的文件,如果一个map输出的全部内容没有超过限制,那么最终也会发生这个写磁盘的操作,只不过是写几次的问题。

  3. 从缓冲区写到磁盘的时候,会进行分区并排序,分区指的是某个key应该进入到哪个分区,同一分区中的key会进行排序,如果定义了Combiner的话,也会进行combine操作

  4. 如果一个map产生的中间结果存放到多个文件,那么这些文件最终会合并成一个文件,这个合并过程不会改变分区数量,只会减少文件数量。例如,假设分了3个区,4个文件,那么最终会合并成1个文件,3个区

  5. 以上只是一个map的输出,接下来进入reduce阶段

  6. 每个reducer对应一个ReduceTask,在真正开始reduce之前,先要从分区中抓取数据

  7. 相同的分区的数据会进入同一个reduce。这一步中会从所有map输出中抓取某一分区的数据,在抓取的过程中伴随着排序、合并。

  8. reduce输出

案例背景

假设有以下好友列表,A的好友有B,C,D,F,E,O; B的好友有A,C,E,K
那我们要如何算出A-O用户每个用户之间的共同好友呢?

A:B,C,D,F,E,O
B:A,C,E,K
C:F,A,D,I
D:A,E,F,L
E:B,C,D,M,L
F:A,B,C,D,E,O,M
G:A,C,D,E,F
H:A,C,D,E,O
I:A,O
J:B,O
K:A,C,D
L:D,E,F
M:E,F,G
O:A,H,I,J

解决思路

下面我们将演示分步计算,思路主要如下:

  1. 提取用户的好友列表

  1. 提取共同好友

代码实现

由上可知,此次计算由两步组成,因此需要两个MapReduce程序先后执行

Maven项目配置

在编写程序前需要先导入Maven依赖与打包插件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!--此处为Maven项目信息--><groupId></groupId><artifactId></artifactId><version></version><!--Maven项目全局配置--><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!--Hadoop依赖--><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.7.7</version></dependency></dependencies><build><plugins><!--打包插件--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.0.2</version><configuration><archive><manifest><addClasspath>true</addClasspath><mainClass></mainClass> <!-- 此处为主入口函数,需自行填写--></manifest></archive></configuration></plugin></plugins></build>
</project>

Step 1

第一步:通过mapreduce得到某个用户是哪些用户的共同好友

/*** Mapper<> 定义的是两对键值对的泛型* 即为输入键值对与输出键值对* LongWritable 对应 long* Text 对应 String*/
public class FriendListMap extends Mapper<LongWritable, Text,Text,Text> {//重现map方法@Overrideprotected void map(LongWritable key,Text value,Context context) throws IOException, InterruptedException {// 读取需要处理的文件内容String line = value.toString();// 将内容进行分割// A:B,C,D,F,E,OString[] split = line.split(":");// 第一部分为用户// AString user = split[0];// 第二部分为用户拥有的好友列表// [B,C,D,F,E,O]String[] friends = split[1].split(",");// 遍历好友列表for(String friend: friends){// 生成键值对// {B:A},{C:A},{D:A},{F:A},{E,A},{O,A}context.write(new Text(friend),new Text(user));}}
}
/*** Reducer<>定义两个键值对的泛型* 与Mapper<>一致*/
public class FriendListReduce extends Reducer<Text,Text,Text,Text> {// 重写reduce方法,将Map过程生成的键值对进行聚合@Overridepublic void reduce(Text key,Iterable<Text> values, Context context) throws IOException, InterruptedException {// 生成一个StringBuffer对象StringBuffer sb = new StringBuffer();// 将键值对的values进行拼接for (Text person : values){sb.append(person).append(",");}// 最后生成新的键值对context.write(key,new Text(sb.toString().substring(0,sb.length())));}
}
public class FriendListJob {public static void main(String[] args) throws Exception {// 导入配置Configuration conf = new Configuration();Job job = Job.getInstance(conf,"step1");// 指定主类job.setJarByClass(FriendListJob.class);// 指定mapper类与reduce类job.setMapperClass(FriendListMap.class);job.setReducerClass(FriendListReduce.class);// 指定输出的键值对类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);// 指定输入文件与输入文件的路径(需要是HDFS内部路径)String prefix = "hdfs://192.168.50.133:9000";FileInputFormat.setInputPaths(job,new Path(prefix + args[0]));FileOutputFormat.setOutputPath(job,new Path(prefix + args[1]));// 保证程序运行完成时退出System.exit(job.waitForCompletion(true) ? 0 : 1);}
}

Step 2

由上一步可以得知,I,K,C,B,G,F,H,O,D都有好友A;A,F,J,E都有好友B。

接下来我们只需组合这些拥有相同的好友的用户,作为key发送给reduce,由reduce端聚合d得到所有共同的好友

public class SameFriendMap extends Mapper<LongWritable, Text, Text, Text> {// 重写map方法@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {// 获取读取文件内容String line = value.toString();// 分割数据String[] split = line.split("\t");// 第一个元素为好友String friend = split[0];// 第二个元素为好友拥有的好友String[] persons = split[1].split(",");// 将数组进行排序,避免出现重复的情况 A--B B--AArrays.sort(persons);// 进行匹配for(int i = 0;i<persons.length-1;i++){for(int j = i+1;j<persons.length;j++){context.write(new Text(persons[i]+ "--" +persons[j]),new Text(friend));}}}
}
public class SameFriendReduce extends Reducer<Text,Text,Text,Text> {// 重写reduce方法@Overrideprotected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {//声明StringBuffer对象StringBuffer sb = new StringBuffer();// 拼接值一样的结果for(Text friend : values){sb.append(friend).append(",");}// 整合Map的键值对context.write(key,new Text(sb.toString().substring(0,sb.length()-1)));}
}
public class SameFriendJob {public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {// 导入配置Configuration conf = new Configuration();Job job = Job.getInstance(conf,"step2");// 指定主类job.setJarByClass(SameFriendJob.class);// 指定mapper类与reduce类job.setMapperClass(SameFriendMap.class);job.setReducerClass(SameFriendReduce.class);// 指定输出的键值对类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);// 指定输入文件与输入文件的路径(需要是HDFS内部路径)String prefix = "hdfs://192.168.50.133:9000";FileInputFormat.setInputPaths(job,new Path(prefix + "/output/part-r-00000"));FileOutputFormat.setOutputPath(job,new Path(prefix + args[0]));// 保证程序运行完成时退出System.exit(job.waitForCompletion(true) ? 0 : 1);}
}

如图,我们就得到了拥有共同好友的用户列表及其对应关系,在实际场景中再根据用户关系(如是否已经是好友)进行过滤,就形成了我们所看到"可能认识"或者"好友推荐"啦

MapReduce实战案例:发现共同好友相关推荐

  1. 全方位揭秘!大数据从0到1的完美落地之MapReduce实战案例(1)

    案例一: MR实战之小文件合并(自定义inputFormat) 项目准备 需求 无论hdfs还是MapReduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决 ...

  2. MapReduce实战之微信共同好友

    来源:https://www.bilibili.com/video/av36033875?from=search&seid=12700632591522714293 需求 以下是微信的好友列表 ...

  3. 【MapReduce】分区(分区实战案例)、Combiner、Shuffer

    分区(分区实战案例).Combiner.Shuffer 1 分区 2 根据部门号建立分区 3 Combiner 4 Shuffer 手动反爬虫,禁止转载: 原博地址 https://blog.csdn ...

  4. 大数据 - MapReduce编程案例 -BH3

    MapReduce编程案例 用mapreduce解决问题的关键是确定key,只有key相同的结果才会到同一个reduce中进行处理 默认分区使用HashPartitoner,hashCode%redu ...

  5. 基于微博评论的文本情感分析与关键词提取的实战案例~

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 宣室求贤访逐臣,贾生才调更无伦. ...

  6. Impala内存优化实战案例

    Impala内存优化实战案例 李珂 畅游DT时代 2016-03-25 文章来源:中国联通网研院网优网管部--IT技术研究团队 作者:李珂 一. 引言 Hadoop生态中的NoSQL数据分析三剑客Hi ...

  7. 白杨SEO:5000字拆解如何从0-1用知乎排名做精准引流和变现?【实战案例】

    前言:这是白杨SEO公众号原创第230篇.上次写完8000字拆解公众号排名原理(文末推荐),很多朋友说看得很爽,阅读.收藏也上新高. 因为现在上班,所以每周计划写一篇了,今天继续上一篇知乎实战干货,不 ...

  8. 2021年大数据Spark(四十一):SparkStreaming实战案例六 自定义输出 foreachRDD

    目录 SparkStreaming实战案例六 自定义输出-foreachRDD 需求 注意: 代码实现 SparkStreaming实战案例六 自定义输出-foreachRDD 需求 对上述案例的结果 ...

  9. Linux 运维自动化之Cobbler实战案例

    大纲 一.前言 二.Cobbler 工作原理详解 三.Cobbler 常用命令汇总 四.Cobbler 各种目录说明 五.自定义Kickstart文件详解 六.Cobbler 实战案例安装CentOS ...

最新文章

  1. idea 快速导入实现父类方法_教你快速吸引精准粉丝实现流量变现的方法
  2. 宇宙是一个无始无终的循环?
  3. CV之IS:利用pixellib库基于deeplabv3_xception模型对《庆余年》片段实现语义分割/图像分割简单代码全实现
  4. 合约实战,代币合约,DAPP开发
  5. win10此电脑不见了_教程 | win10总提示“你要允许此应用对电脑的修改吗”,如何关闭?...
  6. 无法在Web服务器上启动调试。与Web服务器通信时出现身份验证错误
  7. 光滑噪声数据常用的方法_什么是噪声数据:噪声数据的处理方法
  8. Android中activity的生命周期
  9. hibernate查询出的实体,set值后,自动更新到数据库
  10. OpenSearch 讲解
  11. 机顶盒两个灯出现红色
  12. QT5.14.2 + MSVC2017_64 + MySQL5.7.29 数据库驱动编译及配置
  13. 计算机硬盘换,电脑硬盘可以随便换吗
  14. C# 数组去重的三种方法
  15. 计算机核心论文如何审稿,计算机核心期刊排名及投稿经验(范文).doc
  16. tensorflow if语句
  17. javascript 大文件下载,分片下载,断点续传
  18. [Android] 如何制作手电筒程序
  19. ## 大一java课程设计_航班查询系统(我是小白)
  20. 为何我工作十年,内心仍无比恐慌(腾讯产品总监曹菲)

热门文章

  1. 黑马程序员C++实战(二)——基于多态的职工管理系统完整代码
  2. 浅谈为什么大电容滤低频小电容滤高频
  3. 17福师计算机在线作业,17春福师《计算机辅助设计1(ps)》在线作业一
  4. Telegram正式推出TON区块链测试网络Lite客户端
  5. bzoj3538[Usaco2014 Open]Dueling GPS*
  6. 实现fontsize的全局适配,如何嵌入vue框架?
  7. opencv for python的图像梯度算子以及canny边缘检测
  8. 使用IPV6外网访问的配置方法
  9. HTTP等常用默认端口号
  10. 汽车线束整车3D模型 线束设计资料大全