这篇文章主要介绍了HBase中RowKey设计原则有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
首先看一下RowKey设计的3条原则
1、散列原则,不要用类似于时间戳这样的数据直接作为RowKey,如果确实需要用时间戳,可以把它放在低位,高位用散列来占位。
2、长度原则,其实总结就一句话,rowkey只是一个唯一标识符,并没有更多的实际意义,所以不要搞得太长,但是,我想说但是,如果我的rowkey是有意义的,那么让他长一些是不是也可以呢?
3、唯一性原则,这一点没什么好说的,RowKey需要唯一确定一条数据,所以必须唯一。
后面2条原则没什么好说的,我们重点来看一下散列原则,为什么会有这样的建议。
在HBase当中,表会被划分为1...n个Region,被托管在RegionServer中。Region二个重要的属性:StartKey与EndKey表示这个 Region维护的rowKey范围,当我们要读/写数据时,如果rowKey落在某个start-end key范围内,那么就会定位到目标region并且读/写到相关的数据。
如果我们在建表的时候,不预先设定好分区,随着表内数据的增多,HBase会自动把表进行split,但是这样做有几点问题,第一,分区的原则,可能并不是我们想要的;第二,在表内数据相对较少的时候,无法充分展现分布式并发处理的优势;第三,split操作,其实是比较耗资源的,如果数据增长过快,可能会相对频繁的发生。
那么,预分区又是如何实现的,我们看下面这个语句:
create 'testtable', 'common', 'data', {SPLITS => ['1','2','3']}
建好之后,我们可以在HBase的web页面当中,看到表的分区的分布情况:
我们看到,我们用1,2,3三个数,把一个table划分为了4个region,这四个region分别是:
x<1, 1<=x<2, 2<=x<3, 3<=x
那么我们在insert的数据的时候,又该怎么做呢?看下面的scala代码:
val p = new Put(Bytes.toBytes(String.valueOf(random.nextInt(4)) + new Date().getTime))
这句话是为一条新的数据,生成一个RowKey,那么我们的key值由2部分组成,随机散列+时间戳,其中随机散列包括:【0,1,2,3】一共4个值,根据上面我们划分的region,这4个值,将会映射到4个不同的region当中。
好吧,刚才我们直接把一种比较好的解决方案告诉给大家了。
最初的时候,我可不是这么做的,当时我并不知道有预分区这回事,所以我仅仅是建了一个表,这种情况下,它只有一个分区。
create 'testtable', 'common', 'data'
然后我用下面的语句来生成RowKey。
val p = new Put(Bytes.toBytes(new Date().getTime))
这样会发生什么事情?程序执行之后,持续不断的往这个默认的region当中写入数据,事实上也就只有一个regionserver来为我们服务,数据量大了之后,table终于发生了分裂,2个region了,可是情况并没有任何好转,因为我们的RowKey是不断增大的,所以,按照HBase默认的分区原则,所有的新的数据,都被写到了startkey最大的那个region当中。分布式的性能优势完全无法体现。
感谢你能够认真阅读完这篇文章,希望小编分享的“HBase中RowKey设计原则有哪些”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。