ElasticsSearch-Segment的组成
在Elasticsearch中,Segment(段)是Lucene的核心数据结构,它是索引不可变的、基础的数据块
每个Segment本质上是一个独立的、微型的倒排索引,它由多个文件组成。这些文件共享一个通用的前缀(即Segment名),并使用不同的扩展名来标识其包含的数据类型
组成
.si
(Segment Info) - 段信息文件- 作用:这是Segment的“元数据文件”。它描述了该Segment的基本信息,例如:
- 该Segment包含了多少文档。
- 使用的Lucene版本。
- 有关该Segment的诊断信息。
- 指向其他组件的“桥接”信息。
- 作用:这是Segment的“元数据文件”。它描述了该Segment的基本信息,例如:
.fnm
(Fields) - 字段信息文件- 作用:存储此Segment中所有字段(Field)的元信息。
- 内容:对于每个字段,记录其:
- 名称(Name)
- 索引选项(Index Options):是否被索引(
INDEXED
)、是否存储词向量(DOCS_AND_FREQS_AND_POSITIONS
)等。 - 属性:是否存储(
STORED
)、是否进行分词(TOKENIZED
)等。 - 使用的编解码器(Codec)信息。
.fdx
(Field Index) 和.fdt
(Field Data) - 存储字段文件- 作用:如果你在映射中设置了
"store": true
,文档的原始JSON内容会被存储到这里,以便于通过stored_fields
API检索。 - 分工:
.fdt
文件是真正存储压缩后的文档数据的地方。.fdx
文件是一个索引文件,它像一个指针簿,可以快速定位到某个文档在.fdt
文件中的具体位置,避免扫描整个.fdt
文件。
- 作用:如果你在映射中设置了
.tim
(Term Dictionary) - 词项字典文件- 作用:这是倒排索引的核心。它包含了该Segment内所有字段的所有词项(Term) 的排序列表。
- 内容:类似于一本字典的“所有词条列表”,例如:
["apple", "banana", "elasticsearch", ...]
。
.tip
(Term Index) - 词项索引文件- 作用:为了快速在
.tim
文件中找到某个词项,.tip
文件存储了.tim
文件的索引。 - 原理:它存储了词项字典的“前缀索引”,类似于字典的“部首检字表”或“拼音索引”。通过
.tip
可以快速跳转到.tim
的大致位置,然后再进行精细查找,极大地减少了磁盘寻址次数。
- 作用:为了快速在
.doc
(Postings List) - 倒排表文件- 作用:存储每个词项对应的倒排列表(Postings List)。
- 内容:对于词项
"apple"
,它的倒排列表会包含所有包含"apple"
的文档ID(DocID),以及在该文档中出现的词频(Term Frequency)。
.pos
(Positions) - 位置信息文件- 作用:存储词项在文档中出现的位置(Position)信息。
- 用途:用于支持短语查询(
"quick brown fox"
) 和 邻近度查询(proximity queries)。如果没有这个文件,ES只能判断一个词是否在文档中出现,而无法判断多个词之间的位置关系。
.pay
(Payloads) - 载荷文件- 作用:存储可选的、与每个位置相关联的额外信息(Payload),例如自定义的权重。
- 用途:这是一个高级功能,使用相对较少。例如,可以在索引时给某个词项附加一个权重值,在查询时使用这个权重来计算相关性分数。
.nvd
,.nvm
(Norms) - 长度规范文件- 作用:存储规范化因子(Norms) 数据,用于在查询时对较短的字段进行奖励(Boost),实现“字段长度归一化”。
- 原理:一个包含10个词的文档命中查询,比一个包含1000个词的文档命中查询,相关性应该更高。Norms数据就用于这种计算。
.dvd
,.dvm
(DocValues) - 列式存储文件- 作用:这是为排序、聚合和脚本访问字段值而设计的列式存储结构。它与倒排索引(行式存储)互为补充。
- 原理:
.dvd
文件存储所有文档某个字段的实际值(例如所有文档的price
),而.dvm
文件存储元数据,帮助定位.dvd
文件中的值。 - 重要性:这是聚合操作(如
terms
,avg
,histogram
)性能高的根本原因。
.liv
(Live Documents) - 存活文档文件- 作用:标记哪些文档是被删除的。由于Segment是不可变的,删除文档并不是直接从文件中抹去数据,而是通过一个特殊的“黑名单”文件来标记该文档已被逻辑删除。
- 后续处理:这些被标记删除的文档会在后续的Segment合并(Merge)过程中被物理清除。
总结
可以将一个Segment想象成一本完整的、不可更改的书:
Segment 文件 | 书的比喻 | 主要用途 |
---|---|---|
.si |
书的版权页、前言、目录总览 | 段的元信息 |
.fnm |
书中所有章节的标题列表 | 字段的元信息 |
(.tip +.tim ) |
书的索引部分(例如,按拼音排序的索引表) | 快速查找词项(倒排索引的“索引层”) |
.doc |
索引表后面指向的页码列表 | 查找包含词项的文档(倒排表) |
(.fdx +.fdt ) |
书的正文内容本身 | 存储原始文档 |
(.dvm +.dvd ) |
书后按类别整理的表格数据(如所有地名列表) | 排序、聚合(列式存储) |
.liv |
一份勘误表,指明哪些页码的内容作废 | 标记删除的文档 |
.pos |
记录某个关键词在页码中出现的具体行数 | 短语查询 |
这些文件共同协作,使得Elasticsearch能够高效地进行全文搜索、精确值处理、聚合分析等各种操作。Segment合并(Merge) 过程本质上就是将这些小“书”合并成大“书”,并在这个过程中物理清除被删除的文档(.liv
文件中的记录),最终优化索引结构和查询性能。