如何使用TableMapReduceUtil在hbase扫描器结果上运行mapreduce

时间:2016-08-21 17:15:18

标签: java hadoop mapreduce hbase hdfs


我的hbase表看起来像这样:

    key---------value
    id1/bla     value1
    id1/blabla  value2
    id2/bla     value3
    id2/blabla  value4
    ....

有数百万个以id1开头的键和数百万个以id2开头的键。

我想用mapReduce读取hbase中的数据,因为有许多键以每个ID相同的Id和1个地图不够好。我更喜欢每个Id的100个映射器 我希望不止一个mapper将在已经过id的同一个scannerRoreult上运行。 我阅读了有关TableMapReduceUtil的内容并尝试了以下内容:

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleSummary");
job.setJarByClass(MySummaryJob.class);     // class that contains mapper and reducer

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
    sourceTable,        // input table
    scan,               // Scan instance to control CF and attribute selection
    MyMapper.class,     // mapper class
    Text.class,         // mapper output key
    IntWritable.class,  // mapper output value
    job);


使用看起来像这样的map函数(它应该迭代扫描器结果):

public static class MyMapper extends TableMapper<Text, IntWritable>  {

    private final IntWritable ONE = new IntWritable(1);
    private Text text = new Text();

    public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
            text.set("123");     // we can only emit Writables...    
            context.write(text, ONE);
    }
}
<br>



我的问题是:

  1. 地图功能如何作为输入结果而不是ResultScanner?我知道扫描的结果可以由ResultScanner迭代,可以由Result迭代。 ResultScanner有一个结果列表\数组不是吗?
  2. 如何在地图功能中迭代扫描仪的结果?
  3. 如何控制此功能将执行的分割数量。如果它只打开10个映射器,我想要20可以更改某些内容吗?
  4. 有最简单的方法来实现我的目标吗?

1 个答案:

答案 0 :(得分:1)

我将从列表中的#4开始:

默认行为是为每个区域创建一个映射器。因此,您应该首先考虑将数据拆分为100个区域(然后您将有100个映射器非常均衡),而不是试图破解TableInputFormat根据您的规范创建自定义输入拆分。

这种方法可以提高您的读写性能,因为您不太容易受到热点攻击(假设您的群集中有多个或两个区域服务器)。

解决此问题的首选方法是预分割表(即在表创建时定义拆分)。