ES的文档更新机制

     想获取更多高质量的Java技术文章?欢迎访问Java技术小馆官网,持续更新优质内容,助力技术成长

Java技术小馆官网https://www.yuque.com/jtostring

ES的文档更新机制

   在现代应用中,数据的动态性越来越强,我们不仅需要快速地索引和查询数据,还需要能够有效地更新这些数据。ES作为一个强大的分布式搜索引擎,其文档更新机制设计得相当巧妙,以确保数据的一致性与可用性。

在ES中,文档并不是一成不变的,它们可以随着业务需求的变化而不断更新。这一过程并非简单地替换旧数据,而是涉及到版本控制和冲突管理等复杂的机制。在并发环境下,多个请求同时更新同一文档时,如何确保数据的完整性和一致性,成为我们需要解决的重要问题。

文档更新机制

Elasticsearch(ES)的文档更新机制是其核心功能之一,设计旨在提供高效、可靠的文档修改能力。在ES中,每个文档都由一个唯一的ID标识,并存储在指定的索引中。文档更新的过程并非直接修改原有文档,而是采用了一种写时复制的策略,确保数据的一致性和高效性。

1. 更新操作的基本流程

当一个文档需要更新时,ES首先会生成该文档的最新版本。更新的过程包括以下几个步骤:

  • 获取当前版本:在更新之前,系统会读取当前文档的状态和版本号。
  • 创建新文档:根据提供的更新信息,创建一个新的文档版本。此时,旧版本文档仍然保持不变。
  • 标记旧文档为删除:在创建新版本后,旧文档被标记为删除,但物理上并不会立即从磁盘中移除。这样可以确保在高并发情况下,其他读取操作仍可访问到最新的有效数据。
  • 提交更新:新文档被持久化到索引中,并更新文档的版本号。

2. 版本控制

ES使用版本控制来处理并发更新。当多个客户端尝试同时更新同一文档时,ES会利用文档的版本号来判断更新的合法性:

  • 乐观锁:在更新请求中,客户端需要提供当前文档的版本号。ES会比较这个版本号与存储中的版本号,确保更新的文档是基于最新的状态进行的。如果版本号不匹配,说明该文档已被其他请求更新,此时更新将失败,客户端需要重新获取文档并再次尝试更新。

3. 并发冲突处理

在高并发场景下,如何处理文档更新冲突是设计中的一个重要考虑。ES提供了以下几种策略:

  • 重试机制:当更新操作失败时,客户端可以捕获到版本冲突异常,并根据应用逻辑选择重试更新。
  • 合理设计应用逻辑:在设计数据更新流程时,可以通过合并变更或批量处理来减少并发冲突的发生几率。

4. 性能考虑

文档更新机制需要平衡性能与一致性。虽然使用写时复制提高了数据安全性,但在更新频繁的场景下,可能导致较高的存储开销。因此,适当的索引设计、合理的更新策略及对版本管理的优化是提高系统性能的关键。

更新操作的类型

在Elasticsearch中,文档更新操作主要有几种不同的类型,每种类型适用于特定的使用场景和需求。理解这些更新操作的类型,有助于更有效地管理和优化数据处理过程。

1. 全量更新(Full Update)

全量更新是指对一个文档进行完全替换。更新请求包含整个文档的内容,ES会将现有文档替换为新的版本。这种方式适用于当文档内容发生较大变化时,且更新的数据量相对较小。

  • 优点:操作简单,易于理解,适合一次性修改大部分字段。
  • 缺点:如果文档较大或更新频繁,可能会造成较高的存储开销。

2. 部分更新(Partial Update)

部分更新允许用户仅更新文档中的某些字段,而不必提供整个文档。这通过使用update API实现,用户只需指定需要更改的字段及其新值。

  • 优点:节省带宽和存储空间,特别适用于大文档中的小改动。性能相对较高,因为只涉及必要的字段。
  • 缺点:可能导致更新过程中数据的不一致,特别是在多次快速更新的情况下。

3. 脚本更新(Scripted Update)

脚本更新允许用户通过自定义脚本对文档进行动态修改。用户可以编写脚本来执行复杂的更新逻辑,例如根据当前值计算新值。

  • 优点:提供灵活性,可以实现复杂的业务逻辑,适合动态变化的场景。
  • 缺点:性能开销可能较大,尤其是在高并发情况下,复杂的脚本可能会影响更新速度。

4. 批量更新(Bulk Update)

批量更新允许一次性对多个文档进行更新,适合在处理大量数据时使用。通过bulk API,可以将多个更新操作打包为一个请求,显著提高效率。

  • 优点:减少网络延迟,降低请求数量,提升处理速度。
  • 缺点:需要合理设计批量大小,以避免超出系统的处理能力。

5. 条件更新(Conditional Update)

条件更新通过版本控制实现,只在满足特定条件时才执行更新操作。例如,可以在更新请求中包含一个版本号,确保文档在更新时没有被其他请求修改。

  • 优点:增加数据一致性,确保更新操作的原子性。
  • 缺点:可能导致重试逻辑的复杂性,特别是在高并发场景中。

更新过程详细步骤

在Elasticsearch中,文档的更新过程是一个复杂而高效的操作,涉及多个步骤和机制。以下是文档更新的详细步骤,以及每一步所涉及的关键概念。

1. 接收更新请求

当应用程序发起文档更新请求时,它会通过REST API向Elasticsearch发送HTTP请求。更新请求通常包含要更新的文档ID、要更新的字段及其新值,以及更新类型(全量或部分更新)。

2. 请求解析

Elasticsearch接收到请求后,会解析请求内容,提取出目标索引、文档ID、要更新的字段及值等信息。此时,系统会检查请求的有效性,包括目标索引是否存在,文档ID是否有效等。

3. 文档查找

Elasticsearch使用分片机制来快速定位存储文档的分片。系统会根据文档ID计算出对应的分片,并在该分片中查找目标文档。如果文档存在,系统将继续处理;如果不存在,处理结果可能是创建新文档(在使用全量更新时)。

4. 获取文档的当前版本

在更新过程中,Elasticsearch会读取文档的当前版本号,这是实现乐观锁的关键。版本号用于判断在更新过程中文档是否被其他请求修改,以防止数据不一致。

5. 文档更新

根据更新类型的不同,Elasticsearch会执行以下操作:

  • 全量更新:用新的文档替换旧的文档。系统会删除旧文档并创建新文档,新的版本号会加1。
  • 部分更新:系统只更新指定的字段。此时,Elasticsearch会读取当前文档的内容,并将需要更新的字段值替换为新的值,保留其他字段不变。
  • 脚本更新:如果更新请求中包含脚本,系统会在执行更新之前运行该脚本。脚本可以访问当前文档的所有字段并根据业务逻辑计算新值。

6. 版本检查

在更新过程中,Elasticsearch会检查当前文档的版本号是否与请求中的版本号一致。这是实现乐观锁的一部分。若版本不一致,更新请求将被拒绝,返回冲突错误。用户可以根据需要选择重试或处理冲突。

7. 写入操作

一旦文档成功更新,Elasticsearch会将更新操作写入内存中的缓冲区(translog)。此时,更新操作仍然是暂时的,只有在数据持久化后才会成为永久性更改。

8. 刷新与持久化

  • 刷新:Elasticsearch会在后台定期刷新缓冲区,将内存中的数据写入磁盘索引。此时,更新的数据才会对搜索可见。用户也可以手动触发刷新,但这会影响性能。
  • 持久化:数据在刷新后会持久化到磁盘,确保在节点重启或故障时数据不会丢失。

9. 更新的确认

更新操作完成后,Elasticsearch会向客户端发送确认响应,指示更新是否成功。如果更新过程中发生任何错误或冲突,系统会返回相应的错误信息。

并发更新处理

在Elasticsearch中,处理并发更新是确保数据一致性和系统稳定性的关键。由于Elasticsearch是一个分布式系统,多个客户端可能同时尝试更新同一文档。为此,Elasticsearch采用了乐观锁机制和版本控制来有效管理并发更新。

1. 乐观锁机制

Elasticsearch使用乐观锁来处理并发更新。这种机制允许多个更新请求并行处理,但在实际更新时会检查文档的版本号,从而防止数据冲突。

  • 版本号:每个文档都有一个版本号,代表该文档的当前状态。当文档被更新时,版本号会自增。更新请求中可以包含一个期望的版本号,用于检查当前文档的版本是否与期望一致。

2. 更新请求

当多个客户端同时发送更新请求时,Elasticsearch会为每个请求执行以下操作:

  • 版本检查:在处理更新请求时,系统会读取目标文档的当前版本号,并与请求中的版本号进行比较。
    • 一致:如果版本一致,系统会继续执行更新操作。
    • 不一致:如果版本不一致,Elasticsearch会返回冲突错误(通常是HTTP 409)。这意味着在更新请求发出后,目标文档已被其他请求修改。

3. 冲突处理策略

在处理版本冲突时,Elasticsearch提供了几种处理策略:

  • 重试机制:客户端可以选择重试更新请求。在重试时,客户端通常会重新获取最新的文档版本,以确保更新是基于最新状态的。
  • 放弃更新:客户端也可以选择在发生版本冲突时放弃更新。这样可以避免不必要的重试开销,尤其是在高并发环境中。
  • 合并更新:某些应用场景可能需要合并多个更新。客户端可以先读取当前文档的最新状态,然后计算出合并后的新值,再进行更新。这种方法需要客户端处理逻辑复杂性。

4. 脚本更新与冲突

使用脚本更新时,Elasticsearch会在执行脚本之前进行版本检查。这种情况下,脚本的执行可能会涉及到复杂的逻辑,因此要确保脚本能处理并发冲突。

  • 原子性:脚本执行是在单个操作中完成的,确保在版本检查通过后,文档的状态不会在脚本执行过程中被其他更新所影响。

5. 事务性更新

Elasticsearch本身不支持严格的事务性,但通过版本控制,开发者可以在应用层实现事务性逻辑。例如,可以通过事务管理工具来协调多个更新操作,确保在发生冲突时能够回滚到安全状态。

6. 监控与调优

在高并发环境下,监控Elasticsearch的性能和版本冲突率非常重要。开发者可以通过监控工具观察冲突数量、重试次数等指标,及时调整更新策略和系统配置。

  • 参数调整:根据监控结果,可以调整Elasticsearch的索引设置(如刷新频率、分片数)和客户端的重试策略,以优化并发更新性能。

更新性能优化

在Elasticsearch中,更新性能优化是确保系统高效响应和减少资源消耗的关键。由于Elasticsearch的设计理念是针对搜索和分析优化,更新操作相对较为复杂,尤其是在高并发场景下。

1. 批量更新操作

  • 使用Bulk API:Elasticsearch支持批量操作,可以通过Bulk API一次性提交多个更新请求。这样可以减少网络往返次数,降低请求开销,提高整体更新性能。
  • 合理设置批量大小:在进行批量更新时,合理选择每个批次的大小非常重要。过大的批量可能导致内存压力,而过小的批量则无法充分利用网络带宽。一般来说,建议每批次处理数十到几百条记录。

2. 版本控制优化

  • 减少版本冲突:在高并发环境中,频繁的版本冲突会导致性能下降。通过合理设计应用逻辑,例如减少对同一文档的竞争更新,或在应用层实现合并逻辑,可以有效降低冲突发生率。
  • 使用乐观并发控制:在进行更新时,尽量使用乐观锁而不是悲观锁,降低因锁竞争引起的性能瓶颈。

3. 索引设计

  • 使用合适的分片和副本设置:合理设置索引的分片数量和副本,可以提升写入性能。分片过多会增加管理开销,而分片过少则可能造成单个分片的写入瓶颈。
  • 避免频繁的映射变化:每次对索引映射的修改都会引发重建过程,影响性能。提前设计好文档结构和映射,减少后续的变更。

4. 刷新与合并策略

  • 调整刷新间隔:Elasticsearch默认每秒会刷新一次索引,这会导致频繁的写入操作。如果对实时性要求不高,可以通过调整refresh_interval参数来减少刷新频率,从而提高写入性能。
  • 控制合并策略:定期合并段会提高查询性能,但在高频更新时会影响写入性能。可以根据业务需求,调整合并策略和合并的触发条件。

5. 使用脚本更新

  • 减少数据传输:通过脚本直接在Elasticsearch中进行更新,可以减少从客户端传输数据的需求,从而提高更新速度。脚本允许在Elasticsearch服务器端执行逻辑,直接更新文档内容。
  • 确保脚本性能:编写高效的脚本逻辑,避免不必要的复杂计算和资源消耗,以保证脚本执行时的性能。

6. 资源监控与调整

  • 监控性能指标:使用Elasticsearch提供的监控工具,实时观察更新操作的性能,特别是请求延迟、冲突率和资源使用情况。
  • 集群规模与资源分配:根据监控结果,适时扩展集群规模,增加节点或调整内存、CPU等资源分配,确保集群能够承受高负载的更新请求。

7. 合理的应用设计

  • 设计合理的更新逻辑:避免不必要的更新操作,例如在数据未变动时不进行更新。可以在应用层进行缓存或数据比较,以降低更新频率。
  • 使用事件驱动架构:通过消息队列等机制,将更新请求异步处理,减少对主流程的阻塞,提高系统响应能力。

更新对索引和查询的影响

在Elasticsearch中,文档更新不仅影响索引的性能,还会对查询性能产生深远的影响。这是由于Elasticsearch的底层设计及其在处理更新时的机制。

1. 索引的影响

  • 更新操作的复杂性:Elasticsearch采用的是一种基于Lucene的倒排索引结构。当文档被更新时,实际上并不是在原位置直接修改数据,而是创建一个新的文档版本,并将其插入到索引中。这一过程包括删除旧文档的引用并添加新文档的引用,这会引起一定的索引开销。
  • 段合并:更新导致的文档版本增加会产生更多的段。Elasticsearch会定期合并这些段,以优化存储和查询性能。然而,在合并的过程中,更新操作会导致CPU和I/O的负载增加,影响系统的整体性能。频繁的更新操作可能使得合并过程更加复杂,从而增加延迟。
  • 内存和存储消耗:每次更新都会消耗额外的内存和存储空间,因为更新会暂时保留旧版本,直到合并完成。这可能导致内存压力增大,尤其是在高更新频率的场景中,增加了系统的内存使用。

2. 查询的影响

  • 查询延迟:在高并发更新的情况下,查询延迟可能会增加。尤其是当系统正在进行大量更新操作时,查询可能会遇到更多的延迟,因为数据可能在多次更新中处于不一致状态。此时,系统需要更多的资源来处理并发的读写请求。
  • 数据一致性:在更新过程中,用户在查询时可能会看到过时的数据,尤其是在使用实时搜索的场景下。Elasticsearch的默认刷新间隔为1秒,这意味着更新后的数据可能在此时间段内不可见,导致短暂的数据不一致问题。
  • 影响查询结果:当某个文档被更新后,如果查询的条件与更新前的数据相关,可能会导致查询结果的显著变化。尤其是在使用聚合查询时,频繁的更新可能导致聚合结果的不稳定,从而影响数据分析的准确性。

3. 性能调优

  • 调整刷新策略:通过调整refresh_interval参数,可以减少索引的刷新频率,从而提高写入性能。在对实时性要求不高的情况下,适当延长刷新时间可以减少查询的延迟。
  • 使用版本控制:乐观锁和版本控制机制可以减少并发更新带来的冲突,从而降低对查询性能的影响。
  • 监控与分析:实时监控查询性能和更新操作的指标,及时调整系统资源和配置,以确保查询和索引性能的平衡。

想获取更多高质量的Java技术文章?欢迎访问Java技术小馆官网,持续更新优质内容,助力技术成长

Java技术小馆官网https://www.yuque.com/jtostring

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/899834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

trae.ai 编辑器:前端开发者的智能效率革命

一、为什么我们需要更智能的编辑器? 作为从业5年的前端开发者,我使用过从Sublime到VSCode的各种编辑器。但随着现代前端技术的复杂度爆炸式增长(想想一个React组件可能涉及JSX、CSS-in-JS、TypeScript和GraphQL),传统…

MySQL篇(一):慢查询定位及索引、B树相关知识详解

MySQL篇(一):慢查询定位及索引、B树相关知识详解 MySQL篇(一):慢查询定位及索引、B树相关知识详解一、MySQL中慢查询的定位(一)慢查询日志的开启(二)慢查询日…

uniapp APP端在线升级(简版)

设计思路: 1.版本比较:应用程序检查其当前版本与远程服务器上可用的最新版本 2. 更新状态指示:如果应用程序是不是最新的版本,则页面提示下载最新版本。 3.下载启动:通过plus.downloader.createDownload()启动新应用…

基于javaweb的SpringBoot教务课程管理设计与实现(源码+文档+部署讲解)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

使用大语言模型进行Python图表可视化

Python使用matplotlib进行可视化一直有2个问题,一是代码繁琐,二是默认模板比较丑。因此发展出seaborn等在matplotlib上二次开发,以更少的代码进行画图的和美化的库,但是这也带来了定制化不足的问题。在大模型时代,这个…

【JavaEE】MyBatis - Plus

目录 一、快速使用二、CRUD简单使用三、常见注解3.1 TableName3.2 TableFiled3.3 TableId 四、条件构造器4.1 QueryWrapper4.2 UpdateWrapper4.3 LambdaQueryWrapper4.4 LambdaUpdateWrapper 五、自定义SQL 一、快速使用 MyBatis Plus官方文档:MyBatis Plus官方文档…

采用前端技术开源了一个数据结构算法的可视化工具

今天要推荐的开源项目叫VisuAlgoX,是一个面向计算机科学和游戏开发的 交互式算法可视化工具,帮助用户通过直观的动画理解各种数据结构和算法。 项目的前身 由于最近在做一些关于游戏和图形化方面的文章,因此做了一部分相关算法的动态可视化来做配图展示…

体验智谱清言的AutoGLM进行自动化的操作(Chrome插件)

最近体验了很多的大模型,大模型我是一直关注着ChatGLM,因为它确实在7b和8b这档模型里,非常聪明! 最近还体验了很多大模型的应用软件,比如Agently、5ire、 mcphost、 Dive、 NextChat等。但是这些一般都是图形界面或者…

pytorch中dataloader自定义数据集

前言 在深度学习中我们需要使用自己的数据集做训练,因此需要将自定义的数据和标签加载到pytorch里面的dataloader里,也就是自实现一个dataloader。 数据集处理 以花卉识别项目为例,我们分别做出图片的训练集和测试集,训练集的标…

Blender模型导入虚幻引擎设置

单位系统不一致 Blender默认单位是米(Meters),而虚幻引擎默认使用**厘米(Centimeters)**作为单位。 当模型从Blender导出为FBX或其他格式时,如果没有调整单位,虚幻引擎会将1米(Blen…

Docker基础详解

Docker 技术详解 一、概述 Docker官网:https://docs.docker.com/ 菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html 1.1 什么是Docker? Docker 是一个开源的容器化平台,它允许开发者将应用程序和其依赖项打包到…

FastPillars:一种易于部署的基于支柱的 3D 探测器

FastPillars:一种易于部署的基于支柱的 3D 探测器Report issue for preceding element Sifan Zhou 1 , Zhi Tian 2 , Xiangxiang Chu 2 , Xinyu Zhang 2 , Bo Zhang 2 , Xiaobo Lu11{}^{1}start_FLOATSUPERSCRIPT 1 end_FLOATSUPERSCRIPT11footnotemark: 1 Chengji…

NLP语言模型训练里的特殊向量

1. CLS 向量和 DEC 向量的区别及训练方式 (1) CLS 向量与 DEC 向量是否都是特殊 token? CLS 向量([CLS] token)和 DEC 向量(Decoder Input token)都是特殊的 token,但它们出现在不同类型的 NLP 模型中&am…

字节跳动 UI-TARS 汇总整理报告

1. 摘要 UI-TARS 是字节跳动开发的一种原生图形用户界面(GUI)代理模型 。它将感知、行动、推理和记忆整合到一个统一的视觉语言模型(VLM)中 。UI-TARS 旨在跨桌面、移动和 Web 平台实现与 GUI 的无缝交互 。实验结果表明&#xf…

基于Python深度学习的鲨鱼识别分类系统

摘要:鲨鱼是海洋环境健康的指标,但受到过度捕捞和数据缺乏的挑战。传统的观察方法成本高昂且难以收集数据,特别是对于具有较大活动范围的物种。论文讨论了如何利用基于媒体的远程监测方法,结合机器学习和自动化技术,来…

【漫话机器学习系列】168.最大最小值缩放(Min-Max Scaling)

在机器学习和数据预处理中,特征缩放(Feature Scaling) 是一个至关重要的步骤,它可以使模型更稳定,提高训练速度,并优化收敛效果。最大最小值缩放(Min-Max Scaling) 是其中最常见的方…

开源测试用例管理平台

不可错过的10个开源测试用例管理平台: PingCode、TestLink、Kiwi TCMS、Squash TM、FitNesse、Tuleap、Robot Framework、SpecFlow、TestMaster、Nitrate。 开源测试用例管理工具提供了一种透明、灵活的解决方案,使团队能够在不受限的情况下适应具体的测…

鸿蒙阔折叠Pura X外屏开发适配

首先看下鸿蒙中断点分类 内外屏开合规则 Pura X开合连续规则: 外屏切换到内屏,界面可以直接接续。内屏(锁屏或非锁屏状态)切换到外屏,默认都显示为锁屏的亮屏状态。用户解锁后:对于应用已适配外屏的情况下,应用界面可以接续到外屏。折叠外屏显示展开内屏显示折叠状态…

DRM_CLIENT_CAP_UNIVERSAL_PLANES和DRM_CLIENT_CAP_ATOMIC

drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1); 这两行代码用于启用 Linux DRM(Direct Rendering Manager)客户端的两个关键特性,具体作用如下: 1. drmSetClientCap…

敏捷开发10:精益软件开发和看板kanban开发方法的区别是什么

简介 精益生产起源于丰田生产系统,核心是消除浪费,而看板最初是由丰田用于物料管理的信号卡片,后来被引入软件开发。 Kanban 后来引入到敏捷开发中,强调持续交付和流程可视化。 精益软件开发原则是基于精益生产的原则&#xff0…