ES主副分片数据不一致分析
文章目录
- ES主副分片数据不一致分析
- 问题描述
- 问题重现
- 问题分析
- 修复方案
问题描述
在请求索引中的某一条数据时,时而查询有结果,时而无结果。两种情况交替出现。
问题重现
通过对问题数据的点查,确实重现了该现象
GET indexName/typename/docid
问题分析
按照ES写入的设计,是最终一致性的,在进行刷盘之后,应该是不会丢失的。存储物理文件的损坏,应该是引起索引的不健康或者集群的不健康。
ES的底层使用的是Lucene,所以详细分析了对应版本的Lucene物理文件。
下表总结了 Lucene 中文件的名称和扩展名:
Name | Extension | Brief Description |
---|---|---|
Segments File | segments_N | 存储有关提交点的信息,N随着commit的次数增长而增长 |
Lock File | write.lock | 写入锁文件,可防止多个 IndexWriters 向同一文件写入。 |
Segment Info | .si | 记录对应段的元数据 |
Compound File | .cfs, .cfe | 合并当前段内所有文件生产合并文件,.cfe扩展后缀的合并文件用于记 录合并之前段对应的所有文件的元信息,.cfs扩展后缀的合并文件存储的 是合并前段内所有文件的实际数据 |
Fields | .fnm | 记录index对应所有字段的信息 |
Field Index | .fdx | doc通过docId来标识被存储在.fdt的文件中,方便快速的查询到docid对 应的数据需要对doc数据做相关的索引位置记录 |
Field Data | .fdt | 存储doc数据的文件,只有设置Field.Store.YES的field对应的数据才会 被存储在该文件中 |
Term Dictionary | .tim | 术语词典,记录术语信息 |
Term Index | .tip | term被记录存储在.tim中,当term数据很大时需要对term进行索引方便 快速定位到对应的term |
Frequencies | .doc | 记录包含每个术语的文档列表以及频率 |
Positions | .pos | 记录术语在索引中出现的位置 |
Payloads | .pay | 记录额外的每个位置元数据信息,如字符偏移和用户有效载荷 |
Norms | .nvd, .nvm | nvd保存索引文档字段的加权因子的数据,搜索时计算相关性的一个系数,nvm保存索引文档字段加权因子的元数据 |
Per-Document Values | .dvd, .dvm | dvd保存索引文档的评分因子,也用于存储docValues类型的字段数据,即 列存储(正向索引),dvm保存索引文档的评分因子的元数据 |
Term Vector Index | .tvx | 将偏移量存入文件数据文件 |
Term Vector Data | .tvd | 包含术语向量数据。 |
Live Documents | .liv | 有关实时文件的信息 |
Point values | .dii, .dim | 保存索引点(如果有) |
由于使用的不同,并非每个索引下都同时出现以上后缀名的文件。
对副本分片的物理文件进行破坏。
若进行大规模破坏,在下次刷盘时,会触发修复,重新分配分片。
若进行轻微破坏,比如打开下面的文件,轻微删除某条记录。不会被ES感知。集群和索引状态均显示正常。
GET gudong20231012/_doc/igntIYsBVSH_ahC4Fj7-
出现了副本数据查不到,主分片数据可以查询的现象。
判断应该是数据的物理文件出现了损坏,导致数据读不出来了。
修复方案
以当前主分片的数据为准,对副本分片进行重建。重建后的副本会自动获取全部最新的主分片的数据,若此时还是查询不到数据,那么只有重新向ES写入数据了。
先删除副本分片在增加副本。
PUT gudong20231012/_settings
{
"number_of_replicas": 0
}
PUT gudong20231012/_settings
{
"number_of_replicas": 1
}