2

我在用

Hbase:0.92.1-cdh4.1.2,和Hadoop:2.0.0-cdh4.1.2

我有一个 mapreduce 程序,它将在集群模式下使用 HFileOutputFormat 将数据从 HDFS 加载到 HBase。在该 mapreduce 程序中,我使用 HFileOutputFormat.configureIncrementalLoad() 批量加载 800000 条记录数据集,其大小为 7.3GB,并且运行良好,但对于 8.3GB 的 900000 条记录数据集,它没有运行。

在 8.3GB 数据的情况下,我的 mapreduce 程序有 133 个 map 和一个 reducer,所有 map 都成功完成。我的 reducer 状态一直处于 Pending 很长一段时间。集群没有任何问题,因为其他作业运行良好,并且该作业也运行良好,最高可达 7.3GB 的数据。

我可能做错了什么?我该如何解决这个问题?

4

2 回答 2

0

我遇到了同样的问题。查看 DataTracker 日志,我注意到没有足够的可用空间供单个减速器在我的任何节点上运行:

2013-09-15 16:55:19,385 WARN org.apache.hadoop.mapred.JobInProgress: No room for reduce task. Node tracker_slave01.mydomain.com:localhost/127.0.0.1:43455 has 503,777,017,856 bytes free; but we expect reduce input to take 978136413988

这 503gb 是指特定从属设备(“tracker_slave01.mydomain.com”)上的一个硬盘驱动器上的可用空间,因此减速器显然需要将所有数据复制到单个驱动器。

发生这种情况的原因是您的表在全新时只有一个区域。当数据插入该区域时,它最终会自行拆分。

对此的解决方案是在创建表时预先创建您的区域。HBase 书中的批量加载章节讨论了这一点,并提供了两种选择。这也可以通过 HBase shell 来完成(我认为请参见create'sSPLITS论点)。但是,挑战在于定义您的拆分,以便区域获得均匀分布的密钥。我还没有完美地解决这个问题,但这是我目前正在做的事情:

HTableDescriptor desc = new HTableDescriptor(); 
desc.setName(Bytes.toBytes(tableName));
desc.addFamily(new HColumnDescriptor("my_col_fam"));
admin.createTable(desc, Bytes.toBytes(0), Bytes.toBytes(2147483647), 100);

另一种解决方案是不使用configureIncrementalLoad, 而是: 1) 只需通过 MapReduce 生成您的 HFile 而不使用减速器;2) 使用completebulkloadhbase.jar中的功能将您的记录导入 HBase。当然,我认为这会遇到与区域相同的问题,因此您也需要提前创建区域(我认为)。

于 2013-09-15T21:02:23.920 回答
0

您的工作正在使用单个减少运行,这意味着在单个任务上处理 7GB 数据。其主要原因是 HFileOutputFormat 启动 reducer 对要加载到 HBase 表中的数据进行排序和合并。这里, Reducer 的数量 = HBase 表中的区域数量

增加区域的数量,您将在减速器中实现并行性。:)

您可以在此处获取更多详细信息:http: //databuzzprd.blogspot.in/2013/11/bulk-load-data-in-hbase-table.html

于 2013-12-02T15:21:08.543 回答