Hadoop学習:2つのテーブルをマージするためのMapReduce

✌✌✌古代人は言いたいことがあります。良い記憶は悪いペンほど良くはありません。千マイルの旅は1つのステップから始まります。毎日1000行のコードが不可欠です。毎日要約を書いてください。大きな工場。希望に満ちていれば無敵になります、ははは!✌✌✌

ここに画像の説明を挿入します

1.✌質問の要件

レコードテーブル:

ID 市区町村番号 エアインデックス
001 03 245
002 02 655
003 05 743
004 04 246
005 02 956
006 01 637
007 05 831
008 03 683
009 02 349

シティテーブル:

市区町村番号 都市名
01 長沙
02 株洲
03 湘潭
04 懐化
05 岳陽

ターゲットテーブル:

ID 都市名 エアインデックス
001 湘潭 245
002 株洲 655
003 岳陽 743
004 懐化 246
005 株洲 956
006 長沙 637
007 岳陽 831
008 湘潭 683
009 株洲 349

2.✌アイデアを実現する

繰り返されるフィールドをマップのキーとして使用し、他の属性はBeanに値としてカプセル化されます。
マップを通過した後のファイルの形式は次のとおりです。

市区町村番号 ID 都市名 エアインデックス ファイルの種類
1 006 637 記録
1 長沙
2 002 655 記録
2 005 956 記録
2 009 349 記録
2 株洲
3 001 245 記録
3 008 683 記録
3 湘潭
4 004 246 記録
4 懐化
5 003 743 記録
5 007 831 記録
5 岳陽

1.すべてのプロパティをオブジェクトにカプセル化し、同時にシリアル化を実現し
ます。2。Mapの入力形式はLongWritable、Textである必要があります。3。Map
の出力形式はText、Beanである必要があります。4。Reduce
の出力形式はBeanである必要があります。 、NullWritable

3、✌コードの実装

1.✌Beanクラス

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 pid;
    private int amount;
    private String pname;
    private String type;

	//定义空参构造,为后面反射使用
    public Bean() {
    
    
        super();
    }

	//有参构造
    public Bean(String id, String pid, int amount, String pname, String type) {
    
    
        this.id = id;
        this.pid = pid;
        this.amount = amount;
        this.pname = pname;
        this.type = type;
    }
	
	//重写toString方法
    @Override
    public String toString() {
    
    
        return id + "\t" + pname + "\t\t" + amount;
    }

    public String getId() {
    
    
        return id;
    }

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

    public String getPid() {
    
    
        return pid;
    }

    public void setPid(String pid) {
    
    
        this.pid = pid;
    }

    public int getAmount() {
    
    
        return amount;
    }

    public void setAmount(int amount) {
    
    
        this.amount = amount;
    }

    public String getPname() {
    
    
        return pname;
    }

    public void setPname(String pname) {
    
    
        this.pname = pname;
    }

    public String getType() {
    
    
        return type;
    }

    public void setType(String type) {
    
    
        this.type = type;
    }

	//重写序列化方法
    @Override
    public void write(DataOutput out) throws IOException {
    
    
        out.writeUTF(id);
        out.writeUTF(pid);
        out.writeInt(amount);
        out.writeUTF(pname);
        out.writeUTF(type);
    }

	//反序列化方法
    @Override
    public void readFields(DataInput in) throws IOException {
    
    
        id = in.readUTF();
        pid = in.readUTF();
        amount = in.readInt();
        pname = in.readUTF();
        type = in.readUTF();
    }

}

2.✌マップクラス

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;

import java.io.IOException;

public class Map extends Mapper<LongWritable, Text, Text, Bean> {
    
    

    String fileName;
	
	//获得文件的名称,因为在同一目录,方便再map阶段对不同表做不同操作
    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
    
    

        FileSplit split = (FileSplit) context.getInputSplit();

        fileName = split.getPath().getName();

    }

	//map阶段,将文章内容封装为Bean对象
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    
    

        String line = value.toString();

        if (fileName.startsWith("record")) {
    
    

            String[] words = line.split("\t");

            context.write(new Text(words[1]), new Bean(words[0], words[1], Integer.parseInt(words[2]), "", "record"));

        } else {
    
    

            String[] words = line.split("\t");

            context.write(new Text(words[0]), new Bean("", words[0], 0, words[1], "city"));

        }

    }
}

3.✌クラスを減らす

import org.apache.commons.beanutils.BeanUtils;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

public class Reduce extends Reducer<Text, Bean, Bean, NullWritable> {
    
    

    @Override
    protected void reduce(Text key, Iterable<Bean> values, Context context) throws IOException, InterruptedException {
    
    

		//存取多个Bean对象
        ArrayList<Bean> list = new ArrayList<>();

        Bean pd = new Bean();
		
		//对不同表做不同操作,设置pname
        for (Bean value : values) {
    
    

            if ("record".equals(value.getType())) {
    
    

                Bean temp = new Bean();

                try {
    
    
                    BeanUtils.copyProperties(temp, value);
                } catch (IllegalAccessException e) {
    
    
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
    
    
                    e.printStackTrace();
                }

                list.add(temp);

            } else {
    
    
                try {
    
    
                    BeanUtils.copyProperties(pd, value);
                } catch (IllegalAccessException e) {
    
    
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
    
    
                    e.printStackTrace();
                }
            }
        }

        for (Bean bean : list) {
    
    
            bean.setPname(pd.getPname());
            context.write(bean, NullWritable.get());
        }
    }

}

4.✌ドライバークラス

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

import java.io.IOException;

public class Driver {
    
    

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
    
    

		//设置本地输入输出路径
        args = new String[]{
    
    "D:/input", "D:/output"};
		
        BasicConfigurator.configure();
		
		//配置信息
        Configuration conf = new Configuration();

		//获取job对象
        Job job = Job.getInstance(conf);
		
		//关联相关类
        job.setJarByClass(Driver.class);
        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);

		//设置map输出类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Bean.class);

		//设置最终输出类型
        job.setOutputKeyClass(Bean.class);
        job.setOutputValueClass(NullWritable.class);

		//设置文件路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		//提交任务
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}

おすすめ

転載: blog.csdn.net/m0_47256162/article/details/115010538