欢迎投稿

今日深度:

Hbase的热点问题,

Hbase的热点问题,


在使用hbase中,不免会出现热点问题。那么什么叫做热点问题呢?就是某些region的数据量比较大,某些region的数据量比较小,就导致了某几个的region server的负载量较大。
当我们采用默认的配置时,它会默认使用一个region,当region的数据量大到一定程度时,会发生split分成两个region。通常情况下,我们存储的rowkey都是以字典顺序存储,这样的话,由于region存在start key和end key,每次存储新的rowkey都会往新产生的region里存储(因为它的rowkey要大于之前的region的start key),于是就会导致之前的region存储的数据量小,而之后的region存储的数据量大。region默认发生split的条件为:min(flushsizenn,maxFilesize),这里n为(2*split次数-1),而maxFilesize默认为10G。即在第五次split时为10G,之后均为10G。
这里我就给大家讲解一下在工作中比较常用的处理热点问题的一种方法,预分区机制。

预分区机制

先放出代码:

//建表
public static void createTable(String tableName, String... columFamilys) throws IOException {
	        if (StringUtils.isBlank(tableName) || columFamilys.length == 0) {
	            return;
	        }
	        HBaseAdmin hAmin = HbaseDriver.getHBaseAdmin();
	        HTableDescriptor hd = new HTableDescriptor(TableName.valueOf(tableName));
	        for (String cf : columFamilys) {
	            if (!StringUtils.isBlank(tableName)) {
	                hd.addFamily(new HColumnDescriptor(cf));
	            }
	        }
	        try {
	        //只有下面使用了边界值这点与平时建表不一致
	            hAmin.createTable(hd, getSplitKeys(6));
	        } catch (IOException e) {
	            // TODO Auto-generated catch block
	            e.printStackTrace();
	        } finally {
	            hAmin.close();
	        }
	    }


//得到splitkeys这个二维数组,定义了split的边界值
private static byte[][] getSplitKeys(int regions) {

    byte[][] arr = new byte[regions][];

    TreeSet<byte[]> set = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
    for (int i = 0; i < regions; i++) {
        DecimalFormat df = new DecimalFormat("00");
        String s = df.format(i) + "|"; // ctrl + alt +v
		//定义的为01| 、02|、03|等格式,主要是因为 | 的ascii码为124要大于任何字母和数字,这里也可以采用~
        set.add(Bytes.toBytes(s));
    }
    Iterator<byte[]> iterator = set.iterator();
    int num = 0;
    while (iterator.hasNext()) {
        arr[num++] = iterator.next();
    }
    return arr;
}

这里采用的原理是,我假设设定了6个region,它会分为7个region,第一个的region的startkey为0,stopkey为 00|;第二个region的startkey为00|,stopkey为001|;以此类推,第七个region的startkey为005|,stopkey为无穷大。这里就会产生疑问,明明建立6个region为什么会生成7个呢,这是因为第七个region用于存放计算错误的数据,当第七个region存在数据了,就说明程序出现了问题。
这时,我对原先设定的rowkey进行hash取值,并对分区数也就是6进行取余,将得到的数通过format格式化成两位数,组合拼接到rowkey上,这样我得到的rowkey就变成了这样:00_rowkey1,01_rowkey2等等。再将数据存储到hbase时,就会将00_rowkey的放到第一个region也就是stopkey为00|中,因为我之前说了|的ascii码值大于任何数字、字母以及下划线,依次类推,01_rowkey2就是放在第二个region,startkey为00|,stopkey为01|中。
当处理好的数据存放入hbase中,就如下图所示:

通过对数据的预分区处理,就可以将数据基本平均的分配到各个region当中,当然这里对rowkey的处理还有很多种,大家可以在网上搜索学习一下,这次的分享到此结束,如果有哪里解释的不到位或者解释错误,可以留言给我。

www.htsjk.Com true http://www.htsjk.com/hbase/42286.html NewsArticle Hbase的热点问题, 在使用hbase中,不免会出现热点问题。那么什么叫做热点问题呢?就是某些region的数据量比较大,某些region的数据量比较小,就导致了某几个的region server的负载量较大...
相关文章
    暂无相关文章
评论暂时关闭