当前位置: 首页 > news >正文

HBase之八--(1):HBase二级索引的设计(案例讲解)

摘要

最近做的一个项目涉及到了多条件的组合查询,数据存储用的是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思路类似

 

转载于:https://www.cnblogs.com/duanxz/p/3508332.html

相关文章:

  • 记录上锁
  • Markdown学习笔记
  • 《需求工程》阅读随笔-1.做什么和怎么做
  • curl_errno错误码说明
  • 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇03:子弹发射》
  • 交换机的link-dependency链路依赖功能
  • 打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹
  • 解决:导入第三方jar包后,仍然出现java.lang.NoClassDefFoundError的错误
  • javascript deferred
  • c#对象的内存结构(学习笔记)
  • 学习python的网址
  • 45 个非常有用的 Oracle 查询语句
  • Oracle 创建表空间一边串过程
  • 解读《TCP/IP详解》(卷1):03章:IP(网际协议)
  • LeetCode: Reverse Linked List II
  • [译]前端离线指南(上)
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【RocksDB】TransactionDB源码分析
  • CentOS7 安装JDK
  • const let
  • IP路由与转发
  • JavaScript设计模式系列一:工厂模式
  • Laravel 中的一个后期静态绑定
  • Vim Clutch | 面向脚踏板编程……
  • windows下如何用phpstorm同步测试服务器
  • Zsh 开发指南(第十四篇 文件读写)
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 如何进阶一名有竞争力的程序员?
  • 如何在GitHub上创建个人博客
  • 深度学习入门:10门免费线上课程推荐
  • 试着探索高并发下的系统架构面貌
  • 说说动画卡顿的解决方案
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 以太坊客户端Geth命令参数详解
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​批处理文件中的errorlevel用法
  • # centos7下FFmpeg环境部署记录
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • ###C语言程序设计-----C语言学习(3)#
  • #Spring-boot高级
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)视频码率,帧率和分辨率的联系与区别
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .cn根服务器被攻击之后
  • .describe() python_Python-Win32com-Excel
  • .NET 5种线程安全集合
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件