前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Lucene索引文件解析

Lucene索引文件解析

原创
作者头像
Yiwenwu
修改2024-05-29 10:01:56
1320
修改2024-05-29 10:01:56
举报
文章被收录于专栏:大数据&分布式大数据&分布式

背景介绍

Lucene作为最优秀的开源搜索引擎,内部实现了复杂的架构和算法,用来支撑对海量数据的存储和搜索。Lucene的存储和搜索都与底层的索引文件息息相关,Lucene发展过程中,也不断对索引文件格式进行优化和调整:

  • 基于FST(Finite State Transducer) 数据结构优化Term Index的查找
  • 基于SkipList(跳表) 优化Postings(倒排表)的查找
  • 基于BK-Tree 优化数值型Field的查找
  • 基于Frame Of Reference 增量编码方式对Postings数据压缩
  • 基于Roaring Bitmaps 加速海量数据的搜索查找
  • 使用Segment Merge(段合并)CompoundFormat(复合格式)减少Segment索引段文件,避免文件句柄过多

索引流程

Lucene索引流程的对外方法主要由IndexWriter提供,创建DocumentsWriterPerThread(DWPT)对象,该对象实现不同Index索引下,支持并发执行索引流程。DWPT的索引执行流程由DefaultIndexingChain(索引链)定义,描述了整个索引流程。

每个DWPT都有一定的内存空间,Document执行完索引流程后,索引数据保存在内存中,当触发一定条件后,才刷新(flush)到文件系统,触发条件如下:

  • 超过IndexWriterConfig中定义的ramBufferSizeMB,默认16MB;
  • 超过IndexWriterConfig中定义的maxBufferedDocs,默认-1,不受Doc索引数量限制;
  • 基于MergeScheduler和MergePolicy定时执行Segment段合并操作,
  • 用户主动调用刷新操作:flush()、commit()、close()等;

索引执行流程图如下,核心是执行DefaultIndexingChain(索引链)定义的索引流程:

索引文件

存储形态

Index索引目录下,有多个Segement构成,每个Segment由多个物理上具体的索引文件构成,同个Segment下的索引文件,具有相同的文件前缀,不同后缀的索引文件保存索引不同部分的信息。索引目录下索引文件大致如下:

架构关系

索引文件的架构关系如下:

  • Segments_N:所有的Segment元数据,一个索引目录下只有一个该文件;
  • write.lock:该索引的写操作锁,同个索引下不支持并发写
  • SegmentFiles:索引段包括的索引文件列表,右图所示,主要包括三部分
    • .si:对应Segment下的汇总和元数据
    • .cfs,cfe:复合索引文件,由多个Segment合并成的索引文件
    • 除上外,剩余的索引文件:单个Segment的索引文件构成,包括FieldInfo,倒排索引,DocValues、Term的额外信息

每个Segment的所有索引文件,是整个索引的子集,是一个独立的子索引,因此Lucene搜索可以基于每个Segment执行,提高搜索的并行度。

类型说明

各索引类型的概要说明,官方文档

每个索引Segment文件,包含以下内容:

  • Segment info:汇总并存储各个Segment元数据,如文档数量、索引目录、Segment大小等
  • Field names:存储索引中的Field名称集合
  • Stored Field values:存储每个Document的属性键值对(attribute-value),描述Document的附加信息,以Document Number为键值。同时保存了设置为stored的Field,使得搜索时可以返回对应的Field值
  • Term dictionaryTerm字典,存储所有被索引的Terms信息,除了Term Value值外,还包括:含有该Term的所有Document数量Term Frequency和 Proximity 的指针
    • Term Frequency:每个Term的DF(文档频次),TF(词频)等信息
    • Term Proximity:每个Term在各个Document的Position(位置)信息
  • Normalization factors:每个Field的归一化因子,搜索时与hits score相乘得到算分
  • Term Vectors:Term向量,与Term文本和TF(词频相关)
  • Per-document values:以Document Number为键值,预先将搜索的汇总结果存储到内存中,便于scoring factors(打分因子)打分计算,以加速搜索
  • Live documents:存储当前没有被删除的Document信息
  • Point values:存储数值型索引Field,便于快速的数值Range查询,以KD-tree数据结构保存

上述所有文件,文件名称不会重复使用,同个Segment下的索引文件有相同的文件前缀,使用Compound File format小文件合并后,所有索引文件合并为一个文件,以.cfs为后缀名

索引文件汇总列表如下:

名称

后缀

说明

执行对象

Segments Files

segments_N

存储所有Segments元数据和commit point

Segment Info

.si

存储Segment元数据

Compound File

.cfs,.cfe

复合的索引文件,对其他索引文件进行定期合并

Field File

.fnm,.fdx,.fdt

.fnm: 所有Field的属性信息; .fdx: 指向指定FieldData(.fdt数据)的指针索引; .ftd: Document下持久化的Field信息

Inverted Index

.tim,.tip,.doc,.pos,.pay

.tim: Term Directory列表; .tip: Term Directory的索引,加速Term的查找; .doc: Term值和词频信息; .pos: Term在各个Doc下的位置信息; .pay: Term的payload和偏移量;

Norms

.nvd, .nvm

存储Field的归一化因子信息,其中: .nvd: 归一化值; .nvm: 归一化元数据;

Per-Document Values

.dvd,.dvm

存储DocValues: .dvd: DocValues数据; .dvm: DocValues元数据;

Term Vector Info

.tvx ,.tvd

存储Term向量信息: .tvd: TermVector值; .tvx : TermVector索引;

Point values

.dii, .dim

存储index索引的Point信息: .dii: 指向.dim的指针; .dim: Point数据信息;

Live Documents

.liv

存储Document活跃信息

类型图解

segments_N、.si

存储所有Segments元数据和commit point

代码语言:txt
复制
segments_N --> Header, LuceneVersion, Version, NameCounter, SegCount, MinSegmentLuceneVersion, <SegName, SegID, SegCodec, DelGen, DeletionCount, FieldInfosGen, DocValuesGen, UpdatesFiles>SegCount, CommitUserData, Footer
.si --> Header, SegVersion, SegSize, IsCompoundFile, Diagnostics, Files, Attributes, IndexSort, Footer

.cfs、.cfe

复合的索引文件,对其他索引文件进行定期合并

代码语言:txt
复制
.cfs --> Header, <FileData> FileCount, Footer
.cfe --> Header, FileCount, <FileName, DataOffset, DataLength> FileCount

.fnm、.fdx、.fdt

存储Field属性相关信息,其中 .fnm: 所有Field的属性信息;.fdx: 指向指定FieldData(.fdt数据)的指针索引;.ftd: Document下持久化的Field信息

代码语言:txt
复制
.fnm --> Header,FieldsCount, <FieldName,FieldNumber, FieldBits,DocValuesBits,DocValuesGen,Attributes,DimensionCount,DimensionNumBytes> FieldsCount,Footer
.fdx --> <Header>, <ChunkIndex>, Footer
.fdt --> <Header>, PackedIntsVersion, <Chunk>ChunkCount, ChunkCount, DirtyChunkCount, Footer

.tim、.tip

存储Term Directory相关信息,其中.tim: Term Directory列表;.tip: Term Directory的索引,加速Term的查找;

代码语言:txt
复制
.tim --> Header, PostingsHeader, NodeBlockNumBlocks, FieldSummary, DirOffset, Footer
.tip --> Header, FSTIndexNumFields <IndexStartFP>NumFields,

.doc、.pos、.pay

存储Term Directory相关信息,.doc: Term值和词频信息;.pos: Term在各个Doc下的位置信息;.pay: Term的payload和偏移量;

代码语言:txt
复制
.doc --> Header, <TermFreqs, SkipData?>TermCount, Footer
.pos --> Header, <TermPositions> TermCount, Footer
.pay --> Header, <TermPayloads, TermOffsets?> TermCount, Footer

.nvd、.nvm

存储Field的归一化因子信息:其中:.nvd: 归一化值;.nvm: 归一化元数据;

代码语言:txt
复制
.nvd --> Header,<Data>NumFields,Footer
.dvm --> Header,<Entry>NumFields,Footer

.dvd、.dvm

存储DocValues

.tvx、.tvd

存储Term向量信息

.dim

存储index索引的Point信息:

.liv

存储Document活跃信息:

总结

Lucene通过索引实现高效的全文检索,而索引的数据结构设计是对于检索性能是至关重要的,优良的索引结构能够加速数据读写,提升查询性能。本文主要解析了Lucene的索引文件,并对索引流程和索引文件进行了详细说明。

参考附录

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
  • 索引流程
  • 索引文件
    • 存储形态
      • 架构关系
        • 类型说明
          • 类型图解
            • segments_N、.si
            • .cfs、.cfe
            • .fnm、.fdx、.fdt
            • .tim、.tip
            • .doc、.pos、.pay
            • .nvd、.nvm
            • .dvd、.dvm
            • .tvx、.tvd
            • .dim
            • .liv
        • 总结
        • 参考附录
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档