Elasticsearch底层原理:文档更新与删除完整执行流程深度剖析
-
- 前言
- [一、前置核心知识:ES 文档为什么不能直接修改?](#一、前置核心知识:ES 文档为什么不能直接修改?)
-
- [1.1 底层存储本质](#1.1 底层存储本质)
- [1.2 不可变带来的好处](#1.2 不可变带来的好处)
- [1.3 不可变带来的限制](#1.3 不可变带来的限制)
- [二、Elasticsearch 文档更新底层流程(超详细)](#二、Elasticsearch 文档更新底层流程(超详细))
-
- [2.1 更新操作核心原理](#2.1 更新操作核心原理)
- [2.2 更新完整执行流程(10 步)](#2.2 更新完整执行流程(10 步))
- [2.3 更新操作流程图](#2.3 更新操作流程图)
- [三、Elasticsearch 文档删除底层流程(超详细)](#三、Elasticsearch 文档删除底层流程(超详细))
-
- [3.1 删除操作核心原理](#3.1 删除操作核心原理)
- [3.2 删除完整执行流程(8 步)](#3.2 删除完整执行流程(8 步))
- [3.3 删除操作流程图](#3.3 删除操作流程图)
- 四、关键底层组件说明(必须理解)
-
- [4.1 .del 文件(删除标记文件)](#4.1 .del 文件(删除标记文件))
- [4.2 Segment(段)](#4.2 Segment(段))
- [4.3 Refresh(刷盘)](#4.3 Refresh(刷盘))
- [4.4 Flush + Merge(合并)](#4.4 Flush + Merge(合并))
- [五、更新 vs 删除 核心区别](#五、更新 vs 删除 核心区别)
- [六、为什么 ES 要这样设计?(面试高频)](#六、为什么 ES 要这样设计?(面试高频))
- 七、常见误区纠正
- 八、生产优化建议
- 九、总结
|-----------------------------|
| 🌺The Begin🌺点点关注,收藏不迷路🌺 |
前言
很多开发者使用 Elasticsearch 执行文档的更新、删除操作时,都以为是直接修改或删除磁盘上的原数据,但这是一个极大的误区!
Elasticsearch 基于 Lucene 实现存储,底层文件是段(Segment)不可变 的,因此更新≠修改、删除≠清除 ,而是一套包含版本控制、写索引、段合并、物理删除的复杂流程。
本文带你深入 ES 底层,从原理 → 详细流程 → 流程图 → 为什么设计如此,彻底讲透文档更新和删除的执行全过程,让你知其然更知其所以然。
一、前置核心知识:ES 文档为什么不能直接修改?
1.1 底层存储本质
ES 底层是 Lucene ,数据以 Segment(段) 形式写入磁盘,段一旦生成就是只读不可变的。
1.2 不可变带来的好处
- 无需锁,高并发读写安全
- 利于文件系统缓存
- 利于索引压缩与检索优化
1.3 不可变带来的限制
- 不能直接修改文档
- 不能直接删除文档
- 只能新增版本 或标记删除
二、Elasticsearch 文档更新底层流程(超详细)
2.1 更新操作核心原理
更新 = 先删除旧版本 + 再写入新版本
且所有写操作必须经过 版本号校验,保证并发安全。
2.2 更新完整执行流程(10 步)
- 客户端发送更新请求
- 协调节点(Coordinating)路由 :根据
_id计算目标分片 - 主分片(Primary Shard)接收请求
- 解析文档版本号:检查并发冲突
- 标记旧文档为删除(写入 .del 文件)
- 写入新版本文档到内存缓冲区
- 同步到副本分片(Replica)
- 返回更新成功给客户端
- 后台定期 refresh:缓冲区 → 新段(可检索)
- 后台定期 flush + merge:删除标记文件,合并小段,释放空间
2.3 更新操作流程图
#mermaid-svg-1sgqH9DnacAMaWk9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1sgqH9DnacAMaWk9 .error-icon{fill:#552222;}#mermaid-svg-1sgqH9DnacAMaWk9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1sgqH9DnacAMaWk9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1sgqH9DnacAMaWk9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1sgqH9DnacAMaWk9 .marker.cross{stroke:#333333;}#mermaid-svg-1sgqH9DnacAMaWk9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1sgqH9DnacAMaWk9 p{margin:0;}#mermaid-svg-1sgqH9DnacAMaWk9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 .cluster-label text{fill:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 .cluster-label span{color:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 .cluster-label span p{background-color:transparent;}#mermaid-svg-1sgqH9DnacAMaWk9 .label text,#mermaid-svg-1sgqH9DnacAMaWk9 span{fill:#333;color:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 .node rect,#mermaid-svg-1sgqH9DnacAMaWk9 .node circle,#mermaid-svg-1sgqH9DnacAMaWk9 .node ellipse,#mermaid-svg-1sgqH9DnacAMaWk9 .node polygon,#mermaid-svg-1sgqH9DnacAMaWk9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1sgqH9DnacAMaWk9 .rough-node .label text,#mermaid-svg-1sgqH9DnacAMaWk9 .node .label text,#mermaid-svg-1sgqH9DnacAMaWk9 .image-shape .label,#mermaid-svg-1sgqH9DnacAMaWk9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-1sgqH9DnacAMaWk9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1sgqH9DnacAMaWk9 .rough-node .label,#mermaid-svg-1sgqH9DnacAMaWk9 .node .label,#mermaid-svg-1sgqH9DnacAMaWk9 .image-shape .label,#mermaid-svg-1sgqH9DnacAMaWk9 .icon-shape .label{text-align:center;}#mermaid-svg-1sgqH9DnacAMaWk9 .node.clickable{cursor:pointer;}#mermaid-svg-1sgqH9DnacAMaWk9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1sgqH9DnacAMaWk9 .arrowheadPath{fill:#333333;}#mermaid-svg-1sgqH9DnacAMaWk9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1sgqH9DnacAMaWk9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1sgqH9DnacAMaWk9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1sgqH9DnacAMaWk9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1sgqH9DnacAMaWk9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1sgqH9DnacAMaWk9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1sgqH9DnacAMaWk9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1sgqH9DnacAMaWk9 .cluster text{fill:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 .cluster span{color:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1sgqH9DnacAMaWk9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1sgqH9DnacAMaWk9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-1sgqH9DnacAMaWk9 .icon-shape,#mermaid-svg-1sgqH9DnacAMaWk9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1sgqH9DnacAMaWk9 .icon-shape p,#mermaid-svg-1sgqH9DnacAMaWk9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1sgqH9DnacAMaWk9 .icon-shape .label rect,#mermaid-svg-1sgqH9DnacAMaWk9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1sgqH9DnacAMaWk9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1sgqH9DnacAMaWk9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1sgqH9DnacAMaWk9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
客户端发送Update请求
协调节点路由到主分片
主分片读取旧文档版本
版本是否冲突?
返回版本冲突异常
标记旧文档为删除
写入新版本到内存缓冲区
同步到副本分片
返回更新成功
后台refresh生成新段
后台merge段,物理删除旧数据
三、Elasticsearch 文档删除底层流程(超详细)
3.1 删除操作核心原理
删除 = 标记删除(.del 文件)
文档不会立即从磁盘删除,只是被标记,真正物理删除靠段合并。
3.2 删除完整执行流程(8 步)
- 客户端发送 Delete 请求
- 协调节点路由到对应主分片
- 主分片检查文档是否存在
- 在 .del 文件中标记文档删除
- 同步删除标记到副本分片
- 返回删除成功
- refresh 后标记生效(文档不再被检索)
- 段合并(merge)时真正物理删除
3.3 删除操作流程图
#mermaid-svg-iQR1wWgB7bOkArG9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iQR1wWgB7bOkArG9 .error-icon{fill:#552222;}#mermaid-svg-iQR1wWgB7bOkArG9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iQR1wWgB7bOkArG9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iQR1wWgB7bOkArG9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iQR1wWgB7bOkArG9 .marker.cross{stroke:#333333;}#mermaid-svg-iQR1wWgB7bOkArG9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iQR1wWgB7bOkArG9 p{margin:0;}#mermaid-svg-iQR1wWgB7bOkArG9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 .cluster-label text{fill:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 .cluster-label span{color:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 .cluster-label span p{background-color:transparent;}#mermaid-svg-iQR1wWgB7bOkArG9 .label text,#mermaid-svg-iQR1wWgB7bOkArG9 span{fill:#333;color:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 .node rect,#mermaid-svg-iQR1wWgB7bOkArG9 .node circle,#mermaid-svg-iQR1wWgB7bOkArG9 .node ellipse,#mermaid-svg-iQR1wWgB7bOkArG9 .node polygon,#mermaid-svg-iQR1wWgB7bOkArG9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iQR1wWgB7bOkArG9 .rough-node .label text,#mermaid-svg-iQR1wWgB7bOkArG9 .node .label text,#mermaid-svg-iQR1wWgB7bOkArG9 .image-shape .label,#mermaid-svg-iQR1wWgB7bOkArG9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-iQR1wWgB7bOkArG9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iQR1wWgB7bOkArG9 .rough-node .label,#mermaid-svg-iQR1wWgB7bOkArG9 .node .label,#mermaid-svg-iQR1wWgB7bOkArG9 .image-shape .label,#mermaid-svg-iQR1wWgB7bOkArG9 .icon-shape .label{text-align:center;}#mermaid-svg-iQR1wWgB7bOkArG9 .node.clickable{cursor:pointer;}#mermaid-svg-iQR1wWgB7bOkArG9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iQR1wWgB7bOkArG9 .arrowheadPath{fill:#333333;}#mermaid-svg-iQR1wWgB7bOkArG9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iQR1wWgB7bOkArG9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iQR1wWgB7bOkArG9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iQR1wWgB7bOkArG9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iQR1wWgB7bOkArG9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iQR1wWgB7bOkArG9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iQR1wWgB7bOkArG9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iQR1wWgB7bOkArG9 .cluster text{fill:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 .cluster span{color:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iQR1wWgB7bOkArG9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iQR1wWgB7bOkArG9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-iQR1wWgB7bOkArG9 .icon-shape,#mermaid-svg-iQR1wWgB7bOkArG9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iQR1wWgB7bOkArG9 .icon-shape p,#mermaid-svg-iQR1wWgB7bOkArG9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iQR1wWgB7bOkArG9 .icon-shape .label rect,#mermaid-svg-iQR1wWgB7bOkArG9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iQR1wWgB7bOkArG9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iQR1wWgB7bOkArG9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iQR1wWgB7bOkArG9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
客户端发送Delete请求
路由到主分片
文档存在?
返回404
标记文档为删除状态
同步标记到副本
返回删除成功
refresh后不可检索
段合并时真正物理删除
四、关键底层组件说明(必须理解)
4.1 .del 文件(删除标记文件)
- 专门记录被删除文档的 ID
- 检索时自动过滤标记删除的文档
- 不占用检索性能,但占用磁盘空间
4.2 Segment(段)
- 最小存储单元
- 只读不可变
- 多个小段合并为大段
4.3 Refresh(刷盘)
- 默认 1s 一次
- 内存 → 新段 → 可检索
- 不保证落盘(断电丢失)
4.4 Flush + Merge(合并)
- 真正写入磁盘
- 真正物理删除标记数据
- 释放磁盘空间
五、更新 vs 删除 核心区别
| 操作 | 底层行为 | 版本控制 | 物理删除时机 |
|---|---|---|---|
| 更新 | 标记旧文档删除 + 写入新文档 | 严格校验版本 | 段合并 |
| 删除 | 仅标记删除 | 不校验版本 | 段合并 |
六、为什么 ES 要这样设计?(面试高频)
- 段不可变是高性能检索的基础
- 写操作无需锁,并发能力极强
- 标记删除比物理删除快百倍
- 批量段合并比实时删除更省 IO
- 版本控制保证分布式并发安全
一句话总结:
用写入性能换取检索性能,是 ES 高并发高吞吐的核心设计。
七、常见误区纠正
- ❌ 更新是直接修改磁盘数据
✅ 是标记旧文档 + 写入新文档 - ❌ 删除后磁盘空间立即释放
✅ 只是标记,空间不会立即释放 - ❌ 更新/删除立即生效
✅ 默认 1s refresh 后才生效 - ❌ 副本是写完主分片再写
✅ 主副同步并行,保证高可用
八、生产优化建议
- 避免频繁更新:会产生大量段,影响性能
- 批量更新/删除:使用 bulk 接口
- 定期 force merge:释放磁盘空间(低峰期执行)
- 合理设置 refresh_interval:提升写入性能
- 更新时使用版本号:防止并发覆盖
九、总结
Elasticsearch 文档更新和删除的底层流程,是理解 ES 高性能的关键:
- 更新 = 删旧 + 写新
- 删除 = 标记删除
- 真正物理删除 = 段合并
- 段不可变 = ES 高性能核心
掌握本文内容,你就能彻底理解 ES 写机制,轻松应对面试、调优、故障排查、存储优化等所有场景。

|---------------------------|
| 🌺The End🌺点点关注,收藏不迷路🌺 |