当前位置: 首页 > news >正文

MR源码解析和join案例

MR源码解析

  1. new Job(): 读取本地文件, xml配置
  2. job.start(): 启动线程
  3. job的run():线程方法
    • runTasks(): 传入对应的接口,启动map或者reduce
    • MapTask类的run(): 设置map阶段的参数,初始化任务,创建上下文对象
      • 创建读取器LineRecordReader
      • 判断是否压缩 compressFactory
      • 如果没有压缩,使用seek方法
      • mapTask的write(),进行溢写
      • mapper类的init()方法,设置溢写百分比和缓冲区大小
      • collector收集器:进行map阶段数据类型检查和分数数量检查
      • keySerializer: 进行数据的序列化,调用自己写的bean对象
      • kvmeta.put(): 写入环形缓冲区
      • mapPhase结束
    • 数据量达到缓冲区的80%,对索引进行快速排序
    • input.close():关闭输入
    • 关闭输出并同时将缓冲区数据按照分区写入磁盘。
      • 如果开启了combine,进行数据合并
    • mergePart:归并分区
    • combine第二次合并,如果溢写次数小于3就不合并了
    • collector.close():关闭环形缓冲区
  4. reduceTask的run方法
    • submit: 5个reduce并行提交
    • cLeanTask:初始化
    • shuffle类:map的排序,recuce中的归并排序
    • Merger合并器:两次归并排序,先内存归并,后磁盘归并
    • 抓取数据:可以从本地或者网络中抓取
    • sort :归并排序
    • reduce阶段:
      • 创建上下文对象
      • 调用reducer的run方法
      • real.write(): LineRecordWrite写入HDFS

使用MR来进行拷贝去重

  1. 拷贝:values写入上下文时需要迭代遍历
  2. 去重:values写入上下文时不遍历

使用MR来实现join操作

在这里插入图片描述
在这里插入图片描述

  1. 实现TableBean类,四个属性,空参构造器,get-set方法
    • write():序列化
      • out.writeUTF():该方法有换行,不会连在一起
    • readFields(): 反序列化
  2. 实现mapper类
    • setup()
      • 使用context上下文对象获取InputSplit类
      • 强制类型转换为FileSplit类
      • getPath().getName()获取文件名称
    • map()
      • 切分split
      • 封装
      • context写出
public class TableMapper extends Mapper<LongWritable, Text, Text,TableBean> {private String filename;private Text outK;private TableBean outV;//初始化,每个文件开始一次maptask,并进行一次初始化//获取到文件的名称@Overrideprotected void setup(Mapper<LongWritable, Text, Text, TableBean>.Context context) throws IOException, InterruptedException {//拿到切片信息FileSplit split = (FileSplit) context.getInputSplit();filename = split.getPath().getName();outK = new Text();outV = new TableBean();}@Overrideprotected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, TableBean>.Context context) throws IOException, InterruptedException {//1. 获取一行String line = value.toString();//2.判断是哪个文件的if(filename.contains("order")){//处理的是订单表String[] split = line.split("\t");//封装outK.set(split[1]);//pid作为keyoutV.setId(split[0]);outV.setPid(split[1]);outV.setAmount(Integer.parseInt(split[2]));outV.setTableName("order");outV.setPname("");}else{//处理的是商品表String[] split = line.split(" ");
//            System.out.println("=========> " + Arrays.toString(split)+" <=========");
//            System.out.println("=========> " + split[1] +" <=========");//封装outK.set(split[0]);//pid作为keyoutV.setId("");outV.setPid(split[0]);outV.setAmount(0);outV.setTableName("pd");outV.setPname(split[1]);}//写出context.write(outK, outV);}
}
  1. 实现reduce类
    • 为了分辨map传递过来的数据是哪个表,给bean对象添加一个表名属性
    • 在mapper类中给对应表的抓取过程中添加标记
    • 在获取到value时不能直接使用等于号进行赋值,values是Iterable集合,比较特殊
    • 属性赋值工具类BeanUtils.copyProperties(dest, src);
public class TableReducer extends Reducer<Text, TableBean, TableBean, NullWritable> {private ArrayList<TableBean> orderBeans;private TableBean pdBean;@Overrideprotected void setup(Reducer<Text, TableBean, TableBean, NullWritable>.Context context) throws IOException, InterruptedException {//1.创建集合orderBeans = new ArrayList<>();pdBean = new TableBean();}@Overrideprotected void reduce(Text key, Iterable<TableBean> values, Reducer<Text, TableBean, TableBean, NullWritable>.Context context) throws IOException, InterruptedException {orderBeans.clear();//清空集合//2.遍历赋值for (TableBean value : values) {if ("order".equals(value.getTableName())) {TableBean temp = new TableBean();try {BeanUtils.copyProperties(temp,value);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}orderBeans.add(temp);} else {//商品表try {BeanUtils.copyProperties(pdBean, value);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}}//循环遍历orderBeans,赋值pdnamefor (TableBean orderBean : orderBeans) {orderBean.setPname(pdBean.getPname());context.write(orderBean,NullWritable.get());}}
}

总结:这种写法,在reduce阶段创建了对象和集合,这些方式都是比较消耗资源的,容易造成数据倾斜问题。

MR在环形缓冲区快排时倒排索引,反向溢写,会导致数据反向输出,类似栈结构的的先进后出。

相关文章:

MR源码解析和join案例

MR源码解析 new Job(): 读取本地文件, xml配置job.start(): 启动线程job的run():线程方法 runTasks(): 传入对应的接口&#xff0c;启动map或者reduceMapTask类的run(): 设置map阶段的参数&#xff0c;初始化任务&#xff0c;创建上下文对象 创建读取器LineRecordReader判断是…...

ML+LLMs:利用LLMs大语言模型赋能或者结合ML机器学习算法进行具体应用的简介、具体案例之详细攻略

ML+LLMs:利用LLMs大语言模型赋能或者结合ML机器学习算法进行具体应用的简介、具体案例之详细攻略 目录 利用LLMs赋能或者结合ML算法进行具体应用的简介...

python GIL锁

1、GIL是什么 GIL&#xff1a;Global Interpreter Lock又称全局解释器锁。简单来说是一个互斥锁&#xff0c;每个线程在执行的过程中都需要先获取GIL&#xff0c;作用就是限制多线程同时执行&#xff0c;使得在同一进程内任何时刻仅有一个线程在执行。 由于GIL的存在&#xff0…...

git打tag和版本控制规范

我们在开发中经常会遇到要打tag的情况&#xff0c;但这个tag应该如何打呢&#xff1f;我不知道大家平时是怎么打的&#xff0c;但我基本就是从1.0.0开始进行往上递增&#xff0c;至于如何递增&#xff0c;基本凭感觉。今天同事新打了一个tag进行发版&#xff0c;然后被架构点名…...

php版 短信跳转微信小程序

实现这功能首先&#xff0c;小程序端添加业务域名 php代码 <?php declare (strict_types1);namespace app\controller\Admin;use app\model\Set; use app\Request;class Admin_Url_Scheme {public function getScheme(Request $request) {$appid 小程序appid;$secret 小…...

leetcode127单词接龙刷题打卡

127. 单词接龙 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk&#xff1a; 每一对相邻的单词只差一个字母。对于 1 < i < k 时&#xff0c;每个 si 都在 wordList 中。注意&am…...

基于SSM的物流管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

EagleSDR USB HAT FT600

给EagleSDR做了个USB 3.0的子卡&#xff0c;采用FT600方案&#xff0c;实物如下&#xff1a; 用FT600DataStreamerDemoApp测试&#xff0c;速度如下&#xff1a; 由于FT600是16bit的接口&#xff0c;如果用FT601的32bit接口&#xff0c;性能应该还会有大幅提升。 测试代码很简…...

Java多线程(四)锁策略(CAS,死锁)和多线程对集合类的使用

锁策略&#xff08;CAS&#xff0c;死锁&#xff09;和多线程对集合类的使用 锁策略 1.乐观锁VS悲观锁 2.轻量级锁VS重量级锁 3.自旋锁VS挂起等待锁 4.互斥锁VS读写锁 5.可重入锁vs不可重入锁 死锁的第一种情况 死锁的第二种情况 死锁的第三种情况 CAS 1.实现原子类 …...

基于spring boot+ vue+ mysql开发的UWB室内外定位系统源码

现代制造业厂区面积大、人员数量多、物资设备不断增加&#xff0c;随着工业信息化技术的发展&#xff0c;大型制造企业中对人员、车辆、物资的管理要求越来越细致。 高精度定位管理系统使用UWB室内定位技术&#xff0c;通过在厂区安装定位基站&#xff0c;为人员或设备佩戴定位…...

第2章_瑞萨MCU零基础入门系列教程之面向过程与面向对象

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…...

数字图像处理:亮度对比度-几何变换-噪声处理

文章目录 数字图像增强亮度与对比度转换几何变换图像裁剪尺寸变换图像旋转 噪声处理添加噪声处理噪声 数字图像增强 亮度与对比度转换 图像变换可分为以下两种&#xff1a; 点算子&#xff1a;基于像素变换&#xff0c;在这一类图像变换中&#xff0c;仅仅根据输入像素值计算…...

maven报错:[ERROR] 不再支持源选项 7。请使用 8 或更高版本。

解决方案 pom.xml文件中增加maven编译的java.version jdk版本设置&#xff0c;以及maven.compiler.source 资源编译jdk版本设置和maven.compiler.target 资源构建jdk版本设置 JDK&#xff1a;6~8 一般都是1.6&#xff0c;1.7&#xff0c;1.8的写法。 <properties><…...

MySQL基础3-约束

MySQL基础3-约束 一. 约束概述1.1 概念1.2 目的1.3 分类 二. 约束演示三. 外键约束3.1 概念3.2 语法三. 删除/更新行为 一. 约束概述 1.1 概念 约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据 1.2 目的 保证数据库中数据的正确、有效性和完整…...

OJ练习第166题——课程表(拓扑排序问题)

课程表 力扣链接&#xff1a;207. 课程表 题目描述 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表…...

单臂路由实现VLAN间路由

单臂路由实现VLAN间路由 单臂路由 概述拓扑图PC配置LSW2 接入层交换机LSW3 接入层交换机LSW1 汇聚层交换机R1 路由器ping 测试 单臂路由 概述 单臂路由的原理是通过一台路由器&#xff0c;使 VLAN 间互通数据通过路由器进行三层转发。 如果在路由器上为每个 VLAN 分配一个单独…...

【VSCode】文件模板创建及使用.md

背景 最近使用VSCode学习Vue项目比较频繁&#xff0c;每次创建Vue文件都要手动写重复代码&#xff0c;特别麻烦&#xff0c;就上网查找自动生成代码的说明&#xff0c;结果发现VSCode有代码模板&#xff0c;怪怪&#xff0c;感觉发现新大陆了(low!)。 配置 打开配置 方式一&a…...

【漏洞复现】EnjoySCM存在文件上传漏洞

漏洞描述 EnjoySCM是一款适应于零售企业的供应链管理软件,主要为零售企业的供应商提供服务。EnjoySCM的目的是通过信息技术,实现供应商和零售企业的快速、高效、准确的信息沟通、管理信息交流。。 该系统存在任意文件上传漏洞,攻击者通过漏洞可以获取服务器的敏感信息。 …...

MaPLe: Multi-modal Prompt Learning

本文也是LLM系统的文章&#xff0c;主要是面向多模态的大语言模型&#xff0c;针对《MaPLe: Multi-modal Prompt Learning》的翻译。 MaPLe&#xff1a;多模态提示学习 摘要1 引言2 相关工作3 方法4 实验5 结论 摘要 CLIP等预先训练的视觉语言&#xff08;V-L&#xff09;模型…...

软件测试/测试开发丨Jenkins Pipeline 学习笔记

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/26711 1. Jenkins节点 1.1 常用的节点 内建节点SSH节点Java Web节点 1.1.1 SSH节点配置 远程工作目录 节点中必须有该目录&#xff0c;用于下载和运行j…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

linux设备重启后时间与网络时间不同步怎么解决?

linux设备重启后时间与网络时间不同步怎么解决&#xff1f; 设备只要一重启&#xff0c;时间又错了/偏了&#xff0c;明明刚刚对时还是对的&#xff01; 这在物联网、嵌入式开发环境特别常见&#xff0c;尤其是开发板、树莓派、rk3588 这类设备。 解决方法&#xff1a; 加硬件…...

Web APIS Day01

1.声明变量const优先 那为什么一开始前面就不能用const呢&#xff0c;接下来看几个例子&#xff1a; 下面这张为什么可以用const呢&#xff1f;因为复杂数据的引用地址没变&#xff0c;数组还是数组&#xff0c;只是添加了个元素&#xff0c;本质没变&#xff0c;所以可以用con…...

使用python进行图像处理—图像变换(6)

图像变换是指改变图像的几何形状或空间位置的操作。常见的几何变换包括平移、旋转、缩放、剪切&#xff08;shear&#xff09;以及更复杂的仿射变换和透视变换。这些变换在图像配准、图像校正、创建特效等场景中非常有用。 6.1仿射变换(Affine Transformation) 仿射变换是一种…...

ABB馈线保护 REJ601 BD446NN1XG

配电网基本量程数字继电器 REJ601是一种专用馈线保护继电器&#xff0c;用于保护一次和二次配电网络中的公用事业和工业电力系统。该继电器在一个单元中提供了保护和监控功能的优化组合&#xff0c;具有同类产品中最佳的性能和可用性。 REJ601是一种专用馈线保护继电器&#xf…...