[MapReduce]包括的なケース



包括的なケース

①データファイル

ここに画像の説明を挿入


②特定の要件

  • information.txt HDFSにアップロード
  • student.txt ローカルに置く
  • distribute缓存hdfsのデータを読み取ることにより
  • HDFSとローカルデータをJavaBeanオブジェクトにカプセル化します
  • オブジェクトはマップ側でカプセル化する必要があり、属性がNullであるオブジェクト内の属性の数は、出力される値の数としてreduce側で計算され、出力キーはBeanオブジェクトのtostringです。
  • パーティションは2つに設定されています。根据性别分区

③具体的な実現

•ファイルをアップロードする

ここに画像の説明を挿入


•Beanクラスをカプセル化します

package CSDN综合练习;

import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class Bean implements Writable {
    
    
    // 封装属性
    private String id;
    private String name;
    private String sex;
    private String hobby;
    private String job;
    // 无参构造器
    public Bean() {
    
    
    }
    // 重写toString
    @Override
    public String toString() {
    
    
        return "Bean{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", hobby='" + hobby + '\'' +
                ", job='" + job + '\'' +
                '}';
    }
    // 序列化
    @Override
    public void write(DataOutput dataOutput) throws IOException {
    
    
        dataOutput.writeUTF(id);
        dataOutput.writeUTF(name);
        dataOutput.writeUTF(sex);
        dataOutput.writeUTF(hobby);
        dataOutput.writeUTF(job);
    }
    // 反序列化
    @Override
    public void readFields(DataInput dataInput) throws IOException {
    
    
        id = dataInput.readUTF();
        name = dataInput.readUTF();
        sex = dataInput.readUTF();
        hobby = dataInput.readUTF();
        job = dataInput.readUTF();
    }
    // set\get
    public String getId() {
    
    
        return id;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getSex() {
    
    
        return sex;
    }

    public void setSex(String sex) {
    
    
        this.sex = sex;
    }

    public String getHobby() {
    
    
        return hobby;
    }

    public void setHobby(String hobby) {
    
    
        this.hobby = hobby;
    }

    public String getJob() {
    
    
        return job;
    }

    public void setJob(String job) {
    
    
        this.job = job;
    }
}

トップに戻る


•マッパークラスはinformation.txtをキャッシュし、student.txtとの接続を実現します

package CSDN综合练习;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.HashMap;

public class Mapper extends org.apache.hadoop.mapreduce.Mapper<LongWritable, Text,Text, Bean> {
    
    

    Bean bean = new Bean();
    HashMap map = new HashMap();
    /**
     *  缓存hdfs上的数据表
     * @param context
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
    
    
        try {
    
    
            // 获取缓存文件
            URI[] cacheFiles = context.getCacheFiles();
            // 通过缓存文件获取路径
            String path = cacheFiles[0].getPath().toString();
            System.out.println(path);
            // 读取文件信息
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path),"UTF-8"));
            String line;
            while (StringUtils.isNotEmpty(line = br.readLine())){
    
    
                // 游戏	大数据	1
                // 读取一行数据,拆分
                String[] fields = line.split("\t");
                map.put(fields[2],fields[0]+"\t"+fields[1]);
            }
            // 关闭资源
            IOUtils.closeStream(br);

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

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    
    
        // 1	张三	女
        // 读取一行数据,进行拆分
        String line = value.toString();
        String[] fields = line.split("\t");
        // 封装bean对象
        String id = fields[0];
        String name = fields[1];
        String sex = fields[2];
        String hobby = (String)map.get(id).toString().split("\t")[0];
        String job = (String)map.get(id).toString().split("\t")[1];
        bean.setId(id);
        bean.setName(name);
        bean.setSex(sex);
        bean.setHobby(hobby);
        bean.setJob(job);
        // 写出
        context.write(new Text(id),bean);
    }
}

トップに戻る


•Reducerクラスの統計オブジェクトの属性がNULLです

package CSDN综合练习;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;

public class Reduce extends Reducer<Text, Bean,Bean,LongWritable> {
    
    
    @Override
    protected void reduce(Text key, Iterable<Bean> values, Context context) throws IOException, InterruptedException {
    
    
        // 获取数据进行null值统计
        int count = 0;
        for (Bean bean:values){
    
    
            if (bean.getName()==null||bean.getName().equals("Null")){
    
    
                count++;
            }
            if (bean.getJob()==null||bean.getJob().equals("Null")){
    
    
                count++;
            }
            if (bean.getHobby()==null||bean.getHobby().equals("Null")){
    
    
                count++;
            }
            if (bean.getSex()==null||bean.getSex().equals("Null")){
    
    
                count++;
            }
            context.write(bean,new LongWritable(count));
        }
    }
}

トップに戻る


•Partitionクラスは、性別に応じたパーティショニングを実装します

package CSDN综合练习;

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;

public class Partition extends Partitioner<Text, Bean> {
    
    
    @Override
    public int getPartition(Text text,Bean bean, int numPartitions) {
    
    
        // 获取用户信息
        String sex = bean.getSex();
        // 指定分区数
        int partition = 1;
        if (sex.equals("男")){
    
    
            partition = 0;
        } else {
    
    
            partition = 1;
        }
        return partition;
    }
}

トップに戻る


•ドライバー構成

package CSDN综合练习;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
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 java.net.URI;

public class Driver {
    
    
    public static void main(String[] args) {
    
    
        Job job;
        Configuration conf = new Configuration();
        try {
    
    
            // 获取job
            job = Job.getInstance(conf);
            // 配置
            job.setMapperClass(Mapper.class);
            job.setReducerClass(Reduce.class);
            job.setJarByClass(Driver.class);

            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(Bean.class);
            job.setOutputKeyClass(Bean.class);
            job.setOutputValueClass(LongWritable.class);

            // 配置缓存
            String path = "hdfs://192.168.64.178:9000/user/MR/input/information.txt";
            job.addCacheFile(new URI("file:///G:/Projects/IdeaProject-C/MapReduce/src/main/java/CSDN综合练习/data/information.txt"));

            // 自定义分区
            job.setPartitionerClass(Partition.class);
            // reduce计算的数量
            job.setNumReduceTasks(2);

            // 配置输入输出文件
            FileInputFormat.setInputPaths(job,new Path("G:/Projects/IdeaProject-C/MapReduce/src/main/java/CSDN综合练习/data/student.txt"));
            FileOutputFormat.setOutputPath(job,new Path("G:/Projects/IdeaProject-C/MapReduce/src/main/java/CSDN综合练习/output_withoutReducer"));

            // 提交job
            boolean result = job.waitForCompletion(true);
            System.exit(result? 0:1);
        } catch (Exception e){
    
    
            e.printStackTrace();
        }
    }
}

ここに画像の説明を挿入

注意:

  • ここで上記のhdfsファイルパスを使用すると、エラーが報告されます:java.io.FileNotFoundException: \user\MR\input\information.txt (系统找不到指定的路径。)理由は一時的に不明であり、解決後に更新されます〜

トップに戻る


おすすめ

転載: blog.csdn.net/qq_45797116/article/details/114045303