【问题标题】:How to run mapreduce on hbase scanner result with TableMapReduceUtil如何使用 TableMapReduceUtil 在 hbase 扫描仪结果上运行 mapreduce
【发布时间】:2016-12-28 06:06:04
【问题描述】:


我的 hbase 表如下所示:

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

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

我想使用 mapReduce 从 hbase 读取数据,因为有很多以相同 Id 开头的键每个 id 一张地图还不够好。我更喜欢每个 ID 100 个映射器

我希望超过 1 个映射器将在已按 id 过滤的同一个scannerResult 上运行。 我阅读了 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);


使用看起来像这样的地图功能(它应该迭代扫描仪结果):

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. map 函数如何作为输入 Result 而不是 ResultScanner?我知道扫描的结果可以通过ResultScanner进行迭代,ResultScanner可以通过Result进行迭代。 ResultScanner 有 Result 的 list\array 不是吗?
  2. 如何在 map 函数中迭代扫描仪的结果?
  3. 如何控制此函数的拆分次数。如果它只打开 10 个映射器,而我想要 20 个,是否可以进行更改?
  4. 有没有最简单的方法可以实现我的目标?

【问题讨论】:

    标签: java hadoop mapreduce hbase hdfs


    【解决方案1】:

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

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

    这种方法可以提高您的读取和写入性能,因为您将不太容易受到热点的影响(假设您的集群中有不止一个或两个区域服务器)。

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

    【讨论】:

    • 听起来不错,但我的表已经创建了 1 个区域,我现在无法编辑或重新创建它。
    • 您不需要重新创建它。您可以从 hbase shell (help "split") 或区域服务器 Web UI 中重复调用 split
    • 我不确定我是否理解正确。我用某种 id 拆分表,然后当我扫描表时 - 在后台它将执行 mapreduce,映射器的数量等于区域(拆分)的数量?
    • 是的;您拆分您的区域,直到达到 100:split 'tablename', "split-key-prefix"(例如 split 'your_table', 'id1/a'split 'your_table', 'id1/b' 等)。如果您运行 X 次,这将创建 X+1 个区域。当您到达(比如说)100 个区域并运行 M/R 作业时,使用标准 TableInputFormat 的映射器数量将为 100。
    • 附录:您可能需要设置 balance_switch true 以确保您的区域得到适当的平衡。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 2013-07-19
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多