周伟 刘希 陈浩
摘要:二级索引方案是分布式存储研究的重要分支之一,基于通用目标设计二级索引方案可避免单一业务编程繁琐问题,使实施人员更多地关注业务本身而非编程细节。以HBase数据库为研究对象,引入分布式索引机制,通过重写观察者Observer协处理器方法,操作完数据后立即触发创建或更新索引的请求,进一步在SolrCloud中完成对索引的管理。反向进行多条件组合查询时,先在SolrCloud中查询包含行键和索引列的文档,再以行键为条件查询并获取HBase记录。部署通用方案,实验证明该方案很好地满足了创建和维护HBase二级索引的要求,且保证了索引与记录的一致性,对进一步研究分布式存储二级索引方案有一定的指导意义。
关键词:分布式存储;分布式索引;二级索引;协处理器;通用方案
DOIDOI:10.11907/rjdk.171483
中图分类号:TP391
文献标识码:A文章编号文章编号:16727800(2018)003018704
英文摘要Abstract:Secondary indexing scheme is an important branch of HBase database research. A scheme based on the general purpose will avoid programming against every single business detail, which helps the developers focus more on the business rather than the programming details. By overriding the methods of observer coprocessor, requests for creating indexes will be triggered after the records are stored in database, and then the indexes will be created and stored in SolrCloud which is a distributed indexer. Furthermore, documents of SolrCloud which contain both row keys and indexed columns can be filtered by a multiconditional query, and the target records will be fetched by the target row keys in the documents. Through deploying this scheme, it turns out that it completely meets the requirements of creating and maintaining secondary indexes of HBase and ensures the consistency between indexes and records. Whats more, the scheme referred in this paper has instructional significance for further study of HBase secondary indexing.
英文關键词Key Words:HBase; SolrCloud; secondary indexing; coprocessor; general schema
0引言
索引是一种特殊文件,存储着数据表中所有记录的引用指针,从逻辑上对记录进行排序。索引通常建立在数据表的某些列上,在数据量不大时,有无合适的索引对记录查找速度影响不大,随着数据量的增加,查找性能会急剧下降,此时索引能加速查找过程。索引对数据库的查询速度至关重要,重构索引是数据库性能调优的起点。传统关系型数据库支持二级索引(也称多级索引),扩展了一级索引只针对单列构建索引的特性,主要用于多条件组合查询的场景。
在大数据应用中,作为一个分布式、可伸缩的列存储数据库,HBase表现出强大的生命力。HBase归属Hadoop生态系统,利用Hadoop分布式文件系统存储切片数据,通过Hadoop MapReduce计算框架处理海量数据,适用于联机分析处理和数据挖掘的场景。HBase主要定义了一个四维数据模型,分别为行键(rowkey)、列族(column family)、列修饰符(column qualifier)和版本(version)。HBase基于行键有序存储,在查询时使用行键十分高效,同时列修饰符可以被动态创建,适合应对属性不固定的半结构化数据。然而HBase本身无法轻易建立二级多列索引(以下简称二级索引),随着应用业务复杂度的增加,单一行键满足不了类似关系型数据库多条件组合查询、分页等功能的要求。
为了突破单一行键在复杂查询上的限制,避免全表扫描,业界已有一些研究成果。朱夏等[1]基于多维数据检索机制MIndex,实现了从复杂查询请求到一维查询键值的转换,并保证了复杂查询的高效性。丁飞等[2]基于HBase协处理器,通过倒排索引实现了第二索引扩展功能。徐熙超等[3]提出HBase4M架构,利用协处理器建立和维护辅助索引,将字段查询转化为索引表的行键查询。葛微等[4]提出的分层式非主键索引方案中,在组合查询时也会转换成索引表主键的查询。上述研究需要巧妙地设计索引表的行键,通过将多个查询条件键值对映射到行键的方式缩小索引表的行键区间,最后确定目标行键。该方式依赖于表结构已知且查询条件固定的情况,具有一定的局限性。陈东辉等[5]依靠第三方搜索引擎Solr提供的API接口,参考具体业务中的查询用例对相关字段建立辅助索引以适应检索时效。该方式借助Solr提供的索引功能为HBase记录创建、存储索引,其中HBase负责存储数据,Solr负责索引数据和检索。许杰等[6]亦使用Solr建立二级索引的方法,提高了检索效率。该方式充分利用各角色的优点,更适于企业级的架构设计。考虑到适应海量数据存储和索引的要求,将原有架构扩展为分布式架构极为迫切[7]。付剑生[8]总结了SolrCloud作为Solr分布式实现的特色功能:数据检索时自动负载均衡、自动化容错处理、索引分片、倒排索引的虚拟化存储等。本文结合SolrCloud研究分布式存储HBase二级索引的通用实现,基于通用目标设计构建索引的具体过程,该过程不依赖于任何特定的业务。二级索引方案整体架构如图1。
1相关技术
1.1分布式存储模型
HBase基于Hadoop分布式文件系统(HDFS)构建,对数据进行索引后,将结果文件存放在HDFS上,以提高查找或更新大数据表中目标记录的速度,同时确保数据的容错性。HBase支持线性伸缩和模块化扩展,突破了关系型数据库有限扩展能力的限制,通过新增节点,集群的存储能力和处理能力明显增强。同时基于HDFS的架构,HBase在故障处理和容错方面具有优良的性能。
1.2分布式索引模型
SolrCloud为服务器之间分发索引文件和请求转发创建了一个高可用、高容错的分布式环境。一份索引文件经切片后被保存在某台机器上,同时索引文件的多份拷贝会被分别存储在其它机器上,客户端通过Solr API请求文件,若分布式系统感知该机器出现宕机、故障,就会直接返回其它机器上的文件拷贝。SolrCloud还支持集群集中管理、自动负载均衡和故障切换等特性。
1.3分布式应用协调服务
ZooKeeper作为分布式应用协调工具,能为分布式应用提供高性能和可靠的协调服务,简化分布式协调服务的实现。HBase将元数据存储在ZooKeeper中,使得客户端不能直接访问或修改HBase元数据,并保证集群只存在唯一HMaster。SolrCloud将配置文件存放在ZooKeeper中,以集中化管理配置信息,使得各节点共享信息,协调工作,并通过配置ZooKeeper访问控制列表以控制外部API调用。HBase(HDFS)、SolrCloud和ZooKeeper关系如图2所示。
2HBase二級索引
传统关系型数据库(以MySQL为例)架构主要分为SQL解析引擎和存储引擎两部分,前者包括解析器和查询优化器,负责解析,后者负责执行(查询或存储),解析完SQL后,解析引擎会调用存储引擎的相关接口供进一步处理。根据MySQL的架构设计,本文构思了HBase二级索引方案(见图3)。HBase作为存储引擎,负责存储数据,待执行完存储命令,索引器向索引引擎发起创建索引的请求,生成记录的索引数据。
HBase自0.92版本后引入了协处理器Coprocessor机制以支持二级索引,Coprocessor存在两种实现,分别是Observer Coprocessor和Endpoint Coprocessor,前者在特定事件出现前后被触发,功能与关系型数据库中的触发器类似,后者则可类比关系型数据库的存储过程,具体逻辑在RegionServer服务器端执行,客户端仅通过类库方法调用服务端接口。Coprocessor执行过程如图4,其中Observer与Endpoint相互之间可通过ZooKeeper共享数据。
根据HBase数据入库的基本流程[5],本文在构建二级索引过程时基于Observer实现,待记录被写入(Put)到HRegion后,会立即触发将记录同步到SolrCloud的操作,进而生成索引。客户端读取(Get)记录时,首先根据索引字段请求SolrCloud查询索引,得到目标行键,继而根据目标行键获取HBase记录。二级索引方案中,各组件通过ZooKeeper协同工作,并通过暴露API接口供外部调用,整体流程如图5。
2.1索引方案设计
Observer允许实施人员在记录被写入到HBase前后作一些处理,本文提供的索引工具类通过继承BaseRegionObserver抽象类,重写postPut方法,请求SolrCloud生成索引。默认情况下,HBase每提交一条数据都会触发一次postPut操作,考虑到系统的性能,工具类引入了一个本地可持久化的队列机制,用来代理创建或删除索引的操作,在postPut或postDelete重载方法中将包含索引字段的记录放入队列,队列以定时器轮询的方式向SolrCloud提交数据,同时监控异常以供故障恢复。索引工具类创建索引的活动见图6。
通用性是软件设计的重要准则之一,通用性使得工具更易于扩展,避免重复编码,提高开发效率。检索业务升级、需求变更伴随着对索引字段灵活性的要求,这也意味着在设计时需考虑索引工具类对不同业务二级索引的通用性要求。
为提高索引方案的通用性,本文规范了Solr配置和HBase创建数据表过程,首先在Solr的配置文件中定义统一的动态字段,格式以下划线加字母的方式进行声明,对照关系如表1。利用工具构建HBase索引,Solr中每一条Document对应着HBase的一条记录,除了需要索引的字段外,还包括4个缺省字段:ID(表名+行键)、表名、行键、更新时间。接着在HBase中建立需索引的字段,其列修饰符按字段名加预定义的标识符进行定义。比如统计用户对各网站的访问量排名,在设计数据表时,访问量列标识符需按照“访问量_i”的格式设计,其中“i”表示访问量是整型数。该方式统一了创建和维护索引的流程,在设计列修饰符时相应字段按约定命名。实现过程参见代码如下:
//获取rowKey
for (Cell cell:cells){
//获取cFamily,cQualifier,cValue
if (cQualifier.endsWith("_s"))
jsonSet.putObject(cFamily+F_SEPARATOR+cQualifier,(new JsonObject()).putString("set",cValue));
else if (cQualifier.endsWith("_t"))
jsonSet.putObject(cFamily+F_SEPARATOR+cQualifier,(new JsonObject()).putString("set",cValue));
//处理其它类型的cQualifier
}
jsonSet.putString(F_ID,tableName+F_SEPARATOR+rowKey);
jsonSet.putObject(F_TABLENAME,(new JsonObject()).putString("set",tableName));
jsonSet.putObject(F_ROWKEY,(new JsonObject()).putString("set",rowKey));
jsonSet.putObject(F_UPDATETIME,(new JsonObject()).putString("set",SolrTools.solrDateFormat.format(new java.util.Date())));
_bqUpdate.enqueue(jsonSet.encode().getBytes(SolrTools.UTF_8));
2.2部署索引方案
本文采用1台服务器,基于3台虚拟机搭建大数据分布式应用实验环境。各机器的具体配置如表2。安装、配置分布式集群时,需配置各机器SSH免密码登录、关闭防火墙、调整SELinux参数、同步机器时间,另外使用官方推荐的整合方式确保各软件版本之间的兼容性。依次分别启动ZooKeeper、Hadoop、HBase和Solr Cloud,启动无异常后,可通过WebUI访问HBase和SolrCloud。
停止HBase服务,将索引工具类打包后上传给所有的Region Servers,并放在HBase根目录下的lib子目录中,接着配置HBasesite.xml文件,主要设置Solr Cloud地址,设置coprocessor实现类为索引工具类。再次启动HBase服务,通过客户端请求HBase,并插入预定义格式的记录,刷新SolrCloud集群狀态后,发现SolrCloud产生新的索引记录,ID参数形如“表名#行键”,其它属性均与HBase记录一致。如先执行建表和插入实验数据的命令:
put 'test_table','row_1','report:name_s','张三'
put 'test_table','row_1','report:age_i','24'
put 'test_table','row_1','report:gender_b','true'
put 'test_table','row_1','report:grade_f','89.5'
put 'test_table','row_2','report:name_s','李四'
put 'test_table','row_2','report:age_i','23'
put 'test_table','row_2','report:gender_b','true'
put 'test_table','row_2','report:grade_f','90.0'
随后在客户端按指定URL(形如[domain]:[port]/solr/admin/collections?action=RELOAD&name;=[coreName])重新加载集群状态,查询索引即得到如下记录:
"docs":[{
"report#name_s":"张三",
"id":"test_table#row_1",
"t_s":"test_table",
"r_s":"row_1",
"u_dt":"2016-07-10T22:47:13Z",
"report#age_i":24,
"report#gender_b":true,
"report#grade_f":89.5,
"_version_":1539479473261379600
},{
"report#name_s":"李四",
"id":"test_table#row_2",
"t_s":"test_table",
"r_s":"row_2",
"u_dt":"2016-07-10T22:47:26Z",
"report#age_i":23,
"report#gender_b":true,
"report#grade_f":90,
"_version_":1539479487465390000
}]
以同样的方式测试更新表中某行记录、删除某行记录的某一列以及删除某行记录的情况,发现SolrCloud存储的索引都会产生相应变化。多条件查询HBase记录时,先在客户端通过API查询Solr索引,待返回目标行键,便可根据目标行键查询HBase目标记录。
3结语
本文针对HBase在二级索引问题上的缺陷,结合SolrCloud分布式索引特性,利用HBase提供的Observer Coprocessor API,设计了创建和维护HBase二级索引的通用实现,简化了开发流程,避免了针对单一业务编程的繁琐问题。通过部署索引方案,发现该方案能很好地满足创建和维护HBase二级索引的要求,并保证索引与记录的一致性。对于通用实现的高并发性能测试将是下一步研究的工作。
参考文献参考文献:
[1]朱夏,罗军舟,宋爱波,等.云计算环境下支持复杂查询的多维数据索引机制[J].计算机研究与发展,2013,50(8):15921603.
[2]丁飞,陈长松,张涛,等.基于协处理器的区域级第二索引研究与实现[J].计算机应用,2014,34(S1):181185.
[3]徐熙超,杨铮,马廷淮.基于HBase的气象结构化数据查询优化[J/OL].计算机工程与应用,http://www.cnki.net/kcms/detail/11.2127.TP.20160510.1117.038.html.
[4]葛微,罗圣美,周文辉,等.一种基于分层式索引的高效查询技术与系统[J].计算机学报,2016,39(1):140153.
[5]陈东辉,曾乐,梁中军,等.基于的气象地面分钟数据分布式存储系统[J].计算机应用,2014,34(9):26172621.
[6]许杰,冷冰,李明桂,等.大数据处理技术在安全审计系统中的应用[J].通信技术,2016,49(3):346351.
[7]吴广君,王树鹏,陈明,等.海量结构化数据存储检索系统[J].计算机研究与发展,2012,49(Sl):15.
[8]付剑生,徐林龙,林文斌.分布式全网职位搜索引擎的研究与实现[J].计算机技术与发展,2015,25(5):69.
责任编辑(责任编辑:何丽)