温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Lucene与HBase的组合使用及HBasene的报告分析

发布时间:2021-11-10 18:52:37 来源:亿速云 阅读:125 作者:柒染 栏目:云计算

Lucene与HBase的组合使用及HBasene的报告分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Lucene简介

  Lucene中,以document的形式作为搜索的主体。document由fieldName和fieldValue所组成,每个fieldValue又可以由一个或多个term元素来组成。基于不同的分词及索引规则,可用于搜索fieldValue的term少于组成fieldValue的term。Lucene的搜索基于反向索引,包含着可用于搜索document的field信息。通过Lucene,可以正向查找document,以便了解其包含哪些field信息;也可以通过反向索引,通过搜索字段的term,来查询包含该term的document。

 Lucene与HBase的组合使用及HBasene的报告分析

[ 图1 ]  Lucene总体架构

  由图1所示,IndexSearcher实现了搜索的逻辑,IndexWriter实现了文档的插入与反向索引的建立,IndexReader由IndexSearcher调用以便读取索引的内容。IndexReader和IndexWriter都依赖于抽象类Directory,Directory提供操作索引数据及的API。

  标准的Lucene是基于文件系统和基于内存的。

  标准基于文件系统的后端的缺点在于,随着索引增加性能会下降,人们使用了各种不同的技术来解决这个问题,包括负载均衡和索引分片(index sharding,在多个Lucene实例之间切分索引)。尽管分片功能很强大,但它让总体的实现架构变得更复杂,并且需要大量对期望文档的预测知识,才能对Lucene索引进行合适地分片。另一方面,在大数据量的情况下,segment的合并花销巨大;频繁的update数据将使得Lucene对Disk io产生巨大的影响。一个新的数据的update,可能导致一部分根本没有变化的索引被重写很多次,并且可能导致很多的小的index segment,造成了search的性能下降。

  Lucene的优势在于索引查找的迅速,而非document的存储。为解决上述问题,基于NoSQL数据库存储索引的后端结构应运而生。

以下,将基于HBase的实现来进行分析。

实现方法

  在Lucene中,其会操作两个单独的数据集:

  • 文档数据集中存储了所有文档,包括存储的字段等。

  • 索引数据集中存储了所有字段/词汇/词频/位置等信息,以及包含当前字段的document

  如果要实现将Lucene的后端移植到HBase上,直接构建一个Directory的实现并不会是最简单的。在已有的开源项目中,Lucandra和HBasene均采用了直接重写IndexReader和IndexWriter的方式,直接绕开了Directory的API。此实现并不会重写Lucene的索引查询机制。如若重载IndexSearcher,则可以在使用现有的Lucene索引查询机制上,根据后端的功能增强性能。

Lucene与HBase的组合使用及HBasene的报告分析 

[ 图2 ] Lucene的后端重新设计

  图2的设计,可以将Lucene后端与HBase整合起来,将索引数据存储到HBase中,从而利用HBase的大数据存储以及分布式性能。

架构设计

  在架构设计上,将HBase用作索引的持久化后端,同时可以如网上所说,基于内存实现一套缓存机制,用来提高数据读取速度。实现一套高效的缓存同步机制,也将有利于数据读写速率的提高。

 Lucene与HBase的组合使用及HBasene的报告分析

[ 图3 ] 带有内存缓存以及同步缓存的HBase后端实现

  对于HBase的访问,每一次交互都需要通过以太网,以太网的运行状态将大大影响系统的使用情况,而索引的建立又希望能达到实时且高响应。为了平衡这两种相互冲突的需求,在内存中,缓存能够最小化HBase用于搜索和文件返回的数据读取量,从而极大提升性能;按照需要运行为多个Lucene示例以支持日益增长的搜索客户端的能力。后者需要最小化缓存的生命周期,从而和HBase实例(上面提到实例的副本)中的内容同步。通过为活动参数实现可配置的缓存时间,限制每个Lucene实例中展现的缓存,我们可以达成一种折中方案。

  根据上述所描述的结构,对于读操作,首先会检查所需数据是否在内存中且没有过期,如果有效将直接使用,否者将从HBase中获取数据并更新到内存中。而对于写操作,可以简化到直接将数据写入到HBase中,进而不需要考虑是否需要建立或更新缓存这种复杂的问题,这也将提高系统的实时响应性。

HBase Table的实现

当前了解到的两种可参考的实现方式:HBasene类型、Lucandra类型。

1-- HBasene

其索引表由以下几个column family组成:

  • fm.sequence:记录sequenceId,表示当前添加的第几个document。在执行createLuceneIndexTable时创建该行,且rowKey为segmentId,Column.qulifier为qual.sequence,Column.value=-1。每add一个document,当前segmentId的Column.value将自增1。

  • fm.doc2int:每个document的存储都将被分配一个唯一的id,如果document的Field.Store=YES,则能够通过该id获取到对应的document的全部信息。

  • fm.fields:记录了Field中value的内容,rowKey为documentId,Column.qulifier为FieldName,Column.value为FieldValue的内容。

  • fm.termVector:向量偏移数据,用于模糊查找,记录了偏移量等信息,rowKey为FileldName/Term的组合,Column.qulifier为documentId,Column.value为指向的document中的所有位置偏移量。Column.value的结构为:[A][size][position]……[position]

  • fm.termFrequencies:关键词在每个document中出现的频率,rowKey结构为zfm/FileName/Term,Column.qulifier为documentId,Column.value为出现的次数。

2-- Lucandra

在Lucendra中,只有两个ColummFamily来存储数据,分别是TermInfo和Documents

<Keyspace Name="Lucandra"> 
    <ColumnFamily   Name="TermInfo" CompareWith="BytesType" ColumnType="Super"  CompareSubcolumnsWith="BytesType"  KeysCached="10%" /> 
    <ColumnFamily Name="Documents" CompareWith="BytesType" KeysCached="10%" /> 
</Keyspace>
  • TermInfo

        TermInfo存储了Lucandra逆向索引的信息,用来存储index的Field信息,其结构如下:

        RowKey:field/term

        SuperColumn.name:documentId

        [ SubColumn.name:"frequencies"  Column.value:count ]

        [ SubColumn.name:"position"  Column.value:position vector ]

        [ SubColumn.name:"offsets"  Column.value:offsets vector ]

        [ SubColumn.name:"norms"  Column.value:norms vector ]

由于HBase中不存在SuperColumn和SubColumn的概念,我们可以将其简化为:

        RowKey:field/term

        Column.qulifier:documentId

        Column.value:fieldInfo [ 此fieldInfo可以通过AVRO类定义 ]

  • Documents

        Documents存储了Document数据,其结构如下:

        RowKey:documentId

        Column.name:fieldName

        Column.value:fieldValue

对比:

        由HBasene的表结构可以知道,对于每一个document的更新以及每一次term的查询,都需要操纵多行数据才能实现,逻辑上相对复杂;而Lucandra只需要处理两行(documents及TermInfo各一行)。但是HBasene的优势在于单行的存储结构小,每次与HBase交互只需要传输少量的数据及可,并且不像Lucandra结构一样需要而外的AVRO组件来序列化与反序列化数据。

HBasene的缺陷:

        1、HBasene在三年前已经停止了其项目的更新,开源的支持断开了。

        2、在对HBasene的最新源码分析过程中,首先是发现其设计上保留着segment的概念,但是其设计阻碍着document的查询。其documentId由segmentId/sequenceId组成,每次segment的commit,sequenceId恢复为-1。而search时返回的TopDocs中只包含了sequenceId[int]。

        3、每次添加document时,只有fm.Fields以及fm.doc2int的数据被实时flush到了HBase中,而其他数据需要segment大小到了一定程度[默认1000条document]才commit,容易造成数据缺失。在segment没被commit的情况下,是无法查询到新添加的document的。

        4、HBase Table的设计中,没有考虑到当document中fieldName相同的情况。当fieldName相同的情况下,后面添加的会覆盖前面添加数据的,最后只保留最后添加的一份。

        5、fm.termVector中,Column.value保存的并不是positionVector信息,而是segment中所有document里出现的次数。

        6、fm.termFrequencies只是单纯地存储了,并没有被应用上。

        7、IndexWriter的重写并没有实现所有函数,只实现了最基本的addDocument

        8、对IndexSearch的重写和扩展也不够。

关于Lucene与HBase的组合使用及HBasene的报告分析问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI