前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术分享 | HBase二级索引实现方案

技术分享 | HBase二级索引实现方案

作者头像
加米谷大数据
发布2018-04-02 15:36:26
1.1K0
发布2018-04-02 15:36:26
举报
文章被收录于专栏:加米谷大数据加米谷大数据
1. 概要设计

主要思路:

为每个DataTable创建一个与之对应的IndexTable,通过各种途径,保证IndexTable Region与DataTable Region一一对应,并且存储在同一个RegionServer上,存储结构如图所示。最终要实现的效果是,每个IndexTable Region是对应的DataTable Region的局部索引,使用索引进行查询时,将对每个IndexTable Region进行检索,找出所有符合条件的DataTable RowKey,再根据DataTable RowKey到对应的DataTable Region中读取相应DataTable Row。

2. 详细设计

2.1. IndexTable的创建

IndexTable的创建主要出现在两个时机,

一是创建新DataTable时,系统根据索引定义,自动创建对应的IndexTable;

二是对已存在的DataTable,用户调用接口方法,动态创建索引。

IndexTable的创建过程如下:

第一步,:

获取DataTable的所有RegionInfo,得到所有DataTable Region的StartKey。

第二步:

结合索引定义和DataTable Region的StartKey信息,调用HBaseAdmin的createTable(final HTableDescriptor desc, byte [][] splitKeys)方法创建索引表。

通过以上两步便建立了IndexTable Region和DataTable Region的以StartKey为依据的一一对应关系。

2.2. IndexTable RowKey的设计

IndexTable的RowKey由四部分组成,按顺序依次是:DataTable Region StartKey、IndexName、IndexValue和DataTable RowKey,如图所示。

DataTable Region StartKey。将DataTable Region的StartKey作为IndexTable Region的RowKey的第一部分,主要基于两个方面的考虑。

一是使得IndexTable Region和对应的DataTable Region拥有相同的StartKey,这样便可将StartKey作为两个Region的关联依据;

二是当DataTable Region分裂时,可使用相同的SplitKey对IndexTable Region进行相应的分裂操作,并将新产生的DataTable Region和IndexTable Region建立关联关系。

IndexName。

在一张DataTable的基础上可以定义多个索引,如果为每个索引创建一个IndexTable,则在实际应用过程中,势必会产生大量的IndexTable,当DataTable Region分裂时,还需要对与之关联的所有IndexTable Region分别执行分裂操作,这将消耗大量的系统资源,并且不易维护。因此,我们考虑将一张DataTable的所有索引数据,存放到同一张IndexTable中,不同索引的数据以IndexName进行区分。

IndexValue。如果索引是单列索引,IndexValue就是DataTable Row的某个Column Value,如果索引是组合索引的话,则IndexValue就是DataTable Row的多个Column Value组合而成的。

DataTable RowKey。被用来定位DataTable Row,以获取最终的数据。

2.3. IndexTable Region的分配控制

IndexTable Region的分配控制过程,即是保证IndexTable Region与DataTable Region的一一对应,并且被分配到同一个RegionServer的过程。

自定义LoadBalancer,重写balanceCluster方法,主要增加对IndexTable Region的分配控制。以相同的StartKey作为IndexTable Region和DataTable Region的关联依据,将IndexTable Region和与其对应的DataTable Region分配到同一个RegionServer。自定义LoadBalancer对IndexTable Region的分配控制过程如图所示。

注意:

这里只增加对IndexTable Region分配的控制,并不对DataTable Region的分配进行干预,DataTable Region由HBase按照指定的负载均衡策略进行分配,使得对现有HBase运行环境的影响降到最小。

2.4. IndexTable Region的分裂过程

本文将以一个示例讲述IndexTable Region的分裂过程,假设当前有一个DataTable Region和对应的IndexTable Region,如图所示,绿色表格为DataTable Region,红色表格为IndexTable Region。

根据概要设计中的说明,假设SplitKey:03,经过一系列操作之后,原来的DataTable Region和IndexTable Region均分裂成两个新的Region,并且依然保存一一对应关系。最终效果如图所示。

IndexTable Region具体分步骤说明如下:

第一步:

确定SplitKey后,遍历IndexTable Region中所有的行,找出所有DataTable RowKey大于或等于SplitKey的Row,如图所示。

第二步:

删除第一步找到的所有DataTable RowKey大于或等于SplitKey的Row,并将RowKey的第一部分(DataTable Region StartKey)替换成SplitKey后,重新插入到IndexTable Region中,如图所示。

第三步:

以SplitKey,同时对DataTable Region和IndexTable Region进行分裂操作,如图所示。最终达到如图所示的效果。

2.5. 数据的写入过程

数据的写入过程,主要通过Coprocessor代理完成,保证更新DataTable Region数据的同时更新IndexTable Region中的数据。具体步骤如图所示。

2.6. 数据的读取过程

与数据的写入过程一样,数据的读取过程也是由Coprocessor代理完成。Coprocessor收到查询请求后,首先判断是否可以利用某个索引,提高本次查询效率。如果有可用的索引,则先从IndexTable Region中查出所有符合条件的RowKey,再根据RowKey,从DataTable Region中查找出实际的数据返回给客户端。具体步骤如图所示。

注意:

描述的IndexTable Region分配机制,保证了IndexTable Region和对应的DataTable Region处于同一个RegionServer上,这样便解决了在有大量符合查询条件的Row的情况下,通过RowKey从DataTable Region中获取实际数据的效率问题。

此外,考虑到从IndexTable中获取的RowKey列表也是有序的,所以在实现时,并不直接调用HBase提供的Get接口,去获取单个实际数据,而是在HFile Data Index的辅助下,通过遍历HFile,获取所有实际数据。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加米谷大数据 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档