MapReduce - 读取 ORC, RcFile 文件

一.引言

MR 任务处理相关 hive 表数据时格式为 orc 和 rcFile,下面记录两种处理方法。

二.偷懒版读取 ORC, RcFile 文件

最初不太熟悉 mr,只会 textFormat 一种输入模式,于是遇到 orc 和 rcFile 形式的 hive 数据需要在 mr 读取时,都是先通过 INSERT OVERWRITE DIRECTORY 将 hive 表重新输出一份 hdfs 的 text 数据,随后用 mr 读取该 text 文件,该方法适合偷懒且原始 hive 数据不大,如果原始 hive 表数据很大,那转换操作比较耗费资源。

function insert() {
hive -e"
INSERT OVERWRITE DIRECTORY '$path'
select * from Table where dt='$dt';"
}

此时使用 TextFormat 读取文件处理生成 Mapper 即可:

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

import java.io.IOException;

public class TextMapper extends Mapper<LongWritable, Text, Text, Text> {

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

        try {
            String[] s = value.toString().split("\t");
            String _key = s[0];
            String _value = s[1];
            context.write(new Text(_key), new Text(_value));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

三.正式版读取 ORC, RcFile 文件

1.pom 依赖

主要是 hadoop map-reduce 和 org.orc 相关依赖

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.3</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.orc</groupId>
            <artifactId>orc-core</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.orc</groupId>
            <artifactId>orc-mapreduce</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hive.hcatalog</groupId>
            <artifactId>hive-hcatalog-core</artifactId>
            <version>0.13.1</version>
        </dependency>

2.读取 orc 文件

读取 Orc File 需要选择对应的 OrcStruct 和 OriInputFormat

A.读取 orc 文件的 mapper

getFiledValue() 选取对应列的内容,直接获取内容为 WritableComparable 类型,需要 toString 转换。

public static class OrcMapper extends Mapper<LongWritable, OrcStruct, Text, Text> {

@Override
protected void map(LongWritable key, OrcStruct value, Context context) throws IOException, InterruptedException {

    String key = value.getFieldValue(0).toString();
    context.write(new Text(key), new Text(value.getFieldValue(1)));
    context.write(new Text(key), new Text(value.getFieldValue(2)));

    }
}

B.添加 mapper

import org.apache.hadoop.mapreduce.lib.input.MultipleInputs;

MultipleInputs.addInputPath(job, new Path(input), OrcInputFormat.class, OrcMapper.class);

3.读取 RcFile 文件

A.读写 RcFile 文件的 mapper

这里获取的 value 形式为 BytesRefWritable,需要反序列化读取才能获取 String 类型字符。

import org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable;
import org.apache.hadoop.hive.serde2.columnar.BytesRefWritable;

public static class RcFileMapper extends Mapper<LongWritable, BytesRefArrayWritable, Text, Text> {

    @Override
    protected void map(LongWritable key, BytesRefArrayWritable value, Context context)
            throws IOException, InterruptedException {

        BytesRefWritable _id = value.get(0);
        BytesRefWritable _value = value.get(1);

        String id = LazyBinaryRCFileUtils.readString(_id).trim();
        String value = LazyBinaryRCFileUtils.readString(_value).trim();
        
        context.write(new Text(id), new Text(value));
    }
}

B.添加 mapper

MultipleInputs.addInputPath(job, new Path(input), RcfileCombineFileInputFormat.class, RcFileMapper.class);

四.总结

偷懒版的形成还是因为自己最初学习不到位导致,才会出此下策对数据多一步转化和落盘,同学们要引以为戒呀,多多学习更优的方法。

猜你喜欢

转载自blog.csdn.net/BIT_666/article/details/124267104