深耕ElasticSearch - 动态更新索引

article/2025/10/9 15:09:22

文章目录

    • 1. 建立索引
    • 2. 倒排索引的不变性
    • 3. 动态更新索引
      • 3.1 动态更新索引原理
      • 3.2 新增文档
      • 3.3 删除和更新文档

1. 建立索引

给定一个文档集合(这个集合中的文档是不变的),索引是如何建立起来的呢?

首先在内存里维护一个倒排索引,当内存占满后,将内存数据写入磁盘临时文件,第二阶段对临时文件进行合并形成最终索引。
在这里插入图片描述
① 从磁盘读取文档,对文档内容进行解析,并在内存中建立一个倒排索引,相当于对目前处理的文档子集单独在内存中建立起了一整套倒排索引,和最终索引相比,其结构和形式是相同的,区别只是这个索引只是部分文档的索引而非全部文档的索引。

② 当内存占满后,为了腾出内存空间,将整个内存中建立的倒排索引写入磁盘临时文件中,然后彻底清除所占内存,这样就空出内存来进行后续文档的处理。

③ 每一轮处理都会在磁盘产生一个对应的临时文件,当所有文档处理完成后,在磁盘中会有多个临时文件,为了产生最终的索引,需要将这些临时文件合并形成最终索引。

2. 倒排索引的不变性

早期的全文检索会为整个文档集合建立一个很大的倒排索引并将其写入到磁盘。 一旦新的索引就绪,旧的就会被其替换,这样最近的变化便可以被检索到。

倒排索引被写入磁盘后是不可改变的:它永远不会修改。 不变性有重要的价值:

  1. 不需要锁。如果你从来不更新索引,你就不需要担心多进程同时修改数据的问题。
  2. 一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求内存,而不会命中磁盘。这提供了很大的性能提升。
  3. 其它缓存(像filter缓存),在索引的生命周期内始终有效。它们不需要在每次数据改变时被重建,因为数据不会变化。
  4. 写入单个大的倒排索引允许数据被压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的使用量。

当然,一个不变的索引也有不好的地方。主要事实是它是不可变的! 你不能修改它。如果你需要让一个新的文档可被搜索,你需要重建整个索引。这要么对一个索引所能包含的数据量造成了很大的限制,要么对索引可被更新的频率造成了很大的限制。

3. 动态更新索引

3.1 动态更新索引原理

倒排索引一旦被写入磁盘就是不可更改的,如果搜索引擎需要处理的文档集合是静态集合,那么在索引建立好之后,就可以一直用建好的索引响应用户查询请求。但是,在真实环境中,搜索引擎需要处理的文档集合往往是动态集合,即在建好初始的索引后,后续不断有新文档进入系统,同时原先的文档集合内有些文档可能被删除或者内容被更改。问题是怎样在保留不变性的前提下实现倒排索引的更新呢?答案是: 用更多的索引,即增加临时索引。

在动态更新索引中,有3个关键的索引结构:倒排索引、临时索引和已删除文档列表。

① 倒排索引就是对初始文档集合建立好的索引结构,该索引存在磁盘中,不可改变。

② 临时索引是在内存中实时建立的倒排索引,该索引存储在内存中,当新增文档进入系统,解析文档,之后更新内存中维护的临时索引,文档中出现的每个单词,在其倒排列表末尾追加倒排列表项,随着新加入系统的文档越来越多,临时索引消耗的内存也会随之增加,一旦临时索引将指定的内存消耗光,要考虑将临时索引的内容更新到磁盘索引中,以释放内存空间来容纳后续的新进文档。

③ 已删除文档列表则用来存储已被删除的文档的相应文档ID,形成一个文档ID列表。这里需要注意的是:当一篇文档内容被更改,可以认为是旧文档先被删除,之后向系统内增加一篇新的文档,通过这种间接方式实现对内容更改的支持。
在这里插入图片描述
当系统发现有新文档进入时,立即将其加入临时索引中。有文档被删除时,则将其加入删除文档队列。文档被更改时,则将原先文档放入删除队列,解析更改后的文档内容,并将其加入临时索引中。通过这种方式可以满足实时性的要求。

如果用户输入查询请求,则搜索引擎同时从倒排索引和临时索引中读取用户查询单词的倒排列表,找到包含用户查询的文档集合,并对两个结果进行合并,之后利用删除文档列表进行过滤,将搜索结果中那些已经被删除的文档从结果中过滤,形成最终的搜索结果,并返回给用户。这样就能够实现动态环境下的准实时搜索功能。

注意:在内存中的临时索引是不断变化的,但是这个临时索引一旦写进磁盘,就是不可变的。

3.2 新增文档

通过增加临时索引来反映新近的修改,而不是直接重写整个倒排索引,来保证在保留倒排索引不变性的前提下实现倒排索引的更新,下面我们一起看看整个实现过程。
在这里插入图片描述
Elasticsearch 基于 Lucene, 这个java库引入了按搜索的概念。 每一本身都是一个倒排索引, 但索引在 Lucene 中除表示所有的集合外, 还增加了提交点的概念,提交点是一个列出了所有已知段的文件。

我想你可能有个疑问,到底什么是段?为什么引入段这个概念?

在早期全文检索中为整个文档集合建立了一个很大的倒排索引,并将其写入磁盘中,如果需要让一个新的文档可被搜索,你需要重建整个索引。这种方式在数据量很大时效率很低,并且由于创建一次索引的成本很高,所以对数据的更新不能过于频繁,也就不能保证时效性,因此提出了段的概念,即将一个索引文件拆分为多个文件,每个子文件叫做段,每个段都是一个被写入磁盘的倒排索引,因此段具有不变性。

这样听起来还是有点抽象,我们来看图理解吧。

① 当新增一个文档时,这个文档会被添加到内存索引缓存中,随后解析文档,更新内存中维护的临时索引,文档中出现的每个单词,在其倒排列表末尾追加倒排列表项。
在这里插入图片描述
② 随着内存索引缓存中的的文档越来越多,临时索引消耗的内存也会随之增加,一旦临时索引将指定的内存消耗光,要考虑将临时索引的内容更新到磁盘索引中,以释放内存空间来容纳后续的新进文档。

我们知道:一个ES索引包含多个分片,一个分片对应的就是一个Lucene索引,一个Lucene索引又由多个段组成,每个段都是一个被写入磁盘的倒排索引,Luncene中还有个文件,用来记录所有段的信息,叫做提交点。

在这里插入图片描述

当缓存被提交时:

  1. 一个新的段被写入磁盘。(这个段就是缓存中维护的临时倒排索引)

  2. 一个新的包含新段名字的提交点被写入磁盘。

  3. 磁盘进行同步。(所有在文件系统缓存中等待的写入都刷新到磁盘,以确保它们被写入物理文件)

  4. 新的段被开启,让它包含的文档可见以被搜索。

  5. 内存缓存被清空,等待接收新的文档。

每一个倒排索引都会被轮流查询到(从最早的开始)查询完后再对结果进行合并。当一个查询被触发,所有已知的段按顺序被查询。词项统计会对所有段的结果进行聚合,以保证每个词和每个文档的关联都被准确计算。 这种方式可以用相对较低的成本将新文档添加到索引。

3.3 删除和更新文档

段是不可改变的,所以既不能从把文档从旧的段中移除,也不能修改旧的段来进行反映文档的更新。 取而代之的是,每个提交点会包含一个 .del 文件,文件中会列出这些被删除文档的段信息。

当一个文档被 “删除” 时,它实际上只是在 .del 文件中被 标记 删除。一个被标记删除的文档仍然可以被查询匹配到, 但它会在最终结果被返回前从结果集中移除。

文档更新也是类似的操作方式:当一个文档被更新时,旧版本文档被标记删除,文档的新版本被索引到一个新的段中。 可能两个版本的文档都会被一个查询匹配到,但被删除的那个旧版本文档在结果集返回前就已经被移除。


http://chatgpt.dhexx.cn/article/8rNErStg.shtml

相关文章

Solr 新增、更新、删除索引

solr-admin新增索引 [索引中无则新增,有则更新] 第一种方式&#xff1a;在doc标签和field标签中增加权重&#xff08;boost&#xff09;&#xff0c;增加权重后&#xff0c;可以在搜索的时候做权重过滤。 1 2 3 4 <delete> <query> id:"100861"<…

全文索引----solr服务器更新增量索引

上篇文章我们介绍了全量更新solr索引&#xff0c;但是在数据量较大时&#xff0c;频繁的更新索引会消耗系统性能&#xff0c;如果更新频率较低&#xff0c;则会影响短时的数据准确性&#xff0c;所以&#xff0c;更新时间的间隔是个很难界定。增量索引解决了这个问题&#xff0…

解决IDEA一直出现更新索引ideal Updating Indices: Indexing paused问题

前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注一下&#xff01; 也许一个人独行&#xff0c;可以走的很快&#xff0c;但是一群人结伴而行&#xff0c;才能走的更远&#xff01;让我们在成长的道路上互相学习&…

es 根据索引名称和索引字段更新值

1&#xff1a;指定索引名称和操作指令 instodayorder_new_2022/_update_by_query 2&#xff1a;执行代码 { "script": { "lang": "painless", "source": "if (ctx._source.reserveString_3 null) {ctx._source.reser…

es 修改(更新)索引模板

es 修改(更新)索引模板 es索引模板的好处就不用我多说了&#xff0c;我这里遇到的问题是&#xff0c;如何修改es模板&#xff0c;网上检索的关键词大多是新增/删除模板&#xff0c;我记录一下自己的修改模板操作吧&#xff08;我是在kibana的UI界面进行操作的&#xff09; 1.…

SQL 索引的操作 数据查询(1)数据更新

文章目录 索引的建立与删除建立索引修改索引删除索引 数据更新插入数据插入元组插入子查询结果 修改数据删除数据 数据查询单表查询查询经过计算的值选择表中的若干元组 索引的建立与删除 建立索引 在SQL语言中&#xff0c;建立索引使用 CREATE INDEX 语句&#xff0c;其一般…

Elasticsearch7.8.0版本进阶——动态更新索引

目录 一、如何在保留不变性的前提下实现倒排索引的更新二、按段搜索执行流程三、按段搜索的文档查询四、按段搜索的文档删除五、按段搜索的文档更新 一、如何在保留不变性的前提下实现倒排索引的更新 用更多的索引。通过增加新的补充索引来反映最近的修改&#xff0c;而不是直…

ElasticSearch 动态更新索引

Elasticsearch版本:2.x 1. 不变性 倒排索引被写入磁盘后是 不可改变(immutable):永远不会被修改。不变性有如下几个重要的优势: 不需要锁。如果你没有必要更新索引,你就没有必要担心多进程会同时修改数据。一旦索引被读入内核的文件系统缓存中,由于其不会改变,便会留在那…

MySQL:插入,更新与删除、索引

一、学习目标 掌握如何向表中插入数据掌握更新数据的方法熟悉如何删除数据掌握对数据表基本操作的方法和技巧了解什么是索引掌握创建索引的方法和技巧熟悉如何删除索引熟悉掌握索引的常见问题 二、实验内容 创建表books&#xff0c;对数据表进行插入、更新和删除操作&#x…

搜索引擎索引之如何更新索引

本文节选自《这就是搜索引擎&#xff1a;核心技术详解》第三章 动态索引通过在内存中维护临时索引&#xff0c;可以实现对动态文档和实时搜索的支持。但是服务器内存总是有限的&#xff0c;随着新加入系统的文档越来越多&#xff0c;临时索引消耗的内存也会随之增加。当最初分…

IDEA总是自动更新索引怎么解决

从File进入settings 搜索index_>修改右边的两个即可,点击OK保存即可

项目中如何使用ElasticSearch?变更数据时难道既更新数据库也要更新索引?这篇文章也许对你有点帮助(持续更新)

目录 1. 概述2.ElasticSearch的调试2.1 启动ES2.2 创建搜索的微服务2.3 使用logstash同步数据库数据到es的索引中 3.Linux系统下部署3.1 拉取es容器3.2 让9300端口可用3.3 安装ik分词器3.4 安装head-master3.5 配置logstash&#xff08;耗时最久&#xff09; 四. 出现的bug4.1 …

【Mysql】 sql语句实现update_or_create(唯一索引 ON DUPLICATE KEY UPDATE)

【Mysql】 on duplicate key update用法、优缺点以及使用案例 1. 应用场景&#xff1a; 导入数据功能&#xff0c;需要实现数据不存在时进行新建&#xff0c;有数据修改时则进行更新。在实现时&#xff0c;思路通常为先判断数据是新增还是更新&#xff0c;除了我们在代码层面实…

mysql-索引

1.索引的定义&#xff1a; 索引是帮助MySql高效获取数据的数据结构。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用数据&#xff0c;这样就可以在这些数据结构上实现高级查找算法&#xff0c;这种数据结构就是索…

mysql中的各种索引大总结

文章目录 为啥不用二叉搜索树&#xff1f;为啥不用平衡二叉&#xff08;avl&#xff09;树&#xff1f;为啥不用b-树&#xff1f;为啥用b树&#xff1f;&#xff08;重点&#xff09;索引聚簇索引聚簇索引的局限聚集的数据的优点非聚簇索引介绍组合索引覆盖索引前缀索引前缀索引…

MySQL索引的更新策略

对于数据的每一次更新&#xff0c;MySQL并不会每次都会更新索引(针对非唯一性索引而言)&#xff0c;索引的更新策略是这样的&#xff1a; 在InnoDB中&#xff0c;增删改都会立刻修改主键or唯一索引&#xff0c;但是不会rebuild全局索引&#xff0c;而是对这些索引增加值(或移除…

苹果各机型尺寸大小

//6.5英寸 #define iPhoneXSMax ([UIScreen instancesRespondToSelector:selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) : NO) //6.1英寸 #define iPhoneXR ([UIScreen instancesRespondToSelector:selec…

iOS 手机尺寸

iPhone设备 物理分辨率是硬件所支持的&#xff0c;逻辑分辨率是软件可以达到的。 代数设备操作系统逻辑分辨率(point)物理分辨率(pixel)屏幕尺寸(对角线长度)缩放因子 iPhone 第一代iPhone 2GiOS 1320 x 480480 x 3203.5寸1x第二代iPhone 3iOS 2320 x 480480 x 3203.5寸1…

jQuery weui 时间选择器datetimepicker年月日最简单解决方案

使用jqweui的时候发现&#xff0c;datetimePicker&#xff08;时间日期选择器&#xff09;竟然不提供只有年月日这种模式&#xff0c;真是牛逼&#xff08;垃圾&#xff09;&#xff0c;跟着我&#xff0c;只需要很简单的修改就好了&#xff0c;上图 下面是js $("#datati…

jquery weui 显示loading

jQuery weui 显示loading按钮官方文档并没有给出demo&#xff0c;经过调试&#xff0c;把代码给拷贝了出来。 实现显示loading的代码如下&#xff1a; <div id"loadDiv" style"display: none;" class"weui-toast weui_loading_toast weui-toast--…