终于,在一系列强大的4.x功能(最近是4.10.2)发布之后,我们终于在努力开发另一个主要的Apache Lucene版本!
没有确切时间的承诺(完成时就完成了!),但是我们已经有一个自愿发布经理 (谢谢您,Anshum!)。
Lucene的一个主要版本意味着所有不推荐使用的API(从4.10.x版本开始)都将被删除,不再支持3.x索引,同时仍支持众多4.x索引格式以实现向后兼容,并且4.10.x分支成为我们的仅修正错误的发行系列(无新功能,无API更改)。
5.0.0已经包含了许多激动人心的更改,我将在下面进行描述,并且随着正在进行的积极开发它们仍在不断发展。
增强索引安全性
5.0.0的许多更改都集中在提供更强大的保护以防止索引损坏。
所有的文件访问现在使用 Java的API的NIO.2 ,给我们更好的错误处理(例如, Files.delete
返回一个有意义的异常)与原子重命名沿更安全的提交 ,减少了狰狞的风险“整个指数走了”之类的错误此doozie 。
Lucene的复制模块以及在Lucene之上的分布式服务器(例如Elasticsearch或Solr )必须将索引文件从一个位置复制到另一个位置。 他们这样做是出于备份目的(例如, 快照和还原 ),从一个节点到另一个节点的迁移或恢复分片或添加新副本时的目的。 这样的复制器会尝试增量复制,因此,如果存在相同的文件名,且具有相同的长度和校验和,则不会再次复制该文件。
不幸的是,这些层有时会有细微的错误(它们很复杂!)。 由于校验和 (在4.8.0中添加),Lucene已经检测到复制器在复制时是否引起了任何位翻转,这表明Elasticsearch使用的压缩库中存在一个长期存在的令人讨厌的错误 。
在5.0.0版本中,我们可以更进一步,现在通过为每个段和提交分配唯一的ID ( segments_N
文件)来检测整个文件是否复制到错误的文件名。 现在,每个索引文件都在其标头中记录段ID ,然后在打开索引时对这些ID进行交叉检查。
新的Lucene50Codec还包括进一步的索引损坏检测。
甚至CorruptIndexException
本身也得到了改进! 现在,它将始终引用检测到损坏的文件或资源,因为现在这是其构造函数的必需参数。 当更高级别检测到损坏(例如,字段信息文件中的字段编号错误)时,产生的CorruptIndexException
现在将指出文件中是否还存在校验和不匹配,从而有助于缩小损坏的可能来源。
最后,在合并期间, IndexWriter
现在始终在合并之前检查传入的段是否损坏。 这可能意味着,升级到5.0.0后,合并可能会发现旧版4.x索引中长期存在的潜在损坏。
减少堆使用
5.0.0还包括一些更改,以减少索引和搜索期间的堆使用。
如果您的索引具有1B文档,则在4.10.2
缓存单个基于FixedBitSet
的筛选器将花费不小的125 MB堆空间! 但是在5.0.0版本中,Lucene现在支持可随机写和可扩展的稀疏位集( RoaringDocIdSet
和SparseFixedBitSet
),因此所需的堆与设置的位成比例,而不是索引中存在的文档总数。 这些位集还大大简化了MultiTermQuery
的重写方式(不再需要CONSTANT_SCORE_AUTO_REWRITE_METHOD
),并且它们提供了比FixedBitSet
的线性扫描更快的高级实现。 最后,它们提供了更准确的cost()
实现,使Lucene可以更好地选择在查询时如何驱动交叉路口。
新的Lucene50Codec 合并 IndexWriter
期间的堆使用量也要低得多 ,因为合并的段的doc值和规范不再完全加载到所有字段的堆中。 现在将它们加载到当前正在合并的一个字段中,然后删除。
现在,默认的规范格式在适当时使用稀疏编码,因此为许多稀疏字段启用规范的索引将在搜索时看到所需堆的大量减少。
解释堆使用的API
如果仍然发现Lucene使用的堆多于预期,则5.0.0有一个新的API可打印树结构 ,该结构显示递归分解哪些部分正在使用多少堆。 这类似于Lucene的explain API ,用于了解文档为什么具有一定的相关性得分,但适用于堆使用。
它产生如下输出:
_cz(5.0.0):C8330469: 28MB postings [...]: 5.2MB ... field 'latitude' [...]: 678.5KB term index [FST(nodes=6679, ...)]: 678.3KB
与查看凝视Java堆转储相比,这是查看堆中正在消耗什么的更快的方法。
进一步的变化
附加的5.0.0更改很长; 这里是其中的一些:
- 旧的实验性发帖格式(
Sep/Fixed/VariableIntPostingsFormat
)已删除。 PulsingPostingsFormat也已删除,因为默认的发布格式已经产生了唯一的条件。 -
FieldCache
走了(移动到专用UninvertingReader
中misc
模块)。 这意味着当您打算对字段进行排序时,应使用doc值对该字段建立索引,这比FieldCache
快得多,堆消耗更少。 -
Tokenizer
和Analyzer
不再需要在初始状态下使用Reader
。 - 现在,
NormsFormat
获得了自己专用的NormsConsumer/Producer
-
FieldInfo
简化(Lucene的“低模式”):不再需要normType
(它始终是DocValuesType.NUMERIC
),不再需要isIndexed
(只需检查IndexOptions
) - 复合文件的处理更为简单,现在处于编解码器的控制之下。
- 用于对多值字段进行排序的
SortedSetSortField
从沙箱提升为Lucene的核心 -
PostingsFormat
现在写帖子的时候,就像DOC值使用“拉” API。 此功能非常强大,因为您可以采用发布格式进行操作,这些操作需要对发布进行一次以上的遍历操作,例如遍历每个术语的所有发布以决定应使用哪种压缩格式。 - 诸如
IndexWriterConfig
和分析组件之类的类的初始化不再需要版本。
我在这里描述的更改只是我们今天针对5.0.0版本进行的排列的快照。 5.0.0仍在积极开发中(欢迎打补丁!),因此该列表将在实际发行完成时更改。
翻译自: https://www.javacodegeeks.com/2014/11/apache-lucene-5-0-0-is-coming.html