传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

一、主体思路

先确定查询场景,再确定表结构。

二、主键设计

主键设计需要考虑两个问题:1.选择哪些作为主键?2.当主键大于1个时,如何排列。

2.1 逻辑上用于表示行的唯一性的列必须作为主键

2.2 单个查询场景中一定出现的列可以考虑加入主键列,用于优化查询性能

2.3 在多个查询场景都出现的主键列要排在前面。

如果出现两个列各占部分场景,怎么排列都会使一部分场景无法达到性能要求,这时候我们要考虑二级索引

三、普通列设计

在保持语义情况下尽量使用尽量使用更短的名字,节省空间

Phoenix支持列族的概念,一个列由列祖名+列名唯一指定。

四、热点问题

分为读热点和写热点。

检索Hbase中的数据首先通过rowkey来定位数据行,当大量的client访问Hbase一个或少数几个节点,造成少数region server的读/写请求负载过大,其他region负载很小,这就造成了热点现象。热点现象会导致热点region所在单个主机上负载过大,引起region性能下降甚至不可用。

热点产生原因是因为大量连续编号的(大量相似的)rowkey的记录集中在个别的region中,解决此问题思想在于:尽量均衡的把每条记录均衡的分散到不同的region中。有很多方法可以达到这个目的,例如在行键前添加一个不连续的前缀。

4.1 随机化

如果查询都是Get类型,即只查询一个对象,可以对主键进行HASH,将HASH作为第一个主键列,常用的HASH方式是:MD5,反转。

byte[] rowKey = MD5(timestamp)

采用MD5之类的散列函数能将行键分散到所有region服务器上。对于时间连续的数据,这种方法明显不是好方法,因为随机化后,用户将不能再按时间范围扫描数据。随机化的方法很适合每次只读一行数据应用。如果用户数据不需要连续扫描而只需要随机读取,用户可以使用这种策略。

4.2 salting方式

用户可以使用salting方法将数据散列到所有的region服务器上去。

byte prefix = (byte)(Long.hashCode(timeStamp) % < number of region servers >)

byte[] rowKey = Bytes.add(Bytes.toByte(prefix),Bytes.toBytes(timestamp))

这样做的缺点是当用户要扫描一个连续范围时,可能需要对每个region服务器都发起请求(因为之前连续的数据,现在已经分散到不同的服务器中)。这样也会带来好处,用户可以并行的读取数据,这有点类似于一个小规模的MapReduce作业,这样查询的吞吐量有所提高。


分享至 : QQ空间
收藏

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马
关闭

站长推荐 上一条 /4 下一条