什么情况下使用hbase?
- 成熟的数据分析主题,查询模式(查询语句固定)已经确立并且不轻易改变;
- 传统关系数据库已经无法承受的负荷,高速插入,大量读取;
- 适合海量,但同时也是简单的 操作(例如key-value)
场景1:浏览历史(列出前5个最近浏览的图书)
关系数据库的困难:简单的事情只要上了量就会变得无比的复杂。order by 消耗很多性能。大量发生,但又无法分布式 处理。顾客需要实时看到自己的足迹,因此不能是缓存技术。
Hbase迎接挑战:天生就是面向时间戳查询。基于行键的查询异常快速,特别是最近的数据被存放在内存的memstore里,完全没有IO开销。分布式化解负荷。
模式设计:用hbase做一个集群解决用户浏览足迹问题,集群中只需要一个表即可,表的结构是:行键userid, 列族和列book:bookid。记录用户在什么时间看了什么书,然后记录下来写到hbase数据库中。当用户要查询历史记录时,直接在hbase中做get查询,将其中的最新的5条记录拿出来即可。
PS:为了充分利用分布式,可以用reverse key、hash等技巧改造行键。
场景2:商品推荐
用关系数据库实现
阅读推荐说白了就是你打开一个帖子,看到有一个提示写着阅读本帖子的人有x%阅读了a帖子,有x%阅读的b帖子,等等。这项功能可以推广到商品推荐,音乐推荐,下载推荐等。
在ITPUB中设置一个log表,记录每次用户点击,有3列分别是时间戳,用户id,还有点击的主题id,使用了一段时间的数据大约有1000万行,写了sql:
需要时间太长
使用Hbase:表设计和查询实现(用30台机器构成的集群)
两个表:一个是u-t,一个是t-u,
u-t表的结构:行键userid,列族和列为:thread:threadid(用户点击的主题号)
s-t表结构:行键threadid, 列族和列:user:userid
查询:当用户点击时先在t-u表从threadid->userid,对于查询到的每一个userid作为key在u-t表做从userid-》threadid查询,这里可能会有滚雪球效应即可能用threadid查询到了100万个userid则就必须对每一个userid在表中查询这样就可能越来越大,但是由于我们采用的key-value查询速度快,并且采用分布式处理,因此这个是没有问题的,由于没有想group by和distinct语句,因此需要在计算程序中实现去重和统计功能。
辅助索引
例子:学生表(学号,身份证号,姓名,性别,系,年龄),有时在学号上查询,有时在身份证上查询。由于在Hbase中不能建立辅助索引。但是可以通过其他方式来解决。
主表:行键为学号,列族为学生,下面的列是身份证号,姓名,性别,系,年龄。
辅助(索引)表:行键为身份证号,列族和列为学号
复合行键的设计(多条件查询)