• Hadoop-Mapreduce-英文单词计数


      1 package mapred;
      2 
      3 import java.io.IOException;
      4 import java.util.StringTokenizer;
      5 import org.apache.hadoop.conf.Configuration;
      6 
      7 import org.apache.hadoop.fs.Path;
      8 import org.apache.hadoop.io.IntWritable;
      9 import org.apache.hadoop.io.Text;
     10 import org.apache.hadoop.io.WritableComparable;
     11 import org.apache.hadoop.mapreduce.Job;
     12 import org.apache.hadoop.mapreduce.Mapper;
     13 
     14 import org.apache.hadoop.mapreduce.Reducer;
     15 import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
     16 import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;
     17 
     18 import org.apache.hadoop.mapreduce.lib.map.InverseMapper;
     19 import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
     20 import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
     21 import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
     22 
     23 public class WordCount {
     24 
     25     // 自定义Mapper静态内部Class 继承父类 Mapper类,进一步实现map过程
     26     public static class TokenizerMapper extends
     27             Mapper<Object, Text, Text, IntWritable> {
     28         public void map(Object key, Text value, Context context)
     29                 throws IOException, InterruptedException {
     30             System.out.println(key);
     31             // Key
     32             Text keyOut;
     33             // 定义整数1, 每个单词计数一次
     34             IntWritable valueOut = new IntWritable(1);
     35 
     36             // 构造一个用来解析输入value值的StringTokenizer对象
     37             StringTokenizer token = new StringTokenizer(value.toString());
     38             while (token.hasMoreTokens()) {
     39                 // 返回从当前位置到下一个分割符的字符串
     40                 keyOut = new Text(token.nextToken());
     41                 // map过程输出键值对:输出每个被拆分出来的单词,以及计数1
     42                 context.write(keyOut, valueOut);
     43             }
     44         }
     45     }
     46 
     47     // 自定义Reducer Class 继承父类 Reducer类,进一步实现reduce过程
     48     public static class IntSumReducer extends
     49             Reducer<Text, IntWritable, Text, IntWritable> {
     50         private IntWritable result = new IntWritable();
     51 
     52         public void reduce(Text key, Iterable<IntWritable> values,
     53                            Context context) throws IOException, InterruptedException {
     54             int sum = 0;
     55             for (IntWritable val : values) {
     56                 sum += val.get();
     57             }
     58             result.set(sum);
     59             context.write(key, result);
     60         }
     61     }
     62 
     63     // 自定义实现降序
     64     // Hadoop默认对IntWritable按升序排序,重写IntWritable.Comparator类实现降序
     65     private static class IntWritableDecreaseingComparator extends IntWritable.Comparator {
     66         @Override
     67         public int compare(WritableComparable a, WritableComparable b) {
     68             return -super.compare(a, b);// 比较结果取负数即可降序
     69         }
     70         @Override
     71         public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
     72             return -super.compare(b1, s1, l1, b2, s2, l2);
     73         }
     74     }
     75 
     76     // 入口
     77     public static void main(String[] args) throws Exception {
     78         // 任何作用的配置信息必须通过Configuration传递,通过Configuration可以实现在多个mapper和多个reducer任务之间共享信息
     79         Configuration conf = new Configuration();
     80 
     81         // 定义一个临时目录:hdfs://localhost:9000/wordcount1 是hdfs上不存在的目录(hdfs://localhost:9000/肯定存在)
     82         // 自定义一个临时目录,如果目录存在请先删除目录后,再运行
     83         Path tempDir = new Path("hdfs://localhost:9000/wordcount1");
     84 
     85         try {
     86             // 创建作业 job
     87             Job job = Job.getInstance(conf, "word count ");
     88 
     89             //  通过传入的WordCount类Class 设置job的jar包
     90             job.setJarByClass(WordCount.class);
     91 
     92             //  设置Mapper类Class
     93             job.setMapperClass(TokenizerMapper.class);
     94             //  设置Combine类Class
     95             job.setCombinerClass(IntSumReducer.class);
     96             //  设置Reducer类Class
     97             job.setReducerClass(IntSumReducer.class);
     98 
     99             // 自定义分区
    100             job.setNumReduceTasks(2);
    101 
    102             // 指定输出类型
    103             job.setOutputKeyClass(Text.class);//  设置输出Key类Class
    104             job.setOutputValueClass(IntWritable.class);//  设置输出Value类Class
    105 
    106             // 指定统计作业输出格式,和排序作业的输入格式应对应
    107             job.setOutputFormatClass(SequenceFileOutputFormat.class);
    108 
    109             // 指定待统计文件目录
    110             FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/words"));
    111 
    112             // 先将词频统计作业的输出结果写到临时目录中,下一个排序作业以临时目录为输入目录
    113             FileOutputFormat.setOutputPath(job, tempDir);
    114 
    115             // 提交job
    116             // waitForCompletion提交作业后,每秒会轮询作业进度,如果发现和上次报告后有改变,就把进度报告到控制台,
    117             // 作业完成后,如果成功就显示作业计数
    118             boolean result = job.waitForCompletion(true);
    119             if (result) {
    120                 // 创建作业 sortJob
    121                 Job sortJob = Job.getInstance(conf, "sort");
    122                 sortJob.setJarByClass(WordCount.class);
    123 
    124                 // 指定临时目录作为排序作业的输入
    125                 FileInputFormat.addInputPath(sortJob, tempDir);
    126 
    127                 // Hadoop 默认的是TextInputFormat和TextOutputFormat,此处可以显示地配置
    128                 sortJob.setInputFormatClass(SequenceFileInputFormat.class);
    129 
    130                 // 由Hadoop库提供,作用是实现map()后的数据对key和value交换
    131                 sortJob.setMapperClass(InverseMapper.class);
    132 
    133                 // 将Reducer的个数限定为1,最终输出的结果文件就是一个
    134                 sortJob.setNumReduceTasks(1);
    135 
    136                 // 最终输出目录,如果目录存在请先删除目录后,再运行
    137                 FileOutputFormat.setOutputPath(sortJob, new Path("hdfs://localhost:9000/wordcount2"));
    138 
    139                 //  设置输出Key类Class
    140                 sortJob.setOutputKeyClass(IntWritable.class);
    141                 //  设置输出Value类Class
    142                 sortJob.setOutputValueClass(Text.class);
    143                 // 一般情况下,mapper和reducer输出的数据类型是一样的,所以可以用上面两条命令;
    144                 // 如果不一样,可以用下面两条命令单独指定mapper输出的key、value数据类型
    145                 // job.setMapOutputKeyClass(Text.class);
    146                 // job.setMapOutputValueClass(IntWritable.class);
    147 
    148                 sortJob.setOutputFormatClass(TextOutputFormat.class);
    149                 // Hadoop 默认的是TextInputFormat和TextOutputFormat,此处可以显示地配置
    150                 // job.setInputFormatClass(TextInputFormat.class);
    151                 // job.setOutputFormatClass(TextOutputFormat.class);
    152 
    153                 // Hadoop默认对IntWritable按升序排序,重写IntWritable.Comparator类实现降序
    154                 sortJob.setSortComparatorClass(IntWritableDecreaseingComparator.class);
    155 
    156                 // 提交sortJob
    157                 // waitForCompletion提交作业后,每秒会轮询作业进度,如果发现和上次报告后有改变,就把进度报告到控制台,
    158                 // 作业完成后,如果成功就显示作业计数
    159                 boolean result2 = sortJob.waitForCompletion(true);
    160                 if (result2) {
    161                     System.out.println("***********ok************");
    162                 }
    163             }
    164         } catch (Exception ex) {
    165             ex.printStackTrace();
    166         }
    167     }
    168 }
    169 
    170 // 查看指定路径文件
    171 // hadoop fs -ls hdfs://localhost:9000/
    172 // 返回结果,如下:
    173 //Found 5 items
    174 //-rw-r--r--   3 jiangshan supergroup  573545760 2021-09-08 15:48 hdfs://localhost:9000/SBSNTEST111.txt
    175 //-rw-r--r--   3 jiangshan supergroup         28 2021-09-08 16:01 hdfs://localhost:9000/testcreate
    176 //drwxr-xr-x   - jiangshan supergroup          0 2021-09-08 19:39 hdfs://localhost:9000/wordcount1
    177 //drwxr-xr-x   - jiangshan supergroup          0 2021-09-08 19:39 hdfs://localhost:9000/wordcount2
    178 //-rw-r--r--   3 jiangshan supergroup  163254798 2021-09-08 16:56 hdfs://localhost:9000/words
    179 
    180 // 查看指定路径文件
    181 // hadoop fs -ls hdfs://localhost:9000/wordcount1
    182 // 返回结果,如下:
    183 //Found 3 items
    184 //-rw-r--r--   3 jiangshan supergroup          0 2021-09-08 19:54 hdfs://localhost:9000/wordcount1/_SUCCESS
    185 //-rw-r--r--   3 jiangshan supergroup      27888 2021-09-08 19:54 hdfs://localhost:9000/wordcount1/part-r-00000
    186 //-rw-r--r--   3 jiangshan supergroup      27364 2021-09-08 19:54 hdfs://localhost:9000/wordcount1/part-r-00001
    187 
    188 // 查看指定路径文件
    189 // hadoop fs -ls hdfs://localhost:9000/wordcount2
    190 // 返回结果,如下:
    191 //Found 2 items
    192 //-rw-r--r--   3 jiangshan supergroup          0 2021-09-08 19:54 hdfs://localhost:9000/wordcount2/_SUCCESS
    193 //-rw-r--r--   3 jiangshan supergroup      36850 2021-09-08 19:54 hdfs://localhost:9000/wordcount2/part-r-00000
    194 
    195 // 将路径指定文件的内容输出到stdout
    196 // hadoop fs -cat hdfs://localhost:9000/testcreate
    197 // 返回结果,文本文件内容
    198 // Hello Hadoop 888@Chinasofti
    个人学习记录
  • 相关阅读:
    怎么让图片居中显示?
    上传代码出现弹出框“请确保已在git中配置您的user.name和user.email”解决方法
    window.open()下载文件: 在当前页面打开方法
    修改网站颜色为黑白 (100% 灰度)/全页置灰
    ZMQ简单使用
    CCXT
    Python描述符详解
    自定义序列的修改、散列和切片
    使用__slots__类属性节省空间
    QGraphicsView实现虚拟摇杆
  • 原文地址:https://www.cnblogs.com/jeshy/p/15244712.html
Copyright © 2020-2023  润新知