分享

hbase主键设计

bingoyin 发表于 2014-10-25 15:16:33 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 8 34588
现有gps导航数据 ,人的id和获取时间createtime,位置 信息等。因为数据每天增加几千万条记录,因此将数据存放到hbase中,但现在希望能查询一个人一段时间的情况和一段时间内有哪些人上传了位置信息。不知道这个rowkey怎么设计。不知道大家是怎么设计rowkey的,还请各位帮忙!~谢谢

已有(8)人评论

跳转到指定楼层
271592448 发表于 2014-10-25 16:00:23
可以参照一下群里的文章。
http://www.aboutyun.com/thread-7119-1-1.html
回复

使用道具 举报

rsgg03 发表于 2014-10-25 17:49:55
小和尚正解

通过我们在设计rowkey的时候需要考虑两个关键问题
1.容易查询
2.不要产生热数据

这两二者存在着矛盾性,比如为了容易按照时间段查询,我们需要在rowkey中加入时间,但是如果rowkey中以时间前缀,如下
时间+人id
这样会产生热数据,在查询的时候,会有io瓶颈。

如果我们以下面这种

散列值+时间+人id

其中散列指是防止热数据,防止同一时间段数据跑到同一台服务器,不能发挥分布式的优势,所以我们需要这么设计。但是随之带来一个问题,就是如何按照时间段来查询。

我们可以在scan的时候过来散列值,最后达到能够按照时间段来查询。
回复

使用道具 举报

bingoyin 发表于 2014-10-25 20:41:20
rsgg03 发表于 2014-10-25 17:49
小和尚正解

通过我们在设计rowkey的时候需要考虑两个关键问题

你好,我是通过sqoop从SqlServer导入到hbase的,不知道这个散列值弄。并且我要查找一个人一 段时间的数据。如果是时间+人id的话。查询难道全表扫描。谢谢!
回复

使用道具 举报

rsgg03 发表于 2014-10-25 21:14:29
bingoyin 发表于 2014-10-25 20:41
你好,我是通过sqoop从SqlServer导入到hbase的,不知道这个散列值弄。并且我要查找一个人一 段时间的数据 ...
要是导入数据另外说,可以提前预置分区,rowkey里包含时间+人id,的话,并且通过rowkey查询不会全表扫描。
如果通过列族或则列会全表扫描。
回复

使用道具 举报

rsgg03 发表于 2014-10-25 21:16:42
预置分区可以参考下面例子






用HBase Shell建表的时候,除了一些常用的option以外,我们还可以同时建立一些预分区,这样可以预防初次插入数据时热点问题。

通过直接输入create,我们可以看到有如下提示:

  1. Examples:
  2.   hbase> create 't1', {NAME => 'f1', VERSIONS => 5}
  3.   hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}
  4.   hbase> # The above in shorthand would be the following:
  5.   hbase> create 't1', 'f1', 'f2', 'f3'
  6.   hbase> create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}
  7.   hbase> create 't1', 'f1', {SPLITS => ['10', '20', '30', '40']}
  8.   hbase> create 't1', 'f1', {SPLITS_FILE => 'splits.txt'}
  9.   hbase> # Optionally pre-split the table into NUMREGIONS, using
  10.   hbase> # SPLITALGO ("HexStringSplit", "UniformSplit" or classname)
  11.   hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
复制代码
例子中仅给出了要么有普通option,要么是有指定分区等选项,但是没有给出既有普通option(例如VERSIONS,COMPRESSION等),又创建预分区的例子。

如果有这个需求呢?如下对吗?

  1. create 't', {NAME => 'f', VERSIONS => 1, COMPRESSION => 'SNAPPY', SPLITS => ['10','20','30']
复制代码

运行后发现肯定是不行的。正确的写法应该是这样的:
  1. create 't', {NAME => 'f', VERSIONS => 1, COMPRESSION => 'SNAPPY'},
  2.     {SPLITS => ['10','20','30']}
复制代码

因为分区时针对全表而非某个Column Family的。








回复

使用道具 举报

bingoyin 发表于 2014-10-25 21:23:57
rsgg03 发表于 2014-10-25 21:14
要是导入数据另外说,可以提前预置分区,rowkey里包含时间+人id,的话,并且通过rowkey查询不会全表扫描。 ...

不是rowkey查询只有单一查询和区间查询,如果是查询一个人一段时间的数据,这些数据肯定不是在一个区间的,这样查询难道不要全表扫描嘛?
回复

使用道具 举报

rsgg03 发表于 2014-10-25 23:32:56
bingoyin 发表于 2014-10-25 21:23
不是rowkey查询只有单一查询和区间查询,如果是查询一个人一段时间的数据,这些数据肯定不是在一个区间的 ...
查询非rowkey全表扫描,如果使用rowkey则不会。可以了解下rowkey的原理
回复

使用道具 举报

chuyuan_zhou 发表于 2014-12-26 16:48:12
飘过,学习学习!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条