从lucene的文件结构看它的性能
作者:冲出宇宙(lotusroots)
时间:2007-2-6
注:转载请注明作者。
Lucene是一个apache项目,完全使用java语言编写(废话,谁都知道apache主要是做java项目的,不过,已经有人对Lucene进行了迁移,比如CLucene),它提供了一个基本的索引文档后进行搜索的功能。目前版本是2.0,具体信息可以直接看http://lucene.apache.org/官方网站。同时,http://www.lucene.com.cn/about.htm提供了一个很不错的介绍(同时介绍了CLucene项目)。
本文不打算介绍它的使用,因为它的使用实在是过于简单,而且,太多的人写了关于它的使用方法。本文试图从一个更高的层次来分析一下lucene的文件结构及其性能,所以,需要读者已经对搜索引擎的工作原理有较深入的了解(推荐学习MIT的开放课程中的Information Extraction)。
本文的内容主要参考了http://lucene.apache.org/java/docs/fileformats.html,这是lucene的文件结构页面。
一 lucene文件的基本构架
lucene文件结构的最大特点是其结构十分紧凑。从文件开始的第一个字节直到最后一个字节都是有效数据,中间没有任何空闲的字节。这样有优点也有缺点,优点是读取迅速,缺点是修改复杂。因为lucene的作者说lucene并不是为修改频繁的应用设计的,所以,文件结构这么做是无可厚非的。在修改频繁的环境下,lucene的性能注定会很差。如果是那样的话,您或许需要考虑使用更好的技术,因为增加一个文档到索引其实可以做到十分迅速。
在压缩方面,lucene也采用了一些基本的方法。比如,它对int类型就进行了所谓的byte压缩方法(最初级的方法)。不过,它在String上面采用的utf-8的编码显然会比utf-16编码占用更多的空间。其它地方还能够看到压缩的是Field Data(域值,.fdt)文件,这个文件保存的是文档包含的域的具体文本(一个文档可以划分为多个域,每个域都是一个字符串),显然这是很大的数据(zlib好像在这里比较常用,google据说也这样压缩,不过,文本压缩的最好办法显然不是zip,更好的办法还有ppmd)。
二 lucene构建索引的性能
索引,专业点说,包含2种:前向索引和反向索引(倒排索引,inverted index)。前者表示的是某个文档里面的所有词语,后者表示的是包含某个词语的所有文档。对应到Lucene上面,它的前向索引可以认为是Term Vectors(词语向量)相关文件,包含.tvx、.tvd和.tvf这3种文件。前向索引没有什么好评论的,它一般只是做为重组原始数据时候的依据,其构建十分简单明了。反向索引对应到Lucene上就是index(索引)。Lucene把索引划分成一个一个的segment(块,其实是一个小索引),直观的说,当有一批新数据到达的时候,我们一般给其构建成一个新的segment,这是因为修改原来的segment的代价很高(并不是说一定很高,只是lucene采用的文件结构无法简单的加入新的文档)。当一个index包含的segment太多的时候,查找性能就很差了(因为一次查询需要查询多个segment),需要进行segment的合并。
下面是index和segment的基本结构:
1. index:
index包含4类文件:1)记录segment信息的文件;2)指示索引是否正在更改的标记文件;3)简单组合了若干个文件的复杂文件;4)segment文件及其附属文件。
2. segment:
segment其实是一个小型index,它包含了词汇表、域表、反向索引表、域权重表、词语向量(即前向索引)和已经删除文档表。词汇表包括了本segment里面出现的所有词汇(记得词汇不见得是真的词语,它其实就是索引的字符串)。
三 lucene修改和删除索引的性能
严格的说,lucene底层并不支持对某个文档的修改。因为它的紧密结构抗拒了对文档的直接修改。当需要修改某些文档的时候,可以是这样的:
1. 删除这些文档。这样会使得这些文档ID加入到已经删除的文档表里面。
2. 构建新的索引。这样会生成一个新的segment。
3. 合并索引的所有segment。这样会把所有的segment都合并到一起,构成唯一的一个segment。
大家可以看到,如果仅仅从以上3步来看,lucene的修改索引的性能极差。好在可以利用缓冲,分批的懒惰的进行上面的第2步和第3步。
四 lucene的查询性能
我们从几个方面来分析它的查询性能:
1. 文件个数。文件个数越多,查询的时候需要访问的文件就越多,从而开销也会越大。这是因为要读取的类似数据处在不连续的位置。当你把所有segment都合并成一个之后,这种问题就不存在了。可是,合并segment的花销很大,需要谨慎考虑。
2. 索引词汇。lucene的词汇其实并不是简单的词汇,而是“域+词汇”的保存形式。当域比较多的时候,这种方式的索引词汇构建方式显然会大大降低查找的效率。不过,值得一提的是,为了降低空间占用,lucene在排序词汇之后,按照如下的形式进行保存: <PrefixLength, Suffix, FieldNum>,这里,PrefixLength表示本词汇借用了前面一个词汇的前面PrefixLength个字符,Suffix表示本词汇余下的字符串,FieldNum表示本字符串属于的域。
3. 布尔表达式计算。布尔表达式查找的时候,涉及到几条词汇倒排索引的合并的问题。未压缩的索引合并是一个十分容易(不过,算法需要很精细才能优化各种情况)的事情,可是,lucene的索引经过压缩了(包括前面提到的和相邻数据相减的压缩方法)以及String长度的不确定性,所以,我们无法根据词汇直接定位到它对应的TermInfo(做为一个变型,你可以在内存中为它做个索引)。于是lucene就使用了SkipInterval/SkipData(桩,即定位标记)这类结构来加快比较速度,通过和它们的比较,可以简单的跳过多个字节,从而加快了查找速度。当然了,这种策略比起直接的排序后2分查找显然是慢了许多。
4. 权重计算。权重的计算显然和文件结构没有太大关系。但是,已知的是,lucene保存了每个词汇的出现频率和每个域的权重值,这样就可以通过一些简单的公式计算满足要求的文档对本次查询的匹配度了。
五 Nutch对lucene的改进
Nutch据说还是lucene的作者写的,不过,这次这个高手打算直接和商业搜索引擎进行抗衡,他引入了分布式的构架。Nutch一开始就是分布式的,它本来就是定位在百以上量级的集群系统(或者网格)上的。对于搜索引擎来说,除了抓取(或者还包含一些前期的数据处理)外,其余的工作都是信息保存、索引构建和索引查找。Nutch使用的分布式构架,它利用了多台机器的性能来同时构建索引(这一点的可行性在讲MapReduce的google论文里面已经做了详细的描述),这显然能够提高做索引的速度。在索引查找上面,因为索引查找显然不同于做索引,它要求极高的速度和不高的精度。简单的基于MapReduce的方法的最大缺点就是速度慢(因为它简单嘛),所以,这位高手强烈建议不要使用分布式的查找方法,因为速度比单机查找还要慢很多(考虑一下,对于google来说,它的数据量据说达到上百个T,即10万G,没有机器可以挂上这么大的硬盘吧?所以,他们肯定是分布式查询的)。可以肯定的是,Nutch在搜索方面对lucene的改进就是分布式的做索引。当然了,Nutch比lucene好的地方在于它有了抓取程序(虽然十分的原始)。
后记
大家都在热捧这些开源软件,但是,我提醒大家一下:它们距离真正的商业应用还是有一定差距的。或许你会说Nutch不是很好么?它的作者都加入yahoo了。可是,你想过没有?yahoo本来就是做搜索的,它根本就不需要那么简单的技术,它可能基于其它方面的考虑,比如影响度或者创新度。虽然开源软件速度比较慢,但是,你可以通过十分优秀的缓冲算法来弥补它的不足。简单的说,缓冲才是一个追求速度的搜索引擎最需要关心的地方。作者在有空的时候将专门撰文讨论搜索引擎的缓冲处理。
这么多年以来,搜索引擎的构架几乎没有发生任何改变(google使用的构架可以在15年前看到同样的),所以,想在这个方面有所突破几乎不可能了。现在人们的研究热点都集中在信息抓取(抽取,获取)和信息处理上。这些方面的技术还很不成熟,也是能够出现突破的地方。
相关推荐
Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用,甚至某些商业软件也采用了Lucene作为其内部全文检索子系统的...
Lucene 是一个流行的开源...总的来说,Lucene的索引文件格式设计是为了优化存储和检索效率,提供高效的数据结构支持全文搜索。通过理解和掌握这种格式,开发者能够更好地定制和优化Lucene的索引操作,提升搜索性能。
在开发过程中,有时会遇到需要查看二进制索引文件内容的情况,这时可以使用工具如jd-gui.exe(Java反编译器),虽然它主要用于查看Java字节码,但在某些情况下也可以辅助理解Lucene索引文件的组成。然而,由于Lucene...
Lucene 是一个高性能、全文检索的开源库,它主要处理非结构化的数据,如邮件、Word 文档等。与传统的数据库不同,Lucene 更专注于文本的检索,而非存储和管理结构化数据。本文将深入探讨Lucene的核心概念、与其他...
5. **倒排索引**: 倒排索引是Lucene最核心的数据结构,它将每个词对应的所有文档位置存储起来,用于高效检索。 **二、构建文件管理系统的步骤** 1. **初始化**: 创建一个`Directory`对象,这是Lucene索引存储的...
Lucene的API接口设计的比较通用,输入输出结构都很像数据库的表==>记录==>字段,所以很多传统的应用的文件、数据库等都可以比较方便的映射到Lucene的存储结构/接口中。总体上看:可以先把Lucene当成一个支持全文索引...
5. **搜索性能**:Lucene.NET优化了搜索性能,使用内存映射文件和多线程处理,使得搜索速度非常快。同时,它还支持分片和分布式搜索,适合大规模数据集的检索。 6. **结果排序**:搜索结果通常按照相关性排序返回,...
Lucene 是一个高性能、全文本搜索引擎库,由Apache软件基金会开发。在版本3.6中,它提供了强大的文件检索功能,支持对多种文件类型的搜索,包括PDF、Word、PPT、Excel、TXT、HTML和XML等。这个版本的Lucene已经过...
**Lucene实例项目及其打包文件详解** Lucene是一款强大的全文搜索引擎库,由Apache软件基金会开发,广泛应用于各种信息检索系统。这个实例项目是基于Lucene官网提供的,旨在帮助开发者更好地理解和使用Lucene进行...
Lucene.Net 是一个高性能、全文本搜索库,它是Apache Lucene项目的一部分,针对.NET Framework进行了优化。本文将深入探讨如何使用Lucene.Net进行文件检索,特别是针对doc、xls、ppt、txt和pdf等常见文件类型的检索...
它是一款专门针对Lucene 4.7版本设计的索引文件查看和分析工具,帮助我们直观地洞察Lucene索引的内部结构。 LukeAll 4.7.1的核心功能主要集中在以下几个方面: 1. **索引目录选择**:用户可以直接通过双击运行...
1. **索引(Index)**: 在Lucene中,索引是将非结构化的文本数据转换为结构化的倒排索引的过程。倒排索引允许快速查找包含特定词项的文档。 2. **Document**: 代表要索引的一个实体,如一篇文章或一个网页。...
Lucene索引文件结构** Lucene的索引文件主要由以下部分组成: - **倒排索引(Inverted Index)**:记录了每个项在哪些文档中出现,以及对应的频率和位置信息。 - **字段长度表(Field Lengths)**:存储每个文档...
Lucene作为一款高性能、全文检索引擎,被广泛应用于文本搜索场景。本文将详细介绍如何利用Lucene对XML文档进行索引建立的过程,并通过示例代码具体阐述其实现方法。 #### 二、基础知识 1. **Lucene简介** - Lucene...
《深入理解Luke:洞察Lucene索引文件》 在信息技术领域,搜索引擎的高效运作离不开对数据的快速检索,而Lucene作为开源全文检索库,扮演了核心角色。在这个过程中,Luke工具提供了一种直观的方式,让我们能够查看和...
Lucene是一个高性能、全文本搜索库,它为开发者提供了在Java应用程序中实现全文检索的工具集。这个名为“lucene搜索引擎项目”的资源,旨在帮助用户更好地理解和应用Lucene来构建自己的搜索引擎。下面将详细探讨...
在这个Java桌面搜索程序中,Lucene起到了关键作用,它负责索引文件内容并提供高效的查询服务。 首先,我们要理解如何使用Lucene来建立文件索引。在程序启动时,会遍历用户指定的文件夹或硬盘分区,对其中的每个文件...
- **索引(Index)**:索引是Lucene处理数据的核心,它将文本数据转换为可供快速搜索的结构。 - **分词器(Tokenizer)**:分词器将输入的文本分解为一系列的词语,这是建立索引的第一步。 - **分析器(Analyzer)...
Lucene是Apache软件基金会的开源项目,是一个高性能、全文检索引擎的Java库。它不是一个完整的搜索引擎,而是提供了一个强大的文本分析、索引和搜索功能的框架。在标题中提到的"lucene3.6.1文件关键字搜索代码(附加...
**Lucene.Net** 是一个基于Java的全文搜索引擎库,它被移植到了.NET平台,为.NET开发者提供了强大的文本搜索功能。这个库是开源的,由Apache软件基金会维护,遵循Apache许可证,允许开发人员自由使用和修改代码。 ...