ES 索引切换及验证

验证es源索引和目标索引(通过_reindex或快照恢复得到的)数据是否完全一致
方法一:使用_shards API(检查索引健康和分布)

这是一个辅助检查,用于确保索引的物理分片是健康的,这是数据一致性的基础。

powershell 复制代码
curl -s -k -u elastic:Passw0rd "http://xxx.xx.xxx.172:9200/_cat/shards/group_test*?v"
结果
index           shard prirep state   docs store ip             node
group_test_test 2     r      STARTED    0  226b xxx.xx.xxx.174 Elasticsearch-230502205157_ydhy-dmp3
group_test_test 2     p      STARTED    0  226b xxx.xx.xxx.172 Elasticsearch-230502205157_ydhy-dmp1
group_test_test 1     p      STARTED    0  226b xxx.xx.xxx.173 Elasticsearch-230502205157_ydhy-dmp2
group_test_test 1     r      STARTED    0  226b xxx.xx.xxx.172 Elasticsearch-230502205157_ydhy-dmp1
group_test_test 0     p      STARTED    1 5.6kb xxx.xx.xxx.174 Elasticsearch-230502205157_ydhy-dmp3
group_test_test 0     r      STARTED    1 5.6kb xxx.xx.xxx.173 Elasticsearch-230502205157_ydhy-dmp2
group_test_main 2     r      STARTED    0  226b xxx.xx.xxx.174 Elasticsearch-230502205157_ydhy-dmp3
group_test_main 2     p      STARTED    0  226b xxx.xx.xxx.172 Elasticsearch-230502205157_ydhy-dmp1
group_test_main 1     p      STARTED    0  226b xxx.xx.xxx.173 Elasticsearch-230502205157_ydhy-dmp2
group_test_main 1     r      STARTED    0  226b xxx.xx.xxx.172 Elasticsearch-230502205157_ydhy-dmp1
group_test_main 0     p      STARTED    1 5.6kb xxx.xx.xxx.174 Elasticsearch-230502205157_ydhy-dmp3
group_test_main 0     r      STARTED    1 5.6kb xxx.xx.xxx.173 Elasticsearch-230502205157_ydhy-dmp2
结论:
state必须是STARTED。如果是INITIALIZING,RELOCATING或UNASSIGNED,说明索引还未准备就绪。
主分片(prirep=p)和副本分片(prirep=r)的docs数量应该完全相同。

方法二:检查文档总数(最快、最基础)

使用_cat/countAPI分别获取源索引和目标索引的文档总数。

powershell 复制代码
#检查源索引group_test_main的文档数
curl -s -k -u elastic:Passw0rd "http://xxx.xx.xxx.172:9200/_cat/count/group_test_main?v"

#检查目标索引group_test_test的文档数
curl -s -k -u elastic:Passw0rd "http://xxx.xx.xxx.172:9200/_cat/count/group_test_test?v"
结果
epoch      timestamp count
1767676882 05:21:22  1
epoch      timestamp count
1767676882 05:21:22  1

方法三:使用_search的track_total_hits(更精确的计数)

_cat/count是一个轻量级的统计,但在某些极端情况下(如索引正在被大量更新),它的值可能不是绝对精确的。使用_search并设置track_total_hits:true可以得到更精确的总数。

对两个索引分别执行一个不返回任何文档的搜索,并获取hits.total.value.

powershell 复制代码
#精确计算源索引的文档数
curl -s -k -u elastic:Passw0rd -XPOST "http://xxx.xx.xxx.172:9200/group_test_main/_search?filter_path=hits.total" -H "Content-Type: application/json" -d'{"size": 0,"track_total_hits": true}'

#精确计算目标索引的文档数
curl -s -k -u elastic:Passw0rd -XPOST "http://xxx.xx.xxx.172:9200/group_test_test/_search?filter_path=hits.total" -H "Content-Type: application/json" -d'{"size": 0,"track_total_hits": true}'
结果
{"hits":{"total":{"value":1,"relation":"eq"}}}{"hits":{"total":{"value":1,"relation":"eq"}}}
relation:"eq"表示value是精确的文档总数。

方法四:抽样检查文档内容(验证数据完整性)

在确认总数一致后,需要随机抽取一些文档,对比它们在源索引和目标索引中的内容是否完全相同。

powershell 复制代码
操作步骤:
1、从源索引随机获取一个文档的ID和内容。使用function_score查询可以实现随机抽样。
# 从源索引随机获取一个文档
curl -s -k -u elastic:Passw0rd -XPOST "http://xxx.xx.xxx.172:9200/group_test_main/_search?size=1" -H "Content-Type: application/json" -d'{"query": {"function_score": {"query": { "match_all": {} },"random_score": {}}}}'
从返回结果中记下这个文档的_id 和_source。
{"took":117,"timed_out":false,"_shards":{"total":3,"successful":3,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":0.38136137,"hits":[{"_index":"group_test_main","_type":"_doc","_id":"11564745","_score":0.38136137,"_source":{"client_id":"11564745","prod_code":"004807,004913,005725,005994,007262,017653,019982,020224,020225,020855,020856","wid_valid_flag_20241231":1,"wid_valid_flag":1}}]}}
2、使用这个ID在目标索引中查询对应的文档。
#上一步获取的ID是"11564745"
curl -s -k -u elastic:Passw0rd -XGET "http://xxx.xx.xxx.172:9200/group_test_test/_doc/11564745"
{"_index":"group_test_test","_type":"_doc","_id":"11564745","_version":2,"_seq_no":1,"_primary_term":1,"found":true,"_source":{"client_id":"11564745","prod_code":"004807,004913,005725,005994,007262,017653,019982,020224,020225,020855,020856","wid_valid_flag_20241231":1,"wid_valid_flag":1}}
3、手动或使用脚本对比两个_source的内容。确保所有字段的值都完全一致。建议多抽取几个(如10-20个)不同的文档进行对比。

方法五:使用_validate API(高级,检查查询一致性)

这个方法可以验证对于一个给定的查询,源索引和目标索引的行为是否一致。它不会返回文档内容,而是检查查询的内部执行计划和结果计数是否相同。

powershell 复制代码
# 验证一个简单的 match_all 查询
curl -s -k -u elastic:Passw0rd -XPOST "http://xxx.xx.xxx.172:9200/group_test_main/_validate/query?rewrite=true" -H "Content-Type: application/json" -d'{"query": { "match_all": {} }}'

# 在目标索引上执行同样的查询
curl -s -k -u elastic:Passw0rd -XPOST "http://xxx.xx.xxx.172:9200/group_test_test/_validate/query?rewrite=true" -H "Content-Type: application/json" -d'{"query": { "match_all": {} }}'
结果
{"_shards":{"total":1,"successful":1,"failed":0},"valid":true,"explanations":[{"index":"group_test_main","valid":true,"explanation":"*:*"}]}
{"_shards":{"total":1,"successful":1,"failed":0},"valid":true,"explanations":[{"index":"group_test_test","valid":true,"explanation":"*:*"}]}
结论:如果两个请求的返回结果完全相同,说明索引的结构(Mapping)和数据对于这个查询的理解是一致的。你可以将match_all替换为更复杂的业务查询,来进行更深度的验证。

总结与推荐流程

对于一次重要的数据迁移或备份恢复,推荐的检查流程是:

第一步:检查索引健康使用_cat/shards确保源和目标索引的所有分片都处于STARTED状态。

第二步:校验文档总数使用_search配合track_total_hits:true来精确比较两个索引的文档总数。这是最关键的一步。

第三步:抽样检查数据内容随机抽取多个文档,对比源和目标索引中同ID文档的_source内容,确保数据没有损坏或丢失。

(可选)第四步:深度业务查询验证如果有核心的业务查询,可以使用_validate/query或直接执行查询,对比返回的hits.total是否一致。

通过以上步骤,就可以确认两个索引的数据是否是一致的。

相关推荐
SelectDB9 分钟前
Apache Doris+ Paimon 2.0:构建 Agentic AI 数据闭环
大数据·数据库·数据分析
进击的横打26 分钟前
【人工智能】AI时代公司组织架构的重构
大数据·人工智能·重构
YangYang9YangYan36 分钟前
校招视角|财务数字化岗位 SQL、工具、项目完整备考指南
大数据·数据库·sql
光锥智能1 小时前
小鹏第一位机器人自己走下产线
大数据·人工智能
GISMagic1 小时前
Agent学习,写在开始之前
大数据·学习·agent
Capricorn19881 小时前
知芽 Notebook Skill 引用存在性校验与单元记忆破解幽灵引用危机
大数据·论文阅读·人工智能·论文笔记
hgfsjk2 小时前
跨境电商ERP系统软件哪个好?2026年选型指南
大数据·经验分享·笔记·其他
APItesterCris3 小时前
告别人工盯品!借助 Open‑Claw 快速搭建电商商品全自动监控与数据分析系统(完整实操代码)
java·大数据·前端·数据库
BYSJMG3 小时前
计算机毕设选题推荐:基于大数据的公共交通运营数据分析与可视化,Spark+K-Means聚类城市运营模式
大数据·hadoop·信息可视化·数据分析·spark·kmeans·课程设计
顧棟3 小时前
【ES实战】 低版本Elasticsearch(不具备CCR)集群迁移
大数据·elasticsearch·搜索引擎