我遇到了同样的问题。查看 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) 使用completebulkload
hbase.jar中的功能将您的记录导入 HBase。当然,我认为这会遇到与区域相同的问题,因此您也需要提前创建区域(我认为)。