Opentsdb插入数据导致RegionServer写入请求分布不均匀(二):Opentsdb 预切分Hbase中 tsdb表

8 篇文章 0 订阅
2 篇文章 0 订阅

Opentsdb当中,存储数据表的表名字叫做tsdb表,tsdb表的行健结构是
指标UID(指标+标签的某个组合)+ 数据生成时间(取整小时)+标签1-Key的UID+标签1-Vlaue的UID+…+标签N-Key的UID+标签N-Vlaue的UID

这个样子的,相信你们都已经知道了什么是uid,那也就是说,我们分布在hbase上的数据,是首先以点位名字uid来分割的,也是最基本也是最简单的预切分方法,就是按照点位名字UID来切分的。

为什么要预切分habse中的tsdb表,因为我们都知道,如果我们不预切分Hbase中的region,一开始只有一个region,也就是说,当我们最开始插入数据的时候,所有的数据都是写入一个regionserver上的一个region上面,这样会在我们最开始往集群写入数据的时候,造成数据的分布不均匀,所以我们要在数据最开始写入的时候,就要预先划分好不同的桶,哪些数据进入哪些”桶”做一些人为的预判断。

工欲善其事必先利其器,如果我们想pre-split region,先看一下Hbase是如何预切分的。

看一下tsdb当中,create_table.sh这个脚本

这里写图片描述

其实我们在一开始创建表的时候,就可以按照行健预切分 region,但是我们发现,这里的切分,都是16进制的,我们很不方便十进制和16进制转换,所以我写个了小程序能帮助我们在创建表时预切分region

/**
 * Created by fanzhongyu on 2017/9/6.
 * 针对uid为3字节,可以这么映射
 */
public class Utils {
    public static String toTsdbUid(long value){
        int i;
        char[] bytes;
        String result = Long.toHexString(value);
        StringBuilder sb = new StringBuilder();
        if(result.length()%2==0){
            bytes = result.toCharArray();
        }else{
            result = "0"+result;
            bytes = result.toCharArray();
    }
    for(i=0;i<bytes.length;i++){
        if(i%2==0)
            sb.append("\\x");
        sb.append(bytes[i]);
    }
    return sb.toString();
}

public static String formatTsdbUid(String tsdbUid){
    String reuslt = null;
    StringBuilder sb = new StringBuilder();
    if(tsdbUid.length() == 4){
        sb.append("\\x00\\x00");
        sb.append(tsdbUid);
    }else if(tsdbUid.length() == 8){
        sb.append("\\x00");
        sb.append(tsdbUid);
    }else{
        sb.append(tsdbUid);
    }
    return sb.toString();
}

public static String makeSplitString(List<String> stringList){
    StringBuilder sb =new StringBuilder();
    sb.append("[");
    for(int j=0;j<stringList.size()-1;j++){
        sb.append("'").append(stringList.get(j)).append("',");
    }
    sb.append("'").append(stringList.get(stringList.size()-1)).append("'").append("]");
    return sb.toString();
}

public static String hbaseSplitString(int range,int regionCount){
    String result=null;
    List<String> stringList=new LinkedList<String>();
    int i = range/regionCount;
    for(int j=1;j<regionCount;j++){
            stringList.add(formatTsdbUid(toTsdbUid(i)));
            i=i+range/regionCount;
        }
        result = makeSplitString(stringList);
        return result;
    }
}

public class presplit {
    public static void main(String[] args){
        int range;
        int regionCount;
        Scanner reader = new Scanner(System.in);
        System.out.print("输入分区区间范围:");
        range = reader.nextInt();
        System.out.println("输入region个数");
        regionCount = reader.nextInt();
        System.out.println(Utils.hbaseSplitString(range,regionCount));
    }
}

程序没有用到别的第三方的库。可以直接运行,效果如下图

这里写图片描述

第一开始,我们使用的random metrics 先来预分区,然后random来负载均衡你监控的点位,但是呢,我们知道,metrics name的uid长度是3字节,也就是uid的最大值是2的24次方-1 即为16,777,215,大约1700万个,因为我们开启了random个,所以预分区就要对大约1700万进行分区。

这里写图片描述

可以看到region大致分布均匀,我也测试了,regionserver上的请求也分布均匀,但是!!有个问题,就是我们各个regionserver上的请求相对分布均匀,但是单个regionserver上的某些region分布很不均匀。

这里写图片描述

这里写图片描述

我想了下,可能的原因是比如我们有撑死4000个点位监控,但是我们是在1677万的范围内randon随机,而且我们预分了16个分区,每个分区大概100万,也就是说,我们的点位,相对于我们的随机数来说,太小太小了,也就是我们从regionserver上看出来相对分布均匀,但是进入到单个regionserver中,regionserver中的各个region分布就不均匀了,因为一个region的范围就是100万!!!!

我在想,Opentsdb的random是不是可以指定规定的范围random呢?但是如果范围小的话,random又有什么意义呢?我曹,我好矛盾!!!!!!!!!!!!!!!!!!

其实还是一个字,懒,因为Opentsdb本身是鼓励我们自己预分区,然后自己预创建 UID的,举个例子,假设
我们有4000个监控点位,我们可以手动创建Opentsdb UID 0~4000的,这个tsdb是支持并且鼓励的!,然后我们用我写的那个小程序,写个预切分范围为5000(预留一点),然后region多切分几个,切他个30个

这里写图片描述

然后将这个考进我们的create_table那个脚本里面,创建表,美滋滋!

其实我想说,能不用random就不用,除非你的监控点位真的真的真的超级多!!!!!!!!!,如果只是很少或者我们手动写个小脚本的话,能预先建立就预先建立,因为大多数情况下!我们的监控点位其实并不是很多,是通过标签的多级索引来确定多维度点位的,不是嘛?

而且我们可以预先知道,哪些点位是热点,哪些点位不是热点,热点的数据呢,时间小时数肯定多,所以给他单独一个region也不是不可以,然后非热点数据呢,放在一起,也阔以。

完全取决于你的业务而已~

但是预先评估那些metric的热度较高比较困难,目前就采用第一种方式:确定metric的个数,然后根据startkey, endkey的范围平均切分region。如果后期发现某些region的访问热度特别高,然后在针对这个region做手动切分。

希望大家呢,学到的是我的这种思想,具体的业务,根据你们实际的情况来预分区和预创建点位!!!!!!!!!(很重要),这样对你的集群,带来非常大的提升!

对了,最后再说一句,Hbase切分rowkey是“左闭右开”,千万别漏掉rowkey哦~~~~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值