从Reducer中的HBase读取数据

时间:2014-03-25 10:01:18

标签: java hadoop mapreduce hbase

是Hadoop和HBase的新手。让我用一个例子来解释我的问题。为简洁起见,数据很小。

假设我们有一个名为item.log的文件,它包含以下信息。

ITEM-1,PRODUCT-1
ITEM-2,PRODUCT-1
ITEM-3,PRODUCT-2
ITEM-4,PRODUCT-2
ITEM-5,PRODUCT-3
ITEM-6,PRODUCT-1
ITEM-7,PRODUCT-1
ITEM-8,PRODUCT-2
ITEM-9,PRODUCT-1

我有一个地图缩小代码,如下所示,

package org.sanjus.hadoop;

import java.io.IOException;
import java.util.Iterator;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapred.TextOutputFormat;

public class ProductMapReduce {

    public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, LongWritable> {

        public void map(LongWritable key, Text value, OutputCollector<Text, LongWritable> output, Reporter reporter) throws IOException {
            String[] columns = value.toString().split(",");

            if (columns.length != 2) {
                System.out.println("Bad line/value " + value);
                return;
            }

            Text word = new Text(columns[1]);
            LongWritable counter = new LongWritable(1L);

            output.collect(word, counter);
        }
    }


    public static class Reduce extends MapReduceBase implements Reducer<Text, LongWritable, Text, LongWritable> {

        public void reduce(Text key, Iterator<LongWritable> iterator, OutputCollector<Text, LongWritable> output, Reporter reporter) throws IOException {
            long sum = 0L;

            while (iterator.hasNext()) {
                sum += iterator.next().get();
            }
            output.collect(key, new LongWritable(sum));
        }

    }

    public static void main(String[] args) throws IOException {
        JobConf conf = new JobConf(ProductMapReduce.class);
        conf.setJobName("Product Analyzer");

        conf.setOutputKeyClass(Text.class);
        conf.setOutputValueClass(LongWritable.class);

        conf.setMapperClass(Map.class);
        conf.setCombinerClass(Reduce.class);
        conf.setReducerClass(Reduce.class);

        conf.setInputFormat(TextInputFormat.class);
        conf.setOutputFormat(TextOutputFormat.class);

        FileInputFormat.setInputPaths(conf, new Path(args[0]));
        FileOutputFormat.setOutputPath(conf, new Path(args[1]));

        JobClient.runJob(conf);
    }
}

LABEL 1:地图缩小后的输出低于:

PRODUCT-1   5   
PRODUCT-2   3
PRODUCT-3   1

这是一个问题:

我在HBase中有一张表,其中包含以下信息。

PRODUCT-1   10$
PRODUCT-2   20$
PRODUCT-3   30$

问题/要求:我希望将reduce阶段的输出合并为&#34; LABEL 1中的reduce输出:&#34;以及上面提到的HBase表

PRODUCT-1   10$ * 5 = 50$
PRODUCT-2   20$ * 3 = 60$
PRODUCT-3   30$ * 1 = 30$
     

基本上,Key是PRODUCT-1,HBase表中的值为10 $,且reducer中相同键的值为5,两个值相乘。 ($符号用于理解)

注意:我找到的示例基于HBase的输入或输出。我的场景是,输入和输出将是HDFS中的文件,而我需要使用HBase表中的信息处理reducer输出。

2 个答案:

答案 0 :(得分:1)

由于HBase支持高读取吞吐量,并且您只想读取reducer中的数据(将使用受控数量的数据): 您可以使用HBase API根据reducer的键读取表中的数据。由于Hbase中的读取速度很快(约10毫秒,具体取决于提取的数据大小),我认为您的性能不会受到影响。 只需确保初始化配置&amp;在reducer的configure()方法中是HTable。

答案 1 :(得分:0)

这就是我所做的,

在我的reducer类中,我添加了重载方法&#39; setup&#39;

private HTable htable;

private Configuration config;

protected void setup(Context context) throws IOException, InterruptedException {
    Configuration config = HBaseConfiguration.create();
    config.addResource(new Path("/etc/hbase/conf.hbase1/hbase-site.xml"));
    try {
        htable = new HTable(config, "MY_TABLE");
    }
    catch (IOException e) {
        System.out.println("Error getting table from HBase", e);
    }

}

使用HTable.get api,我得到了Result对象。