Phoenix使用SALT_BUCKETS创建预分区表

1. 基础知识

Phoenix Salted Table是phoenix为了防止hbase表rowkey设计为自增序列而引发热点region读和热点region写而采取的一种表设计手段。通过在创建表的时候指定SALT_BUCKETS来实现pre-split(预分割)。如下表示创建表的时候将表预分割到6个region里面。

默认情况下,对salted table创建二级索引,二级索引表会随同源表切进行Salted切分,SALT_BUCKETS与源表保持一致。当然,在创建二级索引表的时候也可以自定义SALT_BUCKETS的数量,phoenix没有强制它的数量必须跟源表保持一致。


2. 实现原理

Phoenix Salted Table的实现原理是在将一个散列取余后的byte值插入到 rowkey的第一个字节里,并通过定义每个region的start key 和 end key 将数据分割到不同的region,以此来防止自增序列引入的热点问题,从而达到平衡HBase集群的读写性能的目的。

salted byte的计算方式大致如下:
new_row_key = ((byte) (hash(key) % SALT_BUCKETS) + original_key

默认下salted byte将作为每个region的start key 及 end key以此分割数据到不同的region,这样能做到具有相同salted byte的数据能够位于同一个region里面。

写 加前缀,读去除前缀


3. SALT_BUCKET的本质

Salting能够通过预分区(pre-splitting)数据到多个region中来显著提升读写性能。

Salting 翻译成中文是加盐的意思,本质是在hbase中,rowkey的byte数组的第一个字节位置设定一个系统生成的byte值,这个byte值是由主键生成rowkey的byte数组做一个哈希算法,计算得来的。Salting之后可以把数据分布到不同的region上,这样有利于phoenix并发的读写操作。
关于SaltedTable的说明在 http://phoenix.apache.org/salted.html

如下,创建盐表,预分区6个

CREATE TABLE SALT_TEST (HOST VARCHAR NOT NULL PRIMARY KEY, DESCRIPTION  VARCHAR) SALT_BUCKETS=6;

SALT_BUCKETS的值范围在(1 ~ 256)
不成文的规定: region server 多少个,就设置多少个

接下来就开始划重点了: 
salted table可以自动在每一个rowkey前面加上一个字节,这样对于一段连续的rowkeys,它们在表中实际存储时,就被自动地分布到不同的region中去了。当指定要读写该段区间内的数据时,也就避免了读写操作都集中在同一个region上。

简而言之,如果我们用Phoenix创建了一个saltedtable,那么向该表中写入数据时,原始的rowkey的前面会被自动地加上一个byte(不同的rowkey会被分配不同的byte),使得连续的rowkeys也能被均匀地分布到多个regions


4. 实例展示

为了印证这一说法,我往TEST中添加几分数据看看

UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.1','S1');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.2','S2');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.3','S3');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.4','S4');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.5','S5');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.6','S6');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.7','S7');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.8','S8');
UPSERT INTO SALT_TEST (HOST,DESCRIPTION) values ('192.168.0.9','S9');

从phoenix查询数据,没感觉有什么不同:
select * from SALT_TEST;

此时的HBase中的数据为

这里我们可以判断phoenix是在写入数据的时候做了处理,在插入数据的时候会计算一个byte字段并将这个字节插入到rowkey的首位置上;而在读取数据的API里面也相应地进行了处理,跳过(skip)第一个字节从而读取到正确的rowkey(注意只有salted table需要这么处理),所以只能通过phoenix接口来获取数据已确保拿到正确的rowkey。


5. 特别注意

可以看到,在每条rowkey前面加了一个Byte,这里显示为了16进制。也正是因为添加了一个Byte,所以SALT_BUCKETS的值范围在必须再1 ~ 256之间。而添加的这个Byte是根据什么来分的我就不得而知了,所以最好不要使用HBase的API插入数据。

因此,在使用SALT_BUCKETS的时候需要注意以下两点:

  • 创建salted table后,应该使用Phoenix SQL来读写数据,而不要混合使用Phoenix SQL和HBase API
  • 如果通过Phoenix创建了一个salted table,那么只有通过Phoenix SQL插入数据才能使得被插入的原始rowkey前面被自动加上一个byte,通过HBase shell插入数据无法prefix原始的rowkey

好处: 其实本质就是随机数
有助于数据均匀的落在各个region server-各个节点上,从而提供写的性能 

坏处:  1-1000 非盐表 数据在一个region server  查询性能高
           1-1000   盐表 数据在多个region server  查询性能低

           1-1KW 非盐表 数据在一个region server  查询性能低  
           1-1KW   盐表 数据在多个region server  查询性能高

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值