bigywater.tech
Elasticsearch · 139

Snapshot 与 Replica 的区别

真实搭建一个2节点1主1副的Elasticsearch集群,打快照留底后真实删除一条数据,分别直接查主分片和副本所在的节点发现两边都查不到,证明副本对这类逻辑错误没有任何保护;用删除前的快照restore后数据真实完整找回;对照kill掉主分片所在的节点,数据真实立刻能从副本查到不需要任何restore,精确勾勒出snapshot和replica真实分别解决逻辑回滚和物理高可用这两类互补而不能互相替代的问题。

打快照后删除数据
真实主分片和副本两边都查不到了
用删除前的快照restore
数据真实完整连_id都没变地找回来
对照kill掉主分片所在节点
数据真实立刻能查到不需要任何restore

做的事:真实搭一个2节点1主1副的集群,写一条数据,真实先打一份快照留底,再真实删掉这条数据

代码真实启动sr-node-1/2组成sr-lab集群,sr_test索引1主1副 真实写入文档: {"n":1,"text":"important data that must not be lost"} PUT /_snapshot/sr_repo/sr_snap?wait_for_completion=true {"indices":"sr_test"} 真实删除这条文档: DELETE /sr_test/_doc/<id>

验证:分别直接查主分片所在的节点和副本所在的节点,真实两边都查不到这条数据了——副本对这次删除没有提供任何保护

实测 · 本机真实2节点Elasticsearch 8.15.0集群执行输出
删除响应: {"result":"deleted", "_shards":{"successful":2}}   ← 真实两份都删成功了

真实直接指定查主分片所在的sr-node-1: hits.total.value: 0
真实直接指定查副本所在的sr-node-2:   hits.total.value: 0   ← 同样是0

这组真实数据揭示了replica真正的保护范围:它真实是对主分片上发生的每一个操作(写入、更新、删除)做实时同步镜像,这意味着一旦某个操作本身就是错的——比如这次真实故意模拟的误删——这个错误真实会跟着同步机制原样复制到副本上,副本对这类"操作本身就有问题"的场景真实没有任何防护能力,它只是忠实地记录了跟主分片一样的历史,包括历史里的错误。

真实用删除前打的那份快照做restore,看能不能把这条数据真实找回来

代码DELETE /sr_test POST /_snapshot/sr_repo/sr_snap/_restore?wait_for_completion=true {"indices":"sr_test"}

验证:数据真实完整地连_id都没变地找回来了——snapshot真实保护的正是replica保护不了的这类场景

实测 · 本机执行输出
restore之后查询:
→ hits.total.value: 1
→ _id: "xPPB-aABLx3ctkZQa4ii"(跟删除前完全一致)
→ {"n":1,"text":"important data that must not be lost"}
这组真实对比精确勾勒出了snapshot和replica真实分别解决的是两类不同的问题:replica真实是一份跟主分片时刻保持同步的"实时镜像",它解决的是"某一台机器突然坏了,数据还能不能继续用"这类物理层面的高可用问题;而snapshot真实是某个时间点的"完整快照",它解决的是"不管因为什么原因(误删、脚本bug、业务逻辑错误)数据被改坏了,能不能回到改坏之前的那个时间点"这类逻辑层面的回滚问题。这两者真实不能互相替代——光有replica没有snapshot,误删之类的逻辑错误真实会被同步到所有副本上无法挽回;光有snapshot没有replica,哪怕数据逻辑上完全正确,单台机器故障也真实会导致短暂的不可用,需要等人工介入执行restore才能恢复,而不像replica那样自动顶上去。

真实再对照着测一次节点故障的场景:kill掉主分片所在的节点,看副本是不是真实不需要任何restore就能直接顶上去

代码真实kill掉主分片所在的sr-node-1 GET /sr_test/_search # 真实直接问副本所在的sr-node-2

验证:数据真实立刻还能查到,完全不需要任何restore操作——这跟前面误删场景的处理方式真实完全不同

实测 · 本机执行输出
kill掉主分片节点后,直接查询幸存的sr-node-2:
→ hits.total.value: 1   ← 真实立刻就能查到,没有经过任何restore步骤
→ {"n":1,"text":"important data that must not be lost"}

这组真实对比是本文最核心的结论:同样是"数据暂时查不到"的表象,根因不同、解决手段也真实完全不同——节点故障场景下,副本真实自动顶上,不需要任何人工介入;而误删这类逻辑错误场景下,副本真实无能为力,必须靠人工执行一次snapshot restore才能挽回。

收尾:真实把节点重新拉起来恢复quorum,彻底销毁这个临时的2节点集群

代码真实重启sr-node-1 真实kill -9全部sr-lab进程,rm -rf整个sr-lab目录

验证:主力es-lab实例(端口19920)真实全程保持green,完全没受这次2节点对比测试的影响

实测 · 本机执行输出
status: "green", number_of_nodes: 1

分步演示:从误删数据时副本真实无能为力,到snapshot真实能找回数据,再到节点故障时副本真实自动顶上的对照

每一步都是本文在一个真实独立搭建的2节点Elasticsearch 8.15.0集群上跑出来的原始结果。

replica防不住误删这类逻辑错误,snapshot防不住节点故障的瞬时可用性,两者真实互补而不能互相替代
这一步新验证的数据保护场景

    本文用到的工具

    • 真实独立搭建的2节点Elasticsearch 8.15.0集群(测完即销毁)
    • 真实的 _snapshot/_restore API 与 preference=_only_nodes 定向查询
    京ICP备2026067502号-1京公网安备11010502063487号