hbase表的设计
来源:互联网 发布:大草原上的小老鼠 知乎 编辑:程序博客网 时间:2024/05/21 08:51
一、预分区的设计
hbase默认建表时有一个region,该region没有startkey和endkey,在向该表中写数据时都会写入到唯一的一个region中
随着数据量的增加,此region中某个store下的storeFile文件的大小达到一定阈值(动态阈值)会进行split分割,一分为二
在此过程中,会产生两个问题需要解决:
1、在region进行split分割前会产生热点问题
同一时间可能整个hbase集群只有一个或几个regionserver在响应客户的读写请求
2、region在被动执行split时会offline,另外会消耗大量的集群资源,导致整个hbase集群访问不稳定
如何解决:
提前对hbase表的region指定个数,并且指定每个region的rowkey范围,降低被动split分割的几率---预分区
建表时创建预分区的方式
方式1:
>create 't001', 'f1', SPLITS => ['10', '20', '30', '40']
创建出的region会被master随机分散在regionserver上
startkey endkey
region1 10
region2 10 20
region3 20 30
region4 30 40
region5 40
插入数据,使用不同的rowkey:
> put 't200','33','f1:name','tom' --
region的startkey和endkey的范围是对插入数据时的rowkey的前缀进行匹配
> put 't200','30','f1:name','tom'(左闭右开)
方式2:
>create 't002', 'f1', SPLITS_FILE => '/home/hcx/demo/splits.txt'
方式3:
使用自带的api预定义类分割算法
> create 't003', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
适用场景:
rowkey的前缀是十六进制字符串的场景
二、rowkey的设计
rowkey的设计主要是为了避免数据倾斜,数据热点
热点:同一时间内大量的数据读写io都集中在某一台或几台regionserver上
例如:
> create 't001', 'f1', SPLITS => ['10', '20', '30', '40']
如果向t001中插入数据
rowkey的设计的如下:
如果使用一个时间戳+随机字符串作为rowkey的话?
151056426132_afdd3243
热点问题 -》大量的数据会写入到region2中,同一时间只有region2所在的regionserver响应写请求
如何设计:
Rowkey —》 两位00-50之间的随机数据_时间戳_随机字符串
rowkey设计时的要点:
必须唯一,不能重复
rowkey的长度:
官方 -》 10-100字节之间
实际-》 16字节以下
hbase中每个cell中都存在rowkey+列簇+列
列簇和列名名称也需要短小
避免数据热点和倾斜
rowkey设计时要遵循一个【散列原则】
将要插入的数据的rowkey散列的分布在各个region中
满足业务需求!!!
【散列原则】的一般思路:
1、生产随机字符串
crc32/md5可以生产随机数字或字符串
一般不会对rowkey全部使用随机字符串
随机数字+日期/订单id +随机数字
2、反转字符串
正常时间戳
1510564261322
1510564261335
1510564266388
如果将以上时间戳直接作为rowkey容易产生热点问题
反转后时间戳
2231。。。。0151
5331。。。。0151
8836。。。。0151
反转之后将变化比较大的低位反转到字符串的开头
hbase默认支持前缀匹配,进行前缀匹配时会进行散列分布
使用场景:
数字是连续的rowkey场景
时间戳/日期/手机号码/连续的订单id
20171114110526
20171114110526
3、拼接字符串
固定长度的数字+固定长度的随机字符串
日期+随机:
2017101411_fer3435df
2017111411_fer3435df
2017111411_ferghghdf
2017111412_fe5656hdf
2017111510_fesds56hd
2017121810_fesds56hd
(1)如何根据以上rowkey查询11月份的话单记录
Scan scan = new Scan() ;
scan.setStartKey("201711") ;
scan.setStopKey("201712") ;
(2)如何根据以上rowkey查询11月15号的话单记录
Scan scan = new Scan() ;
scan.setStartKey("20171115") ;
scan.setStopKey("20171216") ;
【电话话单rowkey设计案例】
每天用户的话单记录可能几十亿条
每条话单记录里包含很多字段
业务要求:
根据客户的电话号码和时间范围快速查询个人的话单记录
如何满足:
1、如何从一张bhase大表中快速查询出个人的话单记录
本身个人的话单数据相对整个hbase大表数据量非常小
组好将个人的数据放入到一个region中,避免数据散列
这样可以减少region的寻址次数及regionserver的响应次数
2、rowkey如何设计?
考虑要点:
避免数据散列
客户可以根据电话号码+时间范围查询数据
rowkey:
电话号码_日期_随机字符串
电话号码在前可以保证个人的数据在表中存储的连续性,避免数据散列
日期可以通过前缀匹配查询出个人某个时间范围内的话单
随机字符串为了保证rowkey的唯一性
1390000000_2017101411_34fgf 138xxxxx 1.5 5
1390000000_2017111411_34fgf 138xxxxx 1.5 5
1390000000_2017121411_34fgf 138xxxxx 1.5 5
(1)查询11月份的话单记录:
Scan scan = new Scan() ;
scan.setStartKey("1390000000_201711") ;
scan.setStopKey("1390000000_201712") ;
(2)查询11月20号的话单记录:
Scan scan = new Scan() ;
scan.setStartKey("1390000000_20171120") ;
scan.setStopKey("1390000000_20171121") ;
- hbase表的设计
- Hbase -- 表的设计
- Hbase表的设计
- hbase表的设计
- Hbase之表的设计
- 说说我的HBase表设计
- HBase之表的设计原则
- HBase表设计的经验分享
- HBase的rowkey设计
- HBase的设计优化
- HBase的rowkey设计
- HBase的rowkey设计
- HBase的rowkey设计
- HBase的rowkey设计
- HBase的RowKey设计
- HBase的RowKey设计
- HBase的RowKey设计
- hbase的rowkey设计
- 算法15 Continuous Subarray Sum
- 笔记本电脑GHOST重装后就剩一个盘了
- sql执行顺序
- unity鼠标双击
- 关于LINUX权限(启动tomcat)-bash: ./startup.sh: Permission denied
- hbase表的设计
- matlab中pwelch函数用法总结
- Java中的static关键字解析
- 【Tensorflow】tf.dynamic_partition 函数 分拆数组
- java之static关键字
- SpringBoot(一)入门
- 如何使用ultraiso制作LinuxU盘启动盘?
- 上台讲课相关总结
- Spring框架中的设计模式(二)