MapReduce案例之WordCount源码

一. 流程图

二. WordCount代码

大致流程如下:

第一阶段: 开发Map阶段

第二阶段: 开发Reduce阶段

第三阶段: 组装Job

完整代码如下:

package MapReduce;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
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;

import java.io.IOException;

/**
 *  需求: 读取hdfs上的hello.txt文件,计算文件中每个单词出现的总次数
 *
 *  原始文件hello.txt内容如下:
 *  hello you
 *  hello me
 *
 *  执行结果如下:
 *  hello 2
 *  me    1
 *  you   1
 */
public class WordCountJob {
    public static String serverIP = "192.168.247.5" ;
    public static String serverPort = "9000" ;

    //针对Map阶段,我们只需要实现 map函数就可以了,其他的框架会帮助我们自动实现
    public static class MyMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
        @Override
        protected void map(LongWritable k1, Text v1, Context context) throws IOException, InterruptedException {
            //k1代表每一行数据的行首偏移量
            //v1代表每一行内容
            String[] words = v1.toString().split(" ");
            //迭代切割出来的单词数据
            for(String word : words){
                //把迭代出来的单词封装为<k2,v2>形式
                Text k2 = new Text(word);
                LongWritable v2 = new LongWritable(1L);
                //把<k2,v2>写出去
                context.write(k2,v2);
            }
        }
    }
    //针对Reduce阶段,只需要实现reduce函数即可,其他框架会帮你实现
    public static class MyReducer extends Reducer<Text,LongWritable,Text,LongWritable>{
        @Override
        protected void reduce(Text k2, Iterable<LongWritable> v2s, Context context) throws IOException, InterruptedException {
            //针对k2,{v2....vn}的数据进行累加求和,并把最终数据转化为k3,v3写出去
            //创建一个sum,保存v2+v3+....+vn之和
            long sum = 0L;
            for (LongWritable v2:v2s){
                sum += v2.get();
            }
            //组装 k3,v3
            Text k3 = k2;
            LongWritable v3 = new LongWritable(sum);
            //把结果写出去
            context.write(k3,v3);
        }
    }

    /*
     *组装一个Job
     *job = Map + Reduce
     */
    public static void main(String[] args){
        try {
            if(args.length != 2){
                //参数1 读取文件路径
                //参数2 输出文件路径,只能指定一个不存在的目录
                System.exit(100);
            }
            //指定Job需要的配置参数
            Configuration conf = new Configuration();
            /*
            String confString = "hdfs://" + serverIP + ":" + serverPort ;
            //core-site.xml 里面的内容
            conf.set("fs.defaultFS", confString);
             */

            //创建一个Job
            Job job = Job.getInstance(conf);
            //注意了,这行必须设置,否则在集群中执行的时候是找不到WordCountJob这个类的
            job.setJarByClass(WordCountJob.class);

            //指定输入路径(可以是文件,也可以是目录)
            FileInputFormat.setInputPaths(job,new Path(args[0]));
            //获取操作HDFS的对象,用于判断输出路径是否存在
            FileSystem fileSystem = FileSystem.get(conf);
            //判断HDFS是否存在,如果存在则删除它!
            if (fileSystem.exists(new Path(args[1]))) {
                //调用类自身方法删除已存在文件
                fileSystem.delete(new Path(args[1]),true);
                System.out.println("检测到输出文件已存在,已删除!");
            }
            FileOutputFormat.setOutputPath(job,new Path(args[1]));

            //指定Map相关的代码
            job.setMapperClass(MyMapper.class);
            job.setMapOutputKeyClass(Text.class);  //指定k2类型
            job.setMapOutputValueClass(LongWritable.class); //指定v2类型

            //指定reduce相关的代码
            job.setReducerClass(MyReducer.class);
            job.setOutputKeyClass(Text.class);  //指定k3类型
            job.setOutputValueClass(LongWritable.class); //指定v3类型

            //提交Job
            job.waitForCompletion(true);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

动态打包代码:

<?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>

    <groupId>org.example</groupId>
    <artifactId>Hadoop_BigData</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- hadoop的依赖 -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.2.0</version>
            <!-- provided表示这个依赖只在编译的时候使用,执行或打jar包的时候都不使用 -->
            <scope>provided</scope>
        </dependency>

        <!-- log后缀的依赖 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
            <!-- provided表示这个依赖只在编译的时候使用,执行或打jar包的时候都不使用 -->
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.30</version>
            <!-- provided表示这个依赖只在编译的时候使用,执行或打jar包的时候都不使用 -->
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- compiler插件, 设定JDK版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass></mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

进入CMD命令,cd 到项目根目录,然后执行mvn clean package -DskipTests,看到最后输出 BUILD_SUCCESS就说明执行成功了

生成的包为:D:\Desktop__MyDocment\Maven_Program\Hadoop_BigData\target\Hadoop_BigData-1.0-SNAPSHOT-jar-with-dependencies.jar

将此文件传到Linux系统上

执行:hadoop jar Hadoop_BigData-1.0-SNAPSHOT-jar-with-dependencies.jar MapReduce.WordCountJob /test/hello.txt /out

查看执行的结果:

最后说一下:hadoop jar Hadoop_BigData-1.0-SNAPSHOT-jar-with-dependencies.jar MapReduce.WordCountJob /test/hello.txt /out 这个命令

(1) hadoop 表示使用hadoop脚本提交任务,其实这里使用yarn脚本也是可以的,从hadoop2开始支持使用yarn,不过为了兼容hadoop1,也继续支持使用hadoop脚本。

(2) jar 表示执行jar包

(3) Hadoop_BigData-1.0-SNAPSHOT-jar-with-dependencies.jar  是jar包名称

(4) MapReduce.WordCountJob 表示mapreduce代码全路径

(5) /test/hello.txt 输入文件路径,如果指定一个目录,会遍历该目录所有文件

(6) /out  输出文件目录

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值