Su的技术博客

  • 首页
  • 原创
  • 视频
  • Java
  • MySQL
  • DDD
  • 事故复盘
  • 架构方案
  • AI
  • Other
  • 工具
    • AI工具集
    • 工具清单
    • JSON在线格式化
    • JSON在线比较
    • SQL在线格式化
  • 打赏
  • 关于
路很长,又很短
  1. 首页
  2. ElasticSearch
  3. 正文
                           

【搜索引擎】Elasticsearch 使用误区之二——频繁更新文档

2025-03-26 276点热度 0人点赞 0条评论

在使用 Elasticsearch 时,频繁更新文档是一种常见误区。这不仅影响性能,还可能导致系统资源的浪费。

理解 Elasticsearch 的文档更新机制对于优化性能至关重要。

关于 Elasticsearch 更新操作,常见问题如下:

Elasticsearch 使用误区之二——频繁更新文档

——https://t.zsxq.com/bDxwL

1、频繁更新的挑战

在关系型数据库中,更新操作在事务完成后立即生效,查询结果可以立刻反映变化。

而在 Elasticsearch 中,更新操作则依赖于刷新(refresh,如下图标红部分)过程。这增加了额外的开销,特别是在频繁更新的场景下。

Elasticsearch 使用误区之二——频繁更新文档

细节参见《一本书讲透Elasticsearch》第342-343页详细阐释。

2、文档更新的步骤

Elasticsearch 更新的本质可以分为以下几个步骤:

Elasticsearch 使用误区之二——频繁更新文档

Elasticsearch 使用误区之二——频繁更新文档

2.1 查找文档

首先,Elasticsearch 根据请求中的文档 ID 或查询条件,在索引中查找需要更新的文档。

2.2 读取并更新

找到文档后,Elasticsearch 会将文档加载到内存中,并根据请求中的更新内容修改文档数据。这包括字段的增加、修改或删除。

2.3 版本控制

Elasticsearch 使用版本号或乐观锁定机制,确保并发更新时数据的一致性。每次更新,版本号都会增加,以避免更新冲突。

示例:首次写入文档,version是 1。

Elasticsearch 使用误区之二——频繁更新文档

查看索引分段信息如下:

Elasticsearch 使用误区之二——频繁更新文档

2.4 重新索引

修改后的文档并不会直接更新到原位置,而是作为一个新文档写入索引。这是因为 Elasticsearch 使用不可变的段文件来存储数据。

继续刚才的示例:更新操作执行一次后,截图如下:_version 由  1 变成 2。

Elasticsearch 使用误区之二——频繁更新文档

更新后查看分段:

Elasticsearch 使用误区之二——频繁更新文档

文档数显示为1(如下图),但其实是两个不同的分段(如上图)。

Elasticsearch 使用误区之二——频繁更新文档

2.5 旧文档标记删除

原始文档被标记为删除。删除标记会在段合并时清理,以节省存储空间。

Elasticsearch 使用误区之二——频繁更新文档

在如下示例中,通过 _delete_by_query 可以看到标记删除的过程。标记的文档将在段合并时被清理。

Elasticsearch 使用误区之二——频繁更新文档

2.6 刷新与合并

更新完成后,Elasticsearch 定期刷新内存中的变更到磁盘,并合并段文件以优化存储和查询性能。

这些步骤确保了 Elasticsearch 在处理更新时的高效性和数据一致性。

更多细节操作参见源码:

https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/update/UpdateHelper.java

3、更新操作的代价

每次更新都涉及到重新索引,而不是简单的“原地”修改。这会增加磁盘 I/O 和计算资源的使用。

此外,标记为删除的文档在段合并前仍然占用空间,增加了存储负担。

第二部分的截图能让我们进一步理解:为什么越更新文档存储占据磁盘空间越大,为什么越删除文档存储占据磁盘越大的原因。

同时,进一步理解,段合并之后,磁盘空间骤降!

4、性能优化建议

4.1. 减少更新频率

实战场景:对于用户行为数据(如浏览次数、点赞数),可以合并多次更新为一次批量更新。

  • 建议1:设置一个合理的批量更新间隔,比如每隔 5 分钟更新一次,而不是每次用户操作后立即更新。

  • 建议2:使用消息队列收集用户操作,定时批量更新。

4.2. 批量处理

实战场景:在电商平台中,商品信息的批量更新。

  • 建议:使用 _bulk API 一次性更新多个文档,减少单次请求的开销。

实践参考:

POST _bulk
{ "update": {"_id": "1"} }
{ "doc": {"price": 100} }
{ "update": {"_id": "2"} }
{ "doc": {"price": 200} }

4.3. 延迟刷新

实战场景:日志数据的批量插入场景。

  • 建议:对不需要实时可见性的索引,增加 refresh_interval,比如设置为 30s 或 60s。

实现:

PUT /my_index/_settings
{
  "refresh_interval": "30s"
}

4.4. 合理的索引设计

实战场景:对于大规模数据的索引设计,避免不必要的字段更新。

  • 建议1:仅索引必要的字段,避免在频繁更新时更新整个文档。
PUT /my_index
{
  "mappings": {
    "properties": {
      "title": {"type": "text"},
      "views": {"type": "integer", "index": false}
    }
  }
}
  • 建议2:在设计阶段多花时间,考虑建模的充分性,在创建索引时明确指定需要索引的字段。

  • 建议3:能 ingest pipeline 预处理管道或者 logstash filter 中间过滤阶段搞定的,咱们就不要拖到实现阶段。

Elasticsearch 使用误区之二——频繁更新文档

Elasticsearch 使用误区之二——频繁更新文档

如下问题的解决方案就是借助:json processor 实现。相比于更新操作,写入前的预处理非常有必要!

Elasticsearch 使用误区之二——频繁更新文档

5、结论

频繁更新文档是 Elasticsearch 使用中的一个常见误区。

理解其更新机制和潜在开销是进行系统优化的关键。通过减少更新频率、使用批量处理、延迟刷新等策略,可以显著提高系统的性能和资源利用率。Elasticsearch 的强大功能需要合理使用,才能充分发挥其优势。

希望这篇文章能够帮助你更好地理解和优化 Elasticsearch 的使用!

 
参考:

https://betterprogramming.pub/boosting-elasticsearch-cluster-performance-3-proven-tips-9b718a9114bc

https://www.youtube.com/watch?v=gWXkAhnYFYw

本文仅供学习!所有权归属原作者。侵删!文章来源:铭毅天下 https://mp.weixin.qq.com/s/LYwV0ZmWFY92On4_bxz8Pw

更多文章:

  1. Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!
  2. Routing Elasticsearch架构VI:路由
  3. Elasticsearch 使用误区之三——分片设置不合理
  4. 殷浩详解DDD 第三讲 - Repository模式
  5. Elasticsearch 使用误区之五——单次请求获取大量数据
  6. Elasticsearch 使用误区之四——不合理的使用 track_total_hits
  7. Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案
  8. Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!
  9. ElasticSearch之各大版本演进,发布8.0.0 Alpha 2版本
  10. 45 个 Git 经典操作场景,专治不会合代码
标签: 搜索引擎 ElasticSearch ES
最后更新:2025-03-30

coder

分享干货文章,学习先进经验。

打赏 点赞
< 上一篇
下一篇 >
广告
文章目录
  • 1、频繁更新的挑战
  • 2、文档更新的步骤
    • 2.1 查找文档
    • 2.2 读取并更新
    • 2.3 版本控制
    • 2.4 重新索引
    • 2.5 旧文档标记删除
    • 2.6 刷新与合并
  • 3、更新操作的代价
  • 4、性能优化建议
    • 4.1. 减少更新频率
    • 4.2. 批量处理
    • 4.3. 延迟刷新
    • 4.4. 合理的索引设计
  • 5、结论
最新 热点 推荐
最新 热点 推荐
视频笔记-微服务架构P4:必懂5种设计模式 视频笔记:微服务架构P4 设计模式:每服务数据库、API 网关和事件驱动架构 干货 | 论Elasticsearch数据建模的重要性 马蜂窝消息总线——面向业务的消息服务设计 基于 MySQL Binlog 实现可配置的异构数据同步 视频笔记:Google发布Agent2Agent协议 视频笔记:什么是微服务,为什么是微服务? 视频笔记:什么是AI 智能体?
基于 MySQL Binlog 实现可配置的异构数据同步马蜂窝消息总线——面向业务的消息服务设计视频笔记:微服务架构P4 设计模式:每服务数据库、API 网关和事件驱动架构干货 | 论Elasticsearch数据建模的重要性视频笔记-微服务架构P4:必懂5种设计模式视频笔记:什么是微服务,为什么是微服务?视频笔记:Google发布Agent2Agent协议
【视频】如何写高效内存Java代码——How to Write Memory-Efficient Java Code Go整洁架构实践 系统设计:边界与封装 - 视频总结 如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具 为啥不建议用BeanUtils.copyProperties拷贝数据 2000 字教你画项目架构图(建议收藏) 系统设计 | 微服务权限检查点 IT事故“破案”大法

CRUD (1) Event Sourcing (1) graphql (1) id (1) NoSQL (1) quarkus (1) rest (1) RocketMQ (2) Spring Boot (1) zk (1) zookeeper (1) 上下文 (1) 事务消息 (1) 二级缓存 (1) 值对象 (1) 关系数据库 (1) 分布式缓存 (1) 原子性 (1) 唯一ID (1) 商品 (1) 多对多 (1) 子域 (1) 字符集 (1) 客户端心跳 (1) 幂等 (2) 干货 (1) 并发 (1) 应用场景 (1) 应用架构图 (1) 康威定律 (2) 异步复制 (1) 微服务架构 (3) 总体方案 (1) 技术方案 (2) 技术架构 (2) 技术架构图 (1) 技能 (1) 持续集成 (1) 支撑域 (1) 故障恢复 (1) 数据架构图 (1) 方案选型 (1) 日记 (1) 服务发现 (1) 服务治理 (1) 服务注册 (2) 机房 (1) 核心域 (1) 泄漏 (1) 洋葱架构 (1) 消息队列 (5) 源码剖析 (1) 灰度发布 (1) 熔断 (1) 生态 (1) 画图工具 (1) 研发团队 (1) 线程 (2) 组织架构 (1) 缓存架构 (1) 编码 (1) 视频 (20) 读写分离 (1) 贵州 (1) 软件设计 (1) 迁移 (1) 通用域 (1) 集群化 (1) 雪花算法 (1) 顺序消息 (1)

推荐链接🔗
  • AI工具集
  • 工具箱🛠️

COPYRIGHT © 2014-2025 verysu.com . ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备15033072号-2

x