HBase MapReduce - 基于rowkey拆分区域

时间:2013-09-16 17:52:22

标签: java hadoop mapreduce hbase

我正在针对hbase群集运行java mapreduce。

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

在我们的hbase群集中,我们有一些组包含的数据比其他组多得多。一个群体的规模可能会低至数千,或者可能超过一百万。

据我所知,一个地区将被一个地图读取。

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

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

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

现在问我的问题:

是否可以根据rowkey前缀拆分区域,而不是应用全局最大值? 这样,如果一个大的团体达到一定的大小,它可能溢出到另一个区域。但较小的群体可以保留在一个区域内,并使整个区域的数量尽可能低。

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

1 个答案:

答案 0 :(得分: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拆分方法来拆分特定区域