HBase Table Schema设计要素

多少个column family合适

推荐是:1-3个(越少越好)

划分column family的原则

1.是否具有相似的数据格式
2.是否具有相似的访问类型

下面来看两个例子,解释上面的原则:
1.相同的rowkey,有一个很大的text数据需要存储,又有一个picture数据需要存储
对于很大的text数据我们肯定是想让它Compress后再存储
而picture的数据呢,我们并不想让他压缩后存储,因为对于这种二进制的数据压缩并不能节省空间
所以,我们可以将这两个数据分成两个column family来存储:
create ‘table’,{NAME => ‘t’, COMPRESSION => ‘SNAPPY’},{NAME => ‘p’}

2.有一张hbase表,需要存储每个用户的信息(比如名字、年龄等)和这个用户每天访问网站的信息
对于用户的信息,不经常变,而且量少
对于用户每天访问网站的信息是经常变化且数据量很大的

如果将这两种信息放在同一个column family中的话,用户每天访问网站的信息数据的增大导致会出现memory store的flush,然后会导致compaction,因为compaction是column family级别的,所以会将每个用户的信息(比如名字、年龄等)和这个用户每天访问网站的信息都合并到文件中

实际上用户的信息不大,且不经常变,没必要每次compaction都要将用户的信息写到磁盘中,导致资源的浪费
所以可以将用户的信息和用户每天访问网站的信息分成两个column family来存储

Table Schema的设计注意事项

1.每一个region的大小在10到50G(默认是10G)
2.每一个table控制在50-100个regions
3.每一个table控制在1到3个column family
4.每一个column family的命名最好要短,因为column family是会存储在数据文件中的

RowKey的设计原则

原则一

长度原则:
rowkey的长度一般被建议在10-100个字节,不过建议是越短越好(如果长度有点长,建议使用Block Encoding :DATA_BLOCK_ENCODING => ‘FAST_DIFF’)

原因:
1.数据持久化文件HFile是按照keyvalue存储的,如果rowkey过长,比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率
2.MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好
3.目前操作系统是都是64位系统,内存8字节对齐。如果rowkey是8字节的整数倍的话,则利用了操作系统的最佳特性。

原则二

hbase特性: rowkey是按照字典顺序进行存储的
hbase中相似的rowkey会存储在同一个Region中

比如,我们的rowkey是网站的域名,如下:
www.apache.org
mail.apache.org
jira.apache.org
这样去存储,那么就不会分在一起

如果我们将域名反转作为rowkey的话更好点,如下:
org.apache.www
org.apache.mail
org.apache.jira
这样的话,我们查询的时候,就只会存在同一个region中,这样查询性能就会大大提升

原则三

因为rowkey是按照字典顺序存储的,所以如果rowkey没有设计好的话,会引发: Hotspotting(大量的请求只发往到一个Region中)
解决Hotspotting问题的三个方法

1.Salting((撒盐似的)散布、加盐)
创建一个表,这个表以 b c d 进行切分
create ‘test_salt’, ‘f’,SPLITS => [‘b’,‘c’,‘d’]
原始的rowkey是这样的:
boo0001
boo0002
boo0003
boo0004
boo0005
boo0003
撒盐后的rowkey是这样的:
a-boo0001
b-boo0002
c-boo0003
d-boo0004
a-boo0005
d-boo0003
这种方式虽然解决了热点问题,但是带来的问题就是在读的时候,会有额外的处理,因为你不知道你的key变成什么样去了,只有把所有情况拿到,然后再去处理,因此这种方式虽然解决了这个热点问题,但是依旧有其他的问题

2.Hashing
创建一个表(region4个,切分的算法采用HexStringSplit(十六进制)):
create ‘test_hash’, ‘f’, { NUMREGIONS => 4, SPLITALGO => ‘HexStringSplit’ }
原始的rowkey:
boo0001
boo0002
boo0003
boo0004

md5 hash rowkey(hash后的首字母一定是在0-F之间的):
4b5cdf065e1ada3dbc8fb7a65f6850c4
b31e7da79decd47f0372a59dd6418ba4
d88bf133cf242e30e1b1ae69335d5812
f6f6457b333c93ed1e260dc5e22d8afa
这种方式它不会向同一个Region写数据,从而解决了热点问题,在获取的时候也很方便,把rowkey hash后就是hbase中的rowkey

3.反转rowkey
create ‘test_reverse’, ‘f’,SPLITS => [‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’]
时间戳类型的rowkey:
1524536830360
1524536830362
1524536830376

反转rowkey:
0630386354251
2630386354251
6730386354251

以上几种方式,根据自己的业务场景去使用,推荐使用方式2

原则四

我们在设计RowKey时可以这样做:采用多个列组成RowKey,这样既能满足多条件查询,又能有很快的查询速度。比如:CTU到PEK,2019年08月21这是三个列,我们可以直接设置为rowkey(CTUPEK20190821,然后再hash),这样的话,既不会有热点问题,查询的时候,也可以满足很多条件,查询速度也很快了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值