Elasticsearch底层原理:文档更新与删除完整执行流程深度剖析

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. 无需锁,高并发读写安全
  2. 利于文件系统缓存
  3. 利于索引压缩与检索优化

1.3 不可变带来的限制

  • 不能直接修改文档
  • 不能直接删除文档
  • 只能新增版本标记删除

二、Elasticsearch 文档更新底层流程(超详细)

2.1 更新操作核心原理

更新 = 先删除旧版本 + 再写入新版本

且所有写操作必须经过 版本号校验,保证并发安全。

2.2 更新完整执行流程(10 步)

  1. 客户端发送更新请求
  2. 协调节点(Coordinating)路由 :根据 _id 计算目标分片
  3. 主分片(Primary Shard)接收请求
  4. 解析文档版本号:检查并发冲突
  5. 标记旧文档为删除(写入 .del 文件)
  6. 写入新版本文档到内存缓冲区
  7. 同步到副本分片(Replica)
  8. 返回更新成功给客户端
  9. 后台定期 refresh:缓冲区 → 新段(可检索)
  10. 后台定期 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 步)

  1. 客户端发送 Delete 请求
  2. 协调节点路由到对应主分片
  3. 主分片检查文档是否存在
  4. 在 .del 文件中标记文档删除
  5. 同步删除标记到副本分片
  6. 返回删除成功
  7. refresh 后标记生效(文档不再被检索)
  8. 段合并(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 要这样设计?(面试高频)

  1. 段不可变是高性能检索的基础
  2. 写操作无需锁,并发能力极强
  3. 标记删除比物理删除快百倍
  4. 批量段合并比实时删除更省 IO
  5. 版本控制保证分布式并发安全

一句话总结:

用写入性能换取检索性能,是 ES 高并发高吞吐的核心设计。


七、常见误区纠正

  1. 更新是直接修改磁盘数据
    ✅ 是标记旧文档 + 写入新文档
  2. 删除后磁盘空间立即释放
    ✅ 只是标记,空间不会立即释放
  3. 更新/删除立即生效
    ✅ 默认 1s refresh 后才生效
  4. 副本是写完主分片再写
    ✅ 主副同步并行,保证高可用

八、生产优化建议

  1. 避免频繁更新:会产生大量段,影响性能
  2. 批量更新/删除:使用 bulk 接口
  3. 定期 force merge:释放磁盘空间(低峰期执行)
  4. 合理设置 refresh_interval:提升写入性能
  5. 更新时使用版本号:防止并发覆盖

九、总结

Elasticsearch 文档更新和删除的底层流程,是理解 ES 高性能的关键:

  1. 更新 = 删旧 + 写新
  2. 删除 = 标记删除
  3. 真正物理删除 = 段合并
  4. 段不可变 = ES 高性能核心

掌握本文内容,你就能彻底理解 ES 写机制,轻松应对面试、调优、故障排查、存储优化等所有场景。


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

相关推荐
大大大大晴天1 小时前
大数据平台为什么必须走向云原生:从资源孤岛到弹性数据基础设施
大数据·云原生
小白说大模型2 小时前
AI驱动的个性化学习路径:知识图谱与知识点关联的存储与推理
大数据·人工智能·学习·mysql·机器学习·prompt·知识图谱
howdoyoudo2026062 小时前
AI审计手记 #01(数据补全版):107小时、17,600次操作——OpenAI越狱案完整攻击链量化分析
大数据·人工智能·安全·ai·语言模型
潘正翔2 小时前
k8s高级_调度器Deployment
linux·运维·云原生·容器·kubernetes·jenkins·devops
hrrrrxeeeee2 小时前
不同基础怎么报考 CAIE 认证|Level I 与 Level II 报考指南
大数据·人工智能·产品经理
Wang's Blog3 小时前
PostgreSQL笔记28: PostgreSQL ACID 特性与实现机制深度解析
大数据·笔记·postgresql
湖南源点调研咨询4 小时前
湖南(源点)市场调研 服务标准化建立指南与切入方式(中篇)
大数据·产品运营·用户运营·用户体验
潘正翔4 小时前
jenkins构建cicd流水线
运维·服务器·ci/cd·容器·自动化·jenkins·cicd
AI_Auto5 小时前
中小企业数字化转型指南 | 拆解中小企业数字化四大转型特征
大数据·人工智能·制造