实验四:MapReduce中级编程实践

一、实验目的

  • L通过实验掌握基本的MapReduce编程方法;
  • 掌握用MapReduce解决一些常见的数据处理问题,包括数据去重计数、数据排序。

二、实验平台

  • 操作系统:Linux
  • Hadoop版本:3.3.1

三、实验步骤

实验所使用的文件链接:
链接:https://pan.baidu.com/s/16zyA_DZwu9anxjwdHnbMOw
提取码:57ky

(一)对访问同一个网站的用户去重计数。

 注:文件userurl_20150911中,数据以”\t”隔开,用户手机号为第三列,网站主域为第17列
package com.user.mapreduce.homework;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

import java.io.IOException;

public class UserCountDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        //1、获取job
        Configuration conf = new Configuration();

        Job job = Job.getInstance(conf);

        //2、获取jar包路径
        job.setJarByClass(UserCountDriver.class);

        //3、关联mapoer和reducer
        job.setMapperClass(UserCountMapper.class);
        job.setReducerClass(UserCountReducer.class);

        //4、设置map输出的key,value类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

        //5、设置最终输出的key,value类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //6、设置输入路径和输出路径
        FileInputFormat.setInputPaths(job,new Path("E:\\BigData\\homework\\hadoop作业\\userurl_20150911"));

        FileOutputFormat.setOutputPath(job,new Path("C:\\Users\\lenovo\\Desktop\\answer"));

        //7、提交job
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}

package com.user.mapreduce.homework;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;


public class UserCountMapper extends Mapper<Object, Text, Text, Text>{
    private Text outk = new Text();
    private Text outv = new Text();
    @Override
    protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] split = line.split("\t");
        outk.set(split[16]);
        outv.set(split[2]);
        context.write(outk,outv);
    }
}

package com.user.mapreduce.homework;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;
import java.util.*;

public class UserCountReducer extends Reducer<Text, Text, Text, IntWritable> {
    private IntWritable outv = new IntWritable();
    @Override
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
        HashMap<String, Boolean> hashMap = new HashMap<String, Boolean>();
        int num = 0;
        for (Text value : values) {
            String phone = value.toString();
            //if (null == phone) continue;
            if(hashMap.get(phone) != null) continue;
            hashMap.put(phone,true);
            ++num;
        }
        outv.set(num);
        context.write(key,outv);
    }
}

(二)对同一个用户不同记录产生的上下行流量求和后进行排序输出。

注:上行流量位于第25列,下行流量位于第26列
package com.user.mapreduce.homework;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

import java.io.IOException;

public class FlowDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        //1、获取job
        Configuration conf = new Configuration();

        Job job = Job.getInstance(conf);

        //2、获取jar包路径
        job.setJarByClass(FlowtDriver.class);

        //3、关联mapoer和reducer
        job.setMapperClass(FlowMapper.class);
        job.setReducerClass(FlowReducer.class);

        //4、设置map输出的key,value类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        //5、设置最终输出的key,value类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //6、设置输入路径和输出路径
        FileInputFormat.setInputPaths(job,new Path("E:\\BigData\\homework\\hadoop作业\\userurl_20150911"));
        FileOutputFormat.setOutputPath(job,new Path("C:\\Users\\lenovo\\Desktop\\answer"));

        //7、提交job
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}

package com.user.mapreduce.homework;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class FlowMapper extends Mapper<Object, Text, Text, IntWritable>{
    private Text outk = new Text();
    private IntWritable outv = new IntWritable();
    @Override
    protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] split = line.split("\t");
        outk.set(split[2]);
        outv.set(Integer.parseInt(split[24]) + Integer.parseInt(split[25]));
        context.write(outk,outv);
    }
}
package com.user.mapreduce.homework;

import com.user.mapreduce.writable.FlowBean;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;
import java.util.*;

public class FlowReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    private IntWritable outv = new IntWritable();
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        ArrayList<Integer> list = new ArrayList<>();
        for (IntWritable value : values) {
            list.add(value.get());
        }
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if(o1 > o2) return 1;
                if(o1 < o2) return -1;
                return 0;
            }
        });
        for (Integer integer : list) {
            outv.set(integer);
            context.write(key,outv);
        }
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,MapReduce是一种用于大规模数据处理的编程模型和计算框架。下面是一个简单的MapReduce程序的实现。 假设我们有一个大型的文本文件,里面包含了很多单词。我们想要统计每个单词在文件中出现的次数。这可以通过MapReduce来实现。 Map阶段: 1. 将文件分成多个小块,并分配给不同的计算节点。 2. 对于每个小块,计算节点会读取其中的内容,并将每个单词作为key,出现次数作为value,生成一系列键值对。 3. 计算节点将这些键值对按照key进行排序,并将相同key的value合并成一个列表。 Reduce阶段: 1. 将所有的key-value列表按照key进行排序。 2. 对于每个key,将其对应的value列表合并起来,得到该key在文件中出现的总次数。 下面是一个基于Python的MapReduce程序示例: ```python # mapper.py import sys # 从标准输入读取数据 for line in sys.stdin: # 删除行末尾的换行符 line = line.strip() # 将行按照空格分割成单词 words = line.split() # 对于每个单词,输出一个键值对 for word in words: print(word, 1) # reducer.py import sys current_word = None current_count = 0 # 从标准输入读取数据 for line in sys.stdin: # 删除行末尾的换行符 line = line.strip() # 分割键值对 word, count = line.split('\t', 1) # 将字符串类型的计数器转换为整数 count = int(count) # 如果当前单词与上一个单词不同,就输出上一个单词的统计结果 if current_word and current_word != word: print(current_word, current_count) current_count = 0 # 将计数器累加到当前单词的统计结果中 current_word = word current_count += count # 输出最后一个单词的统计结果 if current_word: print(current_word, current_count) ``` 我们可以使用Hadoop框架来运行这个MapReduce程序。具体的步骤如下: 1. 将文件上传到HDFS中。 2. 启动Hadoop集群。 3. 运行Mapper任务和Reducer任务: ``` $ hadoop jar /path/to/hadoop-streaming.jar \ -mapper "python mapper.py" \ -reducer "python reducer.py" \ -input "/path/to/input/file" \ -output "/path/to/output/folder" ``` 4. 在HDFS中查看输出文件。 这个MapReduce程序可以处理很大的数据集,并且可以在分布式计算环境中高效运行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值