2013-09-16 31 views
0

我对一个hbase集群运行java mapreduce。HBase MapReduce - 根据rowkey拆分一个区域

行键的形式为UUID-yyyymmdd-UUID,行组将具有共同的第一个UUID(rowkey前缀)。我将使用共享的前缀组来调用这些行。

在我们的hbase集群中,我们有一些包含比其他更多数据的组。一个团体的规模可能在千人之下,或者可能超过一百万人。

据我所知,一个区域将被一个映射器读取。

这意味着包含较大组的区域被分配给一个映射器,因此这个映射器需要处理大量数据。

我已阅读并测试了将hbase.hregion.max.filesize参数设置得较低,以便区域被拆分。这确实提高了mapreduce作业的性能,因为更多的mapper被编组来处理相同的数据。

但是,将此全局最大参数设置得更低也可能导致更多数百或数千个区域,这会引入其自己的开销并且不建议。

现在我的问题:

代替将全球最大的,是有可能基于该rowkey前缀分割的区域? 这样,如果一个大团体达到一定的大小,它可能会溢出到另一个地区。但是较小的群体可以保持在一个区域内,并尽可能降低总体区域数量。

希望这是有道理的! 谢谢。

回答

1

当您在HBase中创建表格时,如果您事先知道“有问题”的关键字前缀,则可以通过提供列表中的键(即范围)来随意拆分它。 以下是scala中的一个简单示例 - 但它是相当多的在Java中相同的(除了一些更多的样板代码:))

private val admin=new HBaseAdmin(config) 

    if (!admin.tableExists(tableName)) createTable() 

    private def createTable() { 
    val htd = new HTableDescriptor(tableName) 
    val hcd = new HColumnDescriptor(TableHandler.FAMILY) 


    hcd.setMaxVersions(1) 
    htd.addFamily(hcd) 
    admin.createTable(htd, calcSplits) // <---- create the table with the splits 
    } 

    private def calcSplits = { 
    val splits = new Array[Array[Byte]](256) 
    var i=0 
    for (zones <- 0x00 to 0xff) { 
     val temp =new Array[Byte](1) 
     temp(0)=(0xff & zones).asInstanceOf[Byte] 
     splits(i) = temp 
     i+=1 
    } 
    splits 
    } 

而且,当表已经创造了你可以使用相同的HBaseAdmin分裂的方式,分裂特定区域