摘要

最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowKey中显然不太可能),或者全表扫描再结合过滤器筛选出目标数据(太低效),所以通过设计HBase的二级索引来解决这个问题

查询需求

多个查询条件构成多维度的组合查询,需要根据不同组合查询出符合查询条件的数据

HBase的局限性

HBase本身只提供基于行键和全表扫描的查询,而行键索引单一,对于多维度的查询困难(如:对于价格+天数+酒店+交通的多条件组合查询困难),全表扫描效率低下。

二级索引的设计

设计思路

                               (图1)设计思路

二级索引的本质就是建立各列值与行键之间的映射关系

如(图1),当要对F:C1这列建立索引时,只需要建立F:C1各列值到其对应行键的映射关系,如C11->RK1等,这样就完成了对F:C1列值的二级索引的构建,当要查询符合F:C1=C11对应的F:C2的列值时(即根据C1=C11来查询C2的值,图1青色部分)其查询步骤如下: 1. 根据C1=C11到索引数据中查找其对应的RK,查询得到其对应的RK=RK1 2. 得到RK1后就自然能根据RK1来查询C2的值了 这是构建二级索引大概思路,其他组合查询的联合索引的建立也类似。

逻辑视图

(图2) 部分数据在HBase中存储的逻辑视图

表中有两个列族,其中一个是列族INDEX,其并不存储任何的数据,仅仅是为了将索引数据与主数据分开存储(因为在HBase中同一列族的数据会被压缩在一起存储),索引数据的行键格式为:RegionStartKey-索引名-索引键-Rowkwy,其他RegionStartKey就是出发点,因为在创建HBase表时就对表根据出发点进行了预分区,索引键为主数据中某列(可能是多列)的列值,Rowkey对应主数据的行键;主数据的行键格式为:出发点-目的地-性价比,所以在存储数据时,同一出发点 目的地的数据默认是按性价比排序的;索引数据的行键和主数据的行键的前缀都是出发点,所以在存储时相同出发点的索引数据和主数据是存储在同一个Region中的,这样避免了在通过索引得到RK后又去其他Region上查询目标数据,提高了查询效率。

数据的查询过程

假设查询的条件:

  • 出发点:澳门

  • 目的地:杭州

  • 出游天数:3天

  • 酒店等级:4

其查询步骤如下:

  1. 首先根据查询条件来确定索引名,根据其查询条件为出游天数据 酒店等级确定索引名为aaa,这样就将查询的范围缩小在索引名为aaa的索引数据区内

  2. 根据出游天数的值为3天,酒店等级的值为4,结合Phoenix的模糊查询就能确定符合这两个查询条件的索引数据的行键

  3. 得到索引数据行键后就截取其最后的RowKey

  4. 最关键的Rowkey得到后就能轻易的获得其对应的列值了,整个查询过程就结束了。

对于其他更为复杂的组合查询的二级索引设计如类似。

缺点

需要额外的存储空间,属 一种以空间换时间的方式。

注意

1.将查询条件中的可选字段转换成数字能节省存储空间,如交通工具中的飞机,高铁,火车,轮船,汽车分别转换成5,4,3,2,1

2.将汉字转换成拼音才能保证数据按HBase的排序规则排序

3.如果数据量在百万级别以下可使用Phoenix(HBase的SQL查询引擎)模糊查询功能减少索引行键的设计

参考资料

HBase高性能复杂条件查询引擎

奇虎360 HBASE二级索引的设计与实践

apache kylin思路类似

 

HBase之八--(1):HBase二级索引的设计(案例讲解)的更多相关文章

  1. HBase二级索引的设计(案例讲解)

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  2. HBase二级索引的设计

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  3. HBase学习(四) 二级索引 rowkey设计

    HBase学习(四) 一.HBase的读写流程 画出架构 1.1 HBase读流程 Hbase读取数据的流程:1)是由客户端发起读取数据的请求,首先会与zookeeper建立连接2)从zookeepe ...

  4. phoenix连接hbase数据库,创建二级索引报错:Error: org.apache.phoenix.exception.PhoenixIOException: Failed after attempts=36, exceptions: Tue Mar 06 10:32:02 CST 2018, null, java.net.SocketTimeoutException: callTimeou

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  5. hbase基于solr配置二级索引

    一.概述 Hbase适用于大表的存储,通过单一的RowKey查询虽然能快速查询,但是对于复杂查询,尤其分页.查询总数等,实现方案浪费计算资源,所以可以针对hbase数据创建二级索引(Hbase Sec ...

  6. Phoneix(三)HBase集成Phoenix创建二级索引

    一.Hbase集成Phoneix 1.下载 在官网http://www.apache.org/dyn/closer.lua/phoenix/中选择提供的镜像站点中下载与安装的HBase版本对应的版本. ...

  7. HBase的二级索引

    使用HBase存储中国好声音数据的案例,业务描述如下: 为了能高效的查询到我们需要的数据,我们在RowKey的设计上下了不少功夫,因为过滤RowKey或者根据RowKey查询数据的效率是最高的,我们的 ...

  8. hbase构建二级索引解决方案

    关注公众号:大数据技术派,回复"资料",领取1024G资料. 1 为什么需要二级索引 HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索.假设我们相对Hbas ...

  9. [转]HBASE 二级索引

    1.二级索引的核心思想是什么?2.二级索引由谁来管理?3.在主表中插入某条数据后,hbase如何将索引列写到索引表中去?4.scan查询的时候,coprocessor钩子的作用是什么?5.在split ...

随机推荐

  1. firefox和chrome实现页面打印自动分页

    在Firefox和chrome中直接调用打印功能的js方法是 window.print(); 但是如果页面很长,那么就需要分页,这时只需要在页面中添加css属性即可,如果想自动分页,则如下所示 < ...

  2. 排序算法(java版)

    一直想理解一下基本的排序算法,最近正好在搞java所以就一并了(为了便于理解,这儿都是以从小到大排序为目的) 冒泡排序 也就是比较连续的两个值,如果前面一个值大于后面一个值,则交换. 时间复杂度为O( ...

  3. div css 练习1

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Flume-NG启动过程源码分析(一)(原创)

    从bin/flume 这个shell脚本可以看到Flume的起始于org.apache.flume.node.Application类,这是flume的main函数所在. main方法首先会先解析sh ...

  5. Python-flask中数据库连接池DBUtils

    一.DBUtils DBUtils是Python的一个用于实现数据库连接池的模块. 连接池的三种模式: 第一种模式:             它的缺点:每一次请求反复创建数据库的链接,链接的次数太多 ...

  6. nova Reboot (重启)

    物理机有两种重启方式:一种从操作系统中重启,一种直接先断电然后再接通电源.虚机的重启也有类似的两种方式:Soft Reboot 和 Hard Reboot.nova reboot 命令在不使用 “-h ...

  7. 在Silverlight中使用SESSION

    首先Session是运行在服务器上的,而Silverlight运行在客户端.因此在Silverlight中使用SESSION的说法并不准确, 只因大家经常这样搜索才起这个名字.   首先Session ...

  8. 使用hibernate读取hibernate.cfg.xml文件时碰到这个错误org.hibernate.internal.util.config.ConfigurationException: Could not locate cfg.xml resource [/HibernateTest/src/hibernate.cfg.xml]

    我的问题在于把hibernate.cfg.xml文件放置在某个包中了,hibernate.cfg.xml文件需要放置在src目录下.

  9. hibernate学习(1)

    对象的持久化 狭义的理解,“持久化”仅仅指把对象永久保存到数据库中 广义的理解,“持久化”包括和数据库相关的各种操作 -保存:把对象永久保存到数据库中 -更新:更新数据库中对象的状态 -删除:从数据库 ...

  10. js字符串和数组的相互转化

    一.数组转字符串 需要将数组元素用某个字符连接成字符串,示例代码如下: var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); 二 ...