【大数据之Hadoop】八、MapReduce之序列化
1 概述

序列化:
把内存中的对象,转换成字节序列(或其他数据传输协议),以便于存储到磁盘(持久化)和网络传输。
反序列化:
将收到字节序列(或其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象。
序列化原因:
服务器间不能传递内存中的对象,对象只能在本地的进程中使用;所以通过将内存中的对象序列化和反序列化的方式进行传递。

不用Java序列化的原因:
Java的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传输。
Hadoop序列化只附带了一些简单的校验信息。
优点:
(1)结构紧凑:高效利用存储空间。
(2)快速:读写额外开销小。
(3)互操作:支持多语言交互。
2 自定义bean对象实现序列化接口(Writable)
当基本序列化类型(第三章 1.4 部分)不能满足所有需求,比如在Hadoop框架内部传递一个bean对象,那么该对象就需要实现序列化接口。
步骤:
(1)必须实现Writable接口。
(2)反序列化时,需要反射调用空参构造函数,所以必须有空参构造。
public FlowBean() {super();
}
(3)重写序列化方法。
@Override
public void write(DataOutput out) throwsIOException {out.writeLong(upFlow);out.writeLong(downFlow);out.writeLong(sumFlow);
}
(4)重写反序列化方法。
@Override
public void readFields(DataInput in)throws IOException {upFlow= in.readLong();downFlow= in.readLong();sumFlow= in.readLong();
}
(5)反序列化的顺序和序列化的顺序完全一致(先进先出原则)。
(6)想把结果显示在文件中(因为默认传输的是地址值),需要重写toString(),可用"\t"分开,方便后续用。
(7)如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框中的Shuffle过程要求对key必须能排序。
@Override
public int compareTo(FlowBean o) {//倒序排列,从大到小returnthis.sumFlow > o.getSumFlow() ? -1 : 1;
}
3 序列化案例

步骤:
(1)创建一个Bean实现Writable接口,创建构造函数getter和setter,重写序列化方法write(…)和反序列化方法readFields(…)以及输出函数toString()
package com.study.mapreduce.Flow;import org.apache.hadoop.io.Writable;import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;public class FlowBean implements Writable {private long upFlow; //上行流量private long downFlow; //下行流量private long sumFlow; //总流量public FlowBean() {}public long getUpFlow() {return upFlow;}public long getDownFlow() {return downFlow;}public long getSumFlow() {return sumFlow;}public void setUpFlow(long upFlow) {this.upFlow = upFlow;}public void setDownFlow(long downFlow) {this.downFlow = downFlow;}public void setSumFlow() {this.sumFlow = this.upFlow + this.downFlow;}// 反序列化的顺序和序列化的顺序完全一致(先进先出原则)。@Overridepublic void write(DataOutput dataOutput) throws IOException {dataOutput.writeLong(upFlow);dataOutput.writeLong(downFlow);dataOutput.writeLong(sumFlow);}@Overridepublic void readFields(DataInput dataInput) throws IOException {this.upFlow = dataInput.readLong();this.downFlow = dataInput.readLong();this.sumFlow = dataInput.readLong();}@Overridepublic String toString() {return " " + upFlow +" " + downFlow +" " + sumFlow ;}
}
(2)创建Mapper类继承Mapper泛型,Mapper泛型<输入key,输入value,输出key,输出value>,重写map(…)函数,对数据进行切割封装。
输入key一般都是默认的类型LongWritable,输入value为一行数据则为Text;输出key为字符类型即Text,输出value为Bean,Bean中封装有别的内容。
package com.study.mapreduce.Flow;import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;//Mapper泛型<输入key,输入value,输出key,输出value>
//输入key一般都是默认的类型LongWritable,输入value为一行数据则为Text
//输出key为电话号码,为字符类型即Text,输出value为FlowBean,FlowBean中封装有别的内容
public class FlowMapper extends Mapper<LongWritable, Text, Text, FlowBean> {private Text outK = new Text();private FlowBean outV = new FlowBean();@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {//1 获取一行数据,转成字符串//1 13498787894 120.196.100.99 www.baidu.com 1116 954 200String line = value.toString();//2 切割数据//1,13498787894,120.196.100.99,www.baidu.com,1116,954,200String[] split = line.split(" ");//3 抓取我们需要的数据:手机号,上行流量,下行流量String phone = split[1];String up = split[split.length - 3];String down = split[split.length - 2];//4 封装outK outVoutK.set(phone);outV.setUpFlow(Long.parseLong(up)); //Long.parseLong():把string类型转为long型outV.setDownFlow(Long.parseLong(down));outV.setSumFlow();//5 写出outK outVcontext.write(outK, outV);}
}
(3)创建Reducer类继续Reducer泛型,重写reduce(…)函数,对数据进行整合封装。reduce方法是相同的key调用一次
reduce的输入key,value为mapper的输出key,value;reduce的输出key,value为自己指定类型为Text,Bean。
package com.study.mapreduce.Flow;import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;//reducer的输入kv为mapper的输出kv
public class FlowReducer extends Reducer<Text, FlowBean, Text, FlowBean> {private FlowBean outV = new FlowBean();@Overrideprotected void reduce(Text key, Iterable<FlowBean> values, Context context) throws IOException, InterruptedException {//reduce方法是相同的key调用一次long totalUp = 0;long totalDown = 0;//1 遍历values,将其中的上行流量,下行流量分别累加for (FlowBean flowBean : values) {totalUp += flowBean.getUpFlow();totalDown += flowBean.getDownFlow();}//2 封装outKVoutV.setUpFlow(totalUp);outV.setDownFlow(totalDown);outV.setSumFlow();//3 写出outK outVcontext.write(key,outV);}
}
(4)创建Driver类,写法固定。
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {//1 获取job对象Configuration conf = new Configuration(true);Job job = Job.getInstance(conf);//2 关联本Driver类job.setJarByClass(FlowDriver.class);//3 关联Mapper和Reducerjob.setMapperClass(FlowMapper.class);job.setReducerClass(FlowReducer.class);//4 设置Map端输出KV类型job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(FlowBean.class);//5 设置程序最终输出的KV类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(FlowBean.class);//6 设置程序的输入输出路径FileInputFormat.setInputPaths(job, new Path("D:\\inputflow"));FileOutputFormat.setOutputPath(job, new Path("D:\\outputflow"));//7 提交Jobboolean b = job.waitForCompletion(true);System.exit(b ? 0 : 1);}
相关文章:
【大数据之Hadoop】八、MapReduce之序列化
1 概述 序列化: 把内存中的对象,转换成字节序列(或其他数据传输协议),以便于存储到磁盘(持久化)和网络传输。 反序列化: 将收到字节序列(或其他数据传输协议)…...
Python网络爬虫之Selenium详解
1、什么是selenium? Selenium是一个用于Web应用程序测试的工具。Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。支持通过各种driver(FirfoxDriver,IternetExplorerDriver,OperaDriver,ChromeDriver)驱动真实浏览器…...
中睿天下受邀出席电促会第五次会员代表大会
3月21日,中国电力发展促进会(以下简称“电促会”)第五次会员代表大会暨第五届理事会第一次会议在京召开,中睿天下作为网络安全专业委员会会员单位受邀出席。 会议表决通过了第五次会员代表大会工作报告、第四届理事会财务报告、《…...
Chat GPT:软件测试人员的危机?
Chat GPT,作为一个引起科技巨头“红色警报”的人工智能语言模型,短期内便席卷全球,上线仅两个月活跃用户破亿。比尔盖茨更是如此评价“这种AI技术出现的重大历史意义,不亚于互联网和个人电脑的诞生。” 在各个行业备受关注的Chat …...
【Redis】高可用:Redis的主从复制是怎么实现的?
【Redis】高可用:主从复制详解 我们知道要避免单点故障,即保证高可用,便需要冗余(副本)方式提供集群服务。而Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。…...
WLAN速度突然变慢
目录 一、问题 二、在设置中重置网络 1. 按下组合键“WinI”打开设置,在设置窗口中点击“网络和Internet”。 2、点击左侧的“状态”,在右侧选择“网络重置”。 3、然后会进入“网络重置”页面,点击“立即重置”后点击“是”等待完成即可…...
GDAL python教程基础篇(12)GDAL和 Pillow 的互操作
GDAL和 Pillow GDAL和PIL处理和操作的对象都是栅格图像。 但它们又不一样。 GDAL主要重点放在地理或遥感数据的读写和数据建模以及地理定位和转换, 但是PIL的重点是放在图像本身处理上的。 至于在底层数据处理上,两者都可以用 numpy 转化的二进制作为数…...
快速学习java路线建议
还有2 ,3个月就要毕业了,啥都不会的你是不是很慌呢,是不是想知道怎么样快速学习java呢。嘿嘿!它来了。 首先是java的学习 ,推荐 【尚硅谷】7天搞定Java基础,Java零…...
【MySQL】深入浅出主从复制数据同步原理
【MySQL】深入浅出主从复制数据同步原理 参考资料: 全解MySQL之主从篇:死磕主从复制中数据同步原理与优化 MySQL 日志:undo log、redo log、binlog 有什么用? 文章目录【MySQL】深入浅出主从复制数据同步原理一、主从复制架构概述…...
Redis持久化和高可用
Redis持久化和高可用一、Redis持久化1、Redis持久化的功能2、Redis提供两种方式进行持久化二、RDB持久化1、触发条件2、bgsave执行流程3、启动时加载三、Redis高可用1、什么是高可用2、Redis高可用技术四、AOF持久化(支持秒级写入)1、开启AOF2、执行流程…...
【数据结构】第六站:栈和队列
目录 一、栈 1.栈的概念和结构 2.栈的实现方案 3.栈的具体实现 4.栈的完整代码 5.有效的括号 二、队列 1.队列的概念及结构 2.队列的实现方案 3.队列的实现 4.队列实现的完整代码 一、栈 1.栈的概念和结构 栈:一种特殊的线性表,其只允许在固定…...
python matplotlib 绘制训练曲线 综合示例——平滑处理、图题设置、图例设置、字体大小、线条样式、颜色设置
文章目录1 导出曲线数据2 python简单的 绘制曲线3 Savitzky-Golay 滤波器--平滑曲线4 对y轴数值缩放处理5 设置图题、图例、字体、网格、保存曲线图6 补充6.1 python 曲线平滑处理——方法总结-详解6.2 Tensorboard可视化训练曲线导出数据用Python绘制6.3 PyTorch可视化工具-Te…...
vue-element-plus-admin整合后端实战——实现系统登录、缓存用户数据、实现动态路由
目标 整合vue-element-plus-admin前端框架,作为开发平台的前端。 准备工作 前端选用vue-element-plus-admin,地址 https://gitee.com/kailong110120130/vue-element-plus-admin。 首先clone项目,然后整合到开发平台中去。这是一个独立的前…...
Shader Graph2-PBR介绍之表面属性(图解)
PBR的实现由光线和表面属性决定,下面我们介绍一下表面属性。这个5个属性在ShaderGraph的根节点是经常的看到,左侧是Unity中的,右侧是UE中的。 在没有Metallic金属的情况下,基础颜色值就决定了颜色的漫反射值,也就是说基…...
Java多线程编程,Thread类的基本用法讲解
文章目录如何创建一个线程start 与 run线程休眠线程中断线程等待获取线程实例如何创建一个线程 之前我们介绍了什么是进程与线程,那么我们如何使用代码去创建一个线程呢?线程操作是操作系统中的概念,操作系统内核实现了线程这样的机制&#…...
TIA博途Wincc_多路复用变量的使用方法示例(实现多台相同设备参数的画面精简)
TIA博途Wincc_多路复用变量的使用方法示例(实现多台相同设备参数的画面精简) 使用多路复用变量的好处: 当项目中存在多个相同的设备(例如:变频器、电机等),对这些设备在HMI上进行监控或修改参数时,不再需要逐个建立画面或IO域等,只需通过单个画面或IO域组合即可实现对…...
关于console你不知道的那些事
看到标题,大家会不会想,我都在前端岗位叱咤风云这么多年了, console 这个玩意用你讲 但是, 今天我将带你看到不一样的 console, 可以带来更多的帮助 了解 console 什么是 console ? console 其实是 JavaScript 内的一个原生对象。内部存储的方法大部…...
Java设计模式-责任链模式
1 概述 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同…...
顺序表设计循环队列
使用顺序表来设计队列的最大优势是顺序表有可以定位元素的下标。 并且可以以Mod来使数组下标循环 #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h> typedef int CQDataType; typedef struct { int* array; in…...
UEFI 基础教程 (十四) - 设置默认启动项为UEFI Shell
一 编写源代码 OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c UINTN BootOptionPriority ( CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { DEBUG ((EFI_D_ERROR," [CSDN] BootOptionPriority %S .\n", BootOption->Description)); if (StrCmp (…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
