术语解释:
Lucene:是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的 查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中 实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
二分查找: 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表, 且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比 较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一 步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
单机版的lucene只能应对千万级,或百万级的索引,通过修改索引,能够支持10亿以上索引的检索。
当前lucene首次加载需要读取整个索引文件,如果数据量较大,索引文件也很大,会照成内存瓶颈。
Lucene 使用倒排索引进行文档的检索,假设存在三个文档
中华人民共和国
人民英雄
中华美食
Lucene在创建索引的的过程中,会将三个文档按照分词结果进行倒排,组成一个倒排表tis文件
中华 {1,3}
人民 {1,2}
共和国 {1}
英雄 {2}
美食 {3}
这样当用户搜索“中华”这个关键词的时候,根据倒排 “中华 {1,3}”就可以知道在文档1和3中含有此关键词,文档1和3就会返回给用户。
我们通常将倒排表中的每个词语叫做一个term,如果想知道,人民这个term对应那些文档,必须先知道 人民这个term在倒排表中位置,然后才能知道这个term (人民)对应那些文档({,2}),故首先要进行的是对term的查找,找到term所在的位置
以上述倒排表为例,假设,中华在倒排表中的偏移量为1,人民的偏移量为2,共和国为3,英雄为4,美食为5
这里的偏移量为距离文件起始的位置,知道了偏移量,就可以通过seek操作,将文件指针直接定位到目标term所在的位置,然后就可以读取文档ID,也就是查询的结果了。
另外很重要的一点是,lucene创建索引的时候会保证倒排表的term是有序的。
Lucene采用128跳跃表的方式创建索引,原理如下
由于lucene索引本身是有序的特点,lucene会在索引文件里存储一些关键term,
假设倒排表里一共有1280个term,那么第1个term,第129个term,257…,1281 一个11个关键term以及偏移量会存储在索引文件tii中。
在进行term的检索前,lucene会将tii文件中的所有关键term,加载到内 存里,以数组的形式存储,当然也是有序的。当我们要检索一个term,首先会在内存里检索此term会落在那两个关键term之间,因为有序的原因,目标 term肯定会在这两个term之间,然后根据两个关键term中较小的term的偏移量,从倒排表tis文件中的偏移量的位置之后开始查找,由于跳跃表 的间隔是128位,那么最多比较128次就可以查找到这个term了。
128跳跃表存在的问题
在进行term检索前,索引文件tii要全部加载到内存里,如果term的数量比较 少,那么不会存在问题,但是如果term特别多,比如说10亿,那么也要消耗几十G的内存(视term的长度不同而不同),普通物理机器一般是没有这么大 的内存的,所以导致lucene因程序崩溃而无法进行检索。另外每次加载索引也是很消耗时间的,如果初级开发者,使用不当,每次都是打开与关闭 lucene,那就会导致索引文件被反复重复加载,也是影响检索性能的。
那怎么解决?
Lucene倒排表tis文件有个显著的特点是,term是有序的,而偏移量是定长的long类型,那么正好适合还用二分查找(折半查找)。
Tii索引文件存储的内容修改为lucene倒排表tis中的每个term的偏移量。根据偏移量我们可以到tis文件中得到对应的term的值。
假设倒排表中一共有1000个term,我们的目标term在第501个term上, 那么二分查找首先会根据中间(折半)位置的term进行比较,也就是根第500个位置的term进行比较,发现目标term应该在500到1000这个区 间内,然后这个区间内在进行折半查找,定位在500~750这个区间,然后进一步定位500~625,500~564,500~532,500~516, 最终找到目标term的偏移量。
在这个过程中,索引文件没有加载到内存里,对内存的依赖较少,假设有100亿个term,那么最坏的情况,进行折半的次数为34次。
另外由于折半的特点,1/2,1/4,1/8,1/16…这些点都是高命中的点,可以 根据物理机器的内存多少,也可以预先加载到内存里,但是与128跳跃表相比,这里加载内存里的都是高命中的区域,对内存的使用率会高很多。如果缓存 16384个位置,那么久可以额外减少14次seek,那么100亿仅仅需要20次的文件seek,但是如果跟原先的进行对比的话,旧的128跳跃表最坏 情况下需要128次seek,平均为64次seek,远远高于二分法的seek次数。而且二分法由于可以在高命中点使用cache,可以进一步减少 cache的数量。
存在问题以及细节的优化
随着term数量的增加,折半查找引起的seek的次数会增加,10000个term要进行12次查找,10万要进行15次,100万进行20次,1000万23次,一亿26次,10亿29次,100亿34次。
2. Term压缩方式由原先,存储上一条记录的差异,存储关键点的差异(这样会照成压缩比降低,但是二分法必须这样做)
3.如果索引二分查找文档差异<128则,保留原先链表顺序查找,调用scan方法(这样做尽管读的次数增多,但考虑磁盘的物理特点,操作系统通常有文件缓冲区,连续的数据读取速度会比不断的跳跃的seek快,物理硬盘适合读取连续的数据),这样可以用1~128此的连续seek,来减少约6~7次左右的跳跃性的seek.
4. 由于norms同样非常消耗内存,这里创建索引的时候禁用norms,待以后改进此处,当前lucene也存在此问题,不过也可以采用同样的二分法来解决此问题,禁止全部加载进内存。
1. Lucene TermInfosReader使用的128位的跳跃表,示例如下
在检索的时候,跳跃表需要加载内存里,在千万级别内的term,检索速度比较理想(但是也需要1~128次的seek),但是如果term数量达到亿的级别,有可能会突破单台机器物理内存的限制,目前业界几乎都是采用分布式,打散成多个索引的方式来减少这个跳跃表的长度,但是单机也是能够支持上十亿key、value的检索(这个地方可以采用定长的数据类型,而且luceneTermInfos这种结构,本身就是有序的,可以支持二分法查找,如果在结合cache,不但不会像跳跃表那样耗费太多的内存,因减少了seek的数量,检索时间也会有所提升,而且支持无限大的term数量,取决于硬盘大小)
当前lucene首次加载需要读取整个索引文件,一般需要成长连接的方式,对开发者要求较高,采用二分法的索引文件就没有此问题。
下表为对100W~10亿条md5值进行创建索引以及查询的情况
读的时间为查询10W条md5的时间,单位毫秒
写为创建完整索引的时间,单位为毫秒。
记录数 |
读10W记录时间 |
每条记录时间 |
创建索引时间 |
索引总大小 |
Tii文件大小 |
|
一百万 |
13667 |
0.13667 |
14338 |
87.6 MB |
7.62 MB |
|
二百万 |
14400 |
0.144 |
25508 |
175 MB |
15.2 MB |
|
一千万 |
20234 |
0.20234 |
120262 |
4.26 GB |
381 MB |
|
一亿 |
2289399 |
22.89399 |
1360215 |
8.51 GB |
762 MB |
|
五亿 |
3793413 |
37.93413 |
12249876 |
42.6 GB |
3.72 GB |
|
十亿 |
5063614 |
50.63614 |
27365596 |
85.2 GB |
7.45 GB |
|
Lucene压缩算法简介
Lucene采用压缩的方式进行创建索引
对于字符串类型
文件链表的第一条记录存储的是完整的信息,第二条记录存储的是跟第一条记录的差异。
举例来说,第一条记录为 abcdefg,如果第二条记录为abcdefh,他们的差异只有h,故第二条记录仅仅会存储一个长度,加上差异的字符,就是存储6+h
对于lucene这种索引结构来说,由于索引是排序过的,故压缩比非常可观。
数值类型的
常见对于文件偏移量的压缩,与字符串形式的压缩类似,但采用的与前一条记录的差值进行存储,如果第一条记录为8,第二条记录为9,则第二条仅仅存储9-8=1,,lucene存储整形也是变长的索引,lucene通常是以append的方式创建索引,故这种压缩方式很有效。
新索引对于压缩的改变
由于上述lucene的 压缩方式,在修改成二分法的时候,无法使用,故需要放弃一定的压缩率。我们采取定义关键点的方式来压缩,关键点存储完整数据,后面的点跟关键点比较差异, 这个跟视频图像压缩的关键帧非常相似,关键帧存储完整的图像信息,后面的帧仅仅存储差异,变化。这样可以节省计算差异的时间消耗(对lucene来说这点微不足道,不是这里解决的主要问题),但是压缩比会降低。
相关推荐
传统的单机索引方法已无法满足高效处理大规模数据的需求,尤其是在搜索引擎领域。Lucene作为一款优秀的全文检索引擎库,其高效、灵活的特点受到了广泛的关注。然而,在面对海量数据时,Lucene的索引构建过程可能会变...
Lucene 支持在一个文档中对多个字段进行索引和搜索,这对于复杂的信息检索需求非常有用。此外,4.6.1版本对多语言的支持也有所加强,提供了多种语言的Analyzer,满足国际化的搜索需求。 6. **更新与删除操作**: ...
随着数据量的增长,单机索引可能无法满足需求。Lucene通过Solr等工具支持分布式搜索,允许多台服务器协同工作,处理大规模数据。 8. **性能提升(Performance Enhancements)**: Lucene 4.1.0引入了更快的文档遍历...
7. **分布式搜索**:随着数据量的增大,单机索引可能无法满足需求,因此需要了解如何利用Solr或Elasticsearch等基于Lucene的分布式搜索解决方案。 8. **性能优化**:这部分可能涵盖索引和查询性能的优化策略,如...
通过分析和运行这些代码,读者可以学习如何配置Lucene索引,如何处理各种类型的文档数据,以及如何实现高效的查询和排序机制。 以下是一些关键知识点的详细说明: 1. **全文检索**:Lucene的核心功能是支持高效的...
在3.0版本中,Lucene引入了许多增强功能和改进,比如更高效的倒排索引结构、新的查询解析器和过滤器等。 在这个压缩包中,我们可以期待找到以下知识点: 1. **文本分析**:Lucene的Analyzer类是处理文本的关键,它...
1. **索引构建**:展示了如何使用Lucene来读取和索引文本数据,包括从文件系统、数据库或其他数据源中抽取内容,并将其转换为可供搜索的索引结构。这通常涉及到分析器(Analyzer)的选择,如标准分析器、中文分词器...
Lucene的核心功能包括索引和搜索,支持丰富的查询语法,以及对文本分析的高级处理。 1. **什么是Lucene?** Lucene是一个纯Java库,它可以将数据结构化为索引,以便快速搜索。它处理文本,将其分词并创建倒排索引...
1. **Lucene基础**:介绍了Lucene的基本架构,包括倒排索引的概念、文档的存储与检索方式,以及如何使用Lucene进行基本的索引和搜索操作。 2. **索引构建**:详细讲解了如何创建、更新和优化索引。包括字段分析、...
- Lucene.NET支持多种查询类型,如布尔查询、短语查询、模糊查询等。查询执行后,会根据查询的相关度对结果进行评分,评分高的结果优先展示。 5. **更新与删除** - Lucene.NET允许动态更新索引,即添加、修改或...
Lucene提供了高级的文本分析、索引和搜索功能,广泛应用于各种信息检索系统,包括网站搜索、文档检索、邮件过滤等场景。 1. **全文搜索引擎基础** Lucene的核心思想是将非结构化的文本数据转化为结构化的索引,...
Solr和Elasticsearch是在Lucene基础上构建的分布式搜索平台,它们提供集群管理和负载均衡,能处理PB级别的数据,并支持复杂的查询和聚合操作。 六、扩展应用 1. ** autocomplete**:利用Lucene的PrefixQuery或...
- 在这一章节中,作者深入探讨了Lucene索引的建立过程,包括索引的结构、索引文档的格式、文档的分词处理等内容。此外,还介绍了如何优化索引的性能,例如使用批量索引来提高效率。 #### 四、使用Lucene进行搜索 -...
Lucene是Java平台上最流行、最强大的开源搜索库之一,它为开发者提供了丰富的文本检索和分析功能。 该书首先会引导读者了解搜索的基本概念,包括倒排索引、TF-IDF(词频-逆文档频率)等核心算法。通过这些基础知识...
1. **Lucene概述**:Lucene是一个高性能、可扩展的信息检索库,支持全文检索、布尔查询、短语查询、模糊查询等多种搜索方式。它提供了一个Java API,开发者可以将其集成到Java应用程序中,构建自己的搜索引擎。 2. ...
- **1.2.1 Solr使用Lucene并且进行了扩展**:Solr是一个开源的高性能搜索引擎,它基于Lucene构建,提供了更高级别的功能和服务,如全文检索、自动完成和实时更新等。 - **1.2.2 Schema(模式)**:Solr使用Schema来...
- **SOLR的使用过程说明**:从设计索引结构、构建索引到执行搜索,整个流程都非常直观。 - **一个简单的例子**:通过一个具体的例子来展示如何设计Solr Schema、构建索引以及进行搜索测试。 - **搜索引擎的规划设计*...
通过Schema,可以灵活地定义索引结构,满足不同类型的搜索需求。 - **1.2.3 查询** Solr支持丰富的查询语言,包括全文查询、范围查询、模糊查询等,使得用户能够精确地找到所需的信息。 - **1.2.4 核心** 每个...
Solr 是一个高度可扩展的、高性能的、开源的企业级搜索平台,它基于 Lucene 构建,能够提供强大的全文检索功能。Solr 可以用于各种应用环境中,包括网站搜索、电子商务商品搜索等场景。其主要特性包括:高可用性、...