MapReduce案例-电影网站数据统计分析

本文适合大数据初学者学习MapReduce统计分析业务问题的步骤和基础的MapReduce编程方法,初步掌握Hadoop对计算任务的管理。

本文末尾有全部数据集和完整代码连接。

1.准备工作

安装Hadoop:Hadoop 3.3.2 离线安装-CSDN博客

按照好Hadoop之后要检查一下datanode运行情况,Hadoop3.x的默认端口是9870

http://10.16.60.31:9870/

2.上传数据文件到HDFS

准备数据集

将数据上传到HDFS

[root@master sbin]# hadoop fs -mkdir -p /mapred-case
[root@master sbin]# hadoop fs -put /home/国家.txt /mapred-case/国家.txt
[root@master sbin]# hadoop fs -put /home/类型.txt /mapred-case/类型.txt
[root@master sbin]# hadoop fs -put /home/评分.txt /mapred-case/评分.txt
[root@master sbin]# hadoop fs -put /home/评价.txt /mapred-case/评价.txt
[root@master sbin]# hadoop fs -chmod a+w /mapred-case

3.编写统计分析代码

3.1 Windows系统配置Hadoop开发环境

windows开发调试Hadoop代码需要下载编译好的Hadoop二进制包。

还要下载winutils放到Hadoopbin目录

winutils下载地址吴所谓/winutils

注意这里Hadoop版本服务器Hadoop版本虽然不一致但是不影响程序调试

并且windowsHadoop不需要启动因为这个步骤只是为了解决MapReduce程序运行开始检测Hadoop环境报错问题

配置Hadoop环境变量并且D:\Dataware\data_cmpt\hadoop\hadoop-2.8.5\bin 添加到Path环境变量

3.2新建maven工程添加Hadoop 依赖配置信息

    <dependencies><!-- Hadoop相关依赖包--><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>3.3.1</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>3.3.1</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>3.3.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

resources目录增加core-site.xml文件,并添加如下配置信息

    <property><!-- URI 定义主机名称和 namenode 的 RPC 服务器工作的端口号 --><name>fs.defaultFS</name><value>hdfs://10.16.60.31:8020</value></property>

resources目录增加mapred-site.xml文件,并添加如下配置信息

<configuration><!-- 远程提交到 Linux 的平台上 --><property><name>mapred.remote.os</name><value>Linux</value><description>Remote MapReduce framework's OS, can be either Linux or Windows</description></property><!--允许跨平台提交 解决 /bin/bash: line 0: fg: no job control  --><property><name>mapreduce.app-submission.cross-platform</name><value>true</value></property>
</configuration>

添加log4j.properties文件用于配置日志输出信息

log4j.appender.A1.Encoding=UTF-8
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n

3.3. 按照国家和地区统计电影的产地信息

首先看下国家.txt数据

新建Map用于统计文档单词信息

    // Mapper抽象类的核心方法,三个参数public void map(Object key, // 首字符偏移量Text value, // 文件的一行内容Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {String[] ars = value.toString().split("['.;,?| \t\n\r\f]");for (String tmp : ars) {if (tmp == null || tmp.length() <= 0) {continue;}word.set(tmp);context.write(word, one);}}

新建Reduce用于文档每个单词出现次数

    // Reducer抽象类的核心方法,三个参数public void reduce(Text key, // Map端 输出的 key 值Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {int sum = 0;for (IntWritable val : values) // 遍历 values集合,并把值相加{sum += val.get();}map.put(key.toString(), sum);System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + ":" + key + "出现了" + sum);}

新建主程序

public class CountryMain {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();//        if (args.length != 2) {
//            System.exit(2);
//        }String input = "/mapred-case/国家.txt";String output = "/mapred-case/国家分布统计";Job job = new Job(conf, "CountryCount"); // 新建一个 job,传入配置信息job.setJarByClass(CountryMain.class); // 设置 job 的主类job.setMapperClass(CountryMap.class); // 设置 job 的 Mapper 类job.setCombinerClass(CountryReduce.class); // 设置 job 的 作业合成类job.setReducerClass(CountryReduce.class); // 设置 job 的 Reducer 类job.setOutputKeyClass(Text.class); // 设置 job 输出数据的关键类job.setOutputValueClass(IntWritable.class); // 设置 job 输出值类FileInputFormat.addInputPath(job, new Path(input)); // 输入路径(数据所在目录)FileOutputFormat.setOutputPath(job, new Path(output)); // 输出路径(必须不存在的文件夹)boolean result = false;try {result = job.waitForCompletion(true);} catch (Exception e) {e.printStackTrace();}System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) +(result ? "电影类型(Country)统计完毕!!!" : "统计失败!!!"));}
}

IDEA启动主程序可以看到程序执行日志信息如下

浏览器打开Hadoop管理页面下载part-r-00000文件,并用记事本打开

可以看到电影数据已经按照国家这个分类统计出来了

3.4 电影评论数量排行榜

首先看下数据这是电影名称评论数量列表但是评论数量并不是有序我们需要电影名按照评论数量排序

新建一个Map,将文档中的电影评论数量存入一个HashMap并调用上一步排序函数进行排序

    protected void map(LongWritable k1, Text v1, Context context) throws IOException, InterruptedException {String line = v1.toString();String[] fields = line.split("\t");String province = fields[0];if (isNumeric(fields[1])){Integer critics = Integer.parseInt(fields[1]);map.put(province, critics);}}

新建一个启动创建一个Hadoop Job执行上一步统计排序函数

public class CommentMain {public static void main(String[] args) {try {// 运行jar包程序指令输入错误,直接退出程序
//            if (args.length != 2) {
//                System.exit(100);
//            }String input = "/mapred-case/评价.txt";String output = "/mapred-case/评价数量统计";Configuration conf = new Configuration();//job需要的配置参数Job job = Job.getInstance(conf, "CommentMain");//创建一个job作业job.setJarByClass(CommentMain.class);//设置入口类FileInputFormat.setInputPaths(job, new Path(input));//指定输入路径(可以是文件,也可以是目录)FileOutputFormat.setOutputPath(job, new Path(output));//指定输出路径(只能是指定一个不存在的目录)job.setMapperClass(CommentMap.class);// 指定K2的输出数据类型job.setMapOutputKeyClass(Text.class);// 指定v2的输出数据类型job.setMapOutputValueClass(IntWritable.class);// 指定Reduce阶段的相关类job.setNumReduceTasks(0);//提交作业jobjob.waitForCompletion(true);} catch (Exception e) {e.printStackTrace();}}
}

执行成功之后我们看下执行日志

浏览器打开Hadoop管理页面下载执行结果文件

看下执行结果电影名称已经按照评论数量降序排列

3.5 电影评分分布

首先看一下数据文档中电影评分

新建Map程序评分写入上下文

// Mapper抽象类的核心方法,三个参数public void map(Object key, // 首字符偏移量Text value, // 文件的一行内容Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {String[] ars = value.toString().split("\t\n");for (String tmp : ars) {if (tmp == null || tmp.length() <= 0) {continue;}word.set(tmp);context.write(word, one);}}

新建Reduce统计每个评分梳理放入HashMapkey评分value次数

    // Reducer抽象类的核心方法,三个参数public void reduce(Text key, // Map端 输出的 key 值Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {int sum = 0;for (IntWritable val : values) // 遍历 values集合,并把值相加{sum += val.get();}map.put(key.toString(), sum);System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + ":" + key + "出现了" + sum);}

新建MapReduce程序启动创建一个Job并执行

public class ScoreMain {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();//        if (args.length != 2) {
//            System.exit(2);
//        }String input = "/mapred-case/评分.txt";String output = "/mapred-case/评分分布";Job job = new Job(conf, "ScoreCount"); // 新建一个 job,传入配置信息job.setJarByClass(ScoreMain.class); // 设置 job 的主类job.setMapperClass(ScoreMap.class); // 设置 job 的 Mapper 类job.setCombinerClass(ScoreReduce.class); // 设置 job 的 作业合成类job.setReducerClass(ScoreReduce.class); // 设置 job 的 Reducer 类job.setOutputKeyClass(Text.class); // 设置 job 输出数据的关键类job.setOutputValueClass(IntWritable.class); // 设置 job 输出值类FileInputFormat.addInputPath(job, new Path(input)); // 文件输入FileOutputFormat.setOutputPath(job, new Path(output)); // 文件输出boolean result = false;try {result = job.waitForCompletion(true);} catch (Exception e) {e.printStackTrace();}System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + (result ? "电影评分(Score)统计完毕!!!" : "统计失败!!!"));}
}

执行统计结果如下

3.6 电影类型分布

数据电影分类

新建Map电影类型写入上下文

    // Mapper抽象类的核心方法,三个参数public void map(Object key, // 首字符偏移量Text value, // 文件的一行内容Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {String[] ars = value.toString().split("['.;,?| \t\n\r\f]");for (String tmp : ars) {if (tmp == null || tmp.length() <= 0) {continue;}word.set(tmp);context.write(word, one);}}

新建Reduce统计每个分类数量

    // Reducer抽象类的核心方法,三个参数public void reduce(Text key, // Map端 输出的 key 值Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似throws IOException, InterruptedException {int sum = 0;for (IntWritable val : values) // 遍历 values集合,并把值相加{sum += val.get();}map.put(key.toString(), sum);System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + ":" + key + "出现了" + sum);}

新建MapReduce程序启动创建一个Job并执行

public class TypeMain {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();//        if (args.length != 2) {
//            System.exit(2);
//        }String input = "/mapred-case/类型.txt";String output = "/mapred-case/类型分布";Job job = new Job(conf, "TypeCount"); // 新建一个 job,传入配置信息job.setJarByClass(TypeMain.class); // 设置 job 的主类job.setMapperClass(TypeMap.class); // 设置 job 的 Mapper 类job.setCombinerClass(TypeReduce.class); // 设置 job 的 作业合成类job.setReducerClass(TypeReduce.class); // 设置 job 的 Reducer 类job.setOutputKeyClass(Text.class); // 设置 job 输出数据的关键类job.setOutputValueClass(IntWritable.class); // 设置 job 输出值类FileInputFormat.addInputPath(job, new Path(input)); // 文件输入FileOutputFormat.setOutputPath(job, new Path(output)); // 文件输出boolean result = false;try {result = job.waitForCompletion(true);} catch (Exception e) {e.printStackTrace();}System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + (result ? "电影标签(Type)统计完毕!!!" : "统计失败!!!"));}
}

本文全部数据代码连接https://download.csdn.net/download/shangjg03/88596022

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/2380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在控制台实现贪吃蛇

在控制台实现贪吃蛇 前备知识Win32APICOORD这个结构体的声明如下&#xff1a;GetStdHandle 函数GetConsoleCursorInfo 函数SetConsoleCursorInfo 函数 SetConsoleCursorPosition 函数getAsyncKeyState 函数 控制台窗口的大小以及字符打印介绍控制台中的坐标宽字符及本地化介绍s…

SRS服务接入华为云CDN

CDN简介: CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网…

SSH远程连接docker容器-Linux-SSH -L 打隧道

问题&#xff1a;在物理机上用podman创建了一个容器&#xff0c;想SSH直接远程连接docker容器 解决方式&#xff1a; 步骤1: 在本地terminal输入以下命令&#xff1a; ssh -L 容器端口号:localhost:容器端口号 物理机用户名物理机ip -p 物理机端口号 即可&#xff0c;可新打…

centos7+mysql57安装以及初始化

1、下载安装yum官方mysql源&#xff1a; http://repo.mysql.com/ ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/061472a86e9e4548b76d4603d4614568.png rpm -ivh mysql57-community-release-el7.rpm2、yum安装mysql服务 yum install -y mysql-community-server…

423 世界读书日 和京东零售技术人一起读好书

我们正处于一个复杂、变化的世界&#xff0c;想要更好地理解、适应它&#xff0c;读书可能是最方便的方式之一。 4 月 23 日世界读书日&#xff0c;我们整理了 10 位零售技术人的书籍推荐给大家&#xff0c;欢迎大家一起来共读好书。愿大家在忙碌工作之余&#xff0c;都能够持…

从0到1实现RPC | 接入Apollo配置中心

一、代码实现 添加依赖 添加apollo客户端的依赖和spring配置相关依赖 添加监听器 通过实现ApplicationContextAware接口&#xff0c;获取Spring上下文。 使用ApolloConfigChangeListener注解监听命名空间rpc-demo-provider.yaml和默认的application.properties。 监听逻辑…

开源大模型王者归来:llama3最大4000亿参数,性能GPT4相当,超越Grok3140亿且全开源代码

llama3&Grok 目前开源的超级大模型有Gork和Llama3 https://github.com/xai-org/grok-1&#xff1b;该模型称为史上最大开源LLM&#xff0c;参数高达3140亿&#xff01;马斯克如约开源Grok&#xff0c;10小时狂揽10000颗Star&#xff0c;搞笑的是这个模型只开源了推理没有训…

17.Nacos与Eureka区别

Nacos会将服务的提供者分为临时实例和非临时实例。默认为临时实例。 临时实例跟eureka一样&#xff0c;会向注册中心报告心跳监测自己是否还活着。如果不正常了nacos会剔除临时实例。&#xff08;捡来的孩子&#xff09; 非临时实例&#xff0c;nacos会主动询问服务提供者是否…

古董展新风尚:山海鲸数据大屏引领科技潮流

在数字化浪潮的推动下&#xff0c;传统文化与现代科技正日益融合&#xff0c;展现出独特的魅力。近日&#xff0c;山海鲸推出了一款古董展览数据可视化大屏&#xff0c;将古董藏品的丰富内涵以直观、生动的形式呈现在观众面前&#xff0c;让人们在欣赏古董之美的同时&#xff0…

深入探索GDB:Linux下强大的调试神器

目录 一、GDB简介&#xff1a;源码级调试的基石 二、GDB基础操作&#xff1a;从入门到熟练 启动与基本命令 三、GDB进阶功能&#xff1a;解锁更深层次的调试能力 1. 回溯追踪&#xff1a;洞察调用栈 2. 动态内存检测&#xff1a;揪出内存问题 3. 条件断点与观察点&#…

制氢机远程监控运维方案

制氢机远程监控运维方案 在当今能源转型的大背景下&#xff0c;氢能作为清洁、高效且可再生的能源载体&#xff0c;其重要性日益凸显。而制氢机作为氢能产业链中的关键设备&#xff0c;其稳定运行与高效运维对于保障氢气供应、推动氢能产业健康发展至关重要。在此背景下&#…

基于Linux系统命令行安装KingbaseES数据库

人大金仓通用性数据库&#xff08;Kingbase&#xff09;下载网址&#xff1a;人大金仓-成为世界卓越的数据库产品与服务提供商 选择“软件版本-数据库”&#xff0c;筛选条件Linux、完整版。找到需要的版本&#xff0c;点击下载。我下载的是KingbaseES_V008R006C008B0014_Lin6…

实现Spring底层机制(二)

文章目录 阶段2—封装bean定义信息到Map1.代码框架图2.代码实现1.文件目录2.新增注解Scope存储单例或多例信息Scope.java3.修改MonsterService.java指定多例注解4.新增bean定义对象存储bean定义信息BeanDefinition.java5.修改pom.xml增加依赖6.修改容器实现bean定义信息扫描Sun…

nginx开启basic认证

basic认证也叫做http基本认证&#xff0c;防止恶意访问 首先用在线网站生成一个叫做htpasswd的账号密码文件。 将生成结果复制到/etc/nginx/htpasswd文件中 在server的location中配置 server { listen 80; server_name a.com;location / { root html;index index.…

springcloud alibaba 整合seata的TCC

一、seata服务端搭建同上篇。 Seata的AT模式客户端两阶段提交流程源码分析 二、seata客户端的结构 1.示例DEMO工程 下单&#xff0c;扣余额&#xff0c; 减库存。 2. MAVEN配置。 父工程&#xff1a;由于spring-cloud-starter-alibaba-seata依赖的seata-spring-boot-starter…

顺序栈着三种结构定义及其初始化

定义 顺序堆栈这三种结构定义及其初始化 - 知乎 (zhihu.com) 根据以上链接得到&#xff1a; 1.理解为数组&#xff0c;top是这个数组的索引值&#xff1b;定义这个结构体类型时&#xff0c;系统不分配空间 在主函数声明时&#xff0c;定义了关于这个结构体的变量&#xff0c…

Java 【数据结构】 二叉树(Binary_Tree)【神装】

登神长阶 第五神装 二叉树 Binary-Tree 目录 &#x1f3b7;一.树形结构 &#x1fa97;1.概念 &#x1f3b8;2.具体应用 &#x1f3b9; 二.二叉树&#xff08;Binary Tree&#xff09; &#x1f3ba;1.概念 &#x1f3bb;2.表现形式 &#x1fa95;3.特殊类型 &#x1f941…

自己手动在Linux上实现一个简易的端口扫描器

背景 常常听到网络攻击有一个东西叫做端口扫描器&#xff0c;可以扫描指定服务器开放的端口&#xff0c;然后尝试连接&#xff0c;并寻找漏洞&#xff0c;最终攻破服务器。而那些使用的端口扫描器都是一个个现成的程序&#xff0c;看上去很厉害的样子。而实际上这些东西对于懂…

【前端技术】HTML基础入门篇

1.1 HTML简介 ​ HTML&#xff08;HyperText Markup Language&#xff1a;超文本标记语言&#xff09;是一种标识性的语言。它包括一系列标签&#xff0e;通过这些标签可以将网络上的文档格式统一&#xff0c;使分散的Internet资源连接为一个逻辑整体。HTML文本是由HTML命令组…

投资网站汇总

1、 中信证券(600030)历年财务指标——亿牛网https://eniu.com/gu/sh600030/cwzb 2、 3、 4、