Elasticsearch如何动态维护一个不可变的倒排索引

2024-05-15 02:58

本文主要是介绍Elasticsearch如何动态维护一个不可变的倒排索引,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇文章中介绍了Elasticsearch中是如何搜索文本的,同时也简述了在es里面索引数据结构的特点不可变性。


索引不可变性的缺点限制了单个索引存储的最大数据量以及更新的频次,所以es面临的问题是如何解决倒排索引不可更新的特点而同时仍然保持不可变特性带来的好处。


答案就是使用多个索引

代替原来的每次重写整个索引,es里面采用方式是增加新的索引来反映最近的变化,然后查询的时候一次查询所有的倒排索引,从最早的一直到最新的,然后在合并结果返回。

在lucene里面一个索引是多个segment加上一个commit point文件组成,每个segment都是一个倒排索引,而commit point这个文件标记了所有的已知的segment文件。如下图所示:


[img]http://dl2.iteye.com/upload/attachment/0129/1489/486c12c3-c8f0-3781-bc92-6b3a7caa77cb.png[/img]


注意lucene里面的index在es里面叫做shard,es里面的一个index可以包含多个shard,对es里面的一个索引查询在es底层会把查询请求发送到所有shard里面最后在把结果集合并并返回。


回到文章开头的问题,es如何利用多索引来解决更新的问题,下面我们看下数据被写入es的过程:


(1)当es收到一个写入或者更新的请求时,首先会把这个数据收集在内存的indexing buffer

(2)经过一定的间隔或者外部命令触发时,会在内存缓冲区生成新的segment。

(3)然后segment首先会被写到filesystem cache中,这个时候其实搜索就能搜到了。

(4)然后经过一段时间filesystem cache中的segment会被fsync到磁盘文件上并在commit point文件中记录新segment文件名称,同时新的segment会被打开确保搜索可见

(5)最终内存里面buffer区会被清空,并等待收集新的documnet。


如下图:

[img]http://dl2.iteye.com/upload/attachment/0129/1491/8201a127-9d97-3ae1-9aa7-cf6f84a39bf5.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0129/1493/85ad0abb-4c41-3ab3-b866-b46e5c2a8cd5.png[/img]



当收到查询请求时,所有的sengment包含内存和磁盘中的会被依次查询,最终聚合所有segment并准确计算每个document的相关性,上面的实现方式可以相对代价比较小的方法处理新增的document。


上面介绍的是新增数据的处理,接下来我们看下如果有删除和更新请求那么es是如何处理的。


首先我们知道sengments本身是不可变的,所以document是不能从旧的segments中移除,同时也不能被更新,那么es是如何处理删除和更新请求的呢?


在每次commit point时,es会生成一个后缀为.del的文件,这个文件标记了所有已经被删除的数据,在一条数据被删除时,es仅仅会在.del文件里面做个删除标记,被标记删除的数据仍然会被查询到,但是在最终返回结果之前,被标记删除的数据会被移除,这就是es里面删除的实现逻辑。


同理更新的逻辑也类似,当一个document被更新时,旧版本的document也会在.del文件里面被打上删除标记,新版本的document会被索引到一个新的segment里面,这个时候的查询会同时把两者都查询出来,但在最终返回结果之前被标记删除的旧版本数据会被移除掉。


以上就是es里面实现动态更新索引的内容,在这里我们能看到es里面更新和删除都类似于采用伪删除的策略来实现,到这里大家可能有个疑问,那些被标记删除的数据,什么时候才会被文件系统真正的清除,毕竟量大了还是对性能有一点影响的,这个在后面segment merge的文章中介绍。

[b][color=green][size=large] 有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。 [/size][/color][/b] [img]http://dl2.iteye.com/upload/attachment/0104/9948/3214000f-5633-3c17-a3d7-83ebda9aebff.jpg[/img]

这篇关于Elasticsearch如何动态维护一个不可变的倒排索引的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990617

相关文章

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下

Pandas中多重索引技巧的实现

《Pandas中多重索引技巧的实现》Pandas中的多重索引功能强大,适用于处理多维数据,本文就来介绍一下多重索引技巧,具有一定的参考价值,感兴趣的可以了解一下... 目录1.多重索引概述2.多重索引的基本操作2.1 选择和切片多重索引2.2 交换层级与重设索引3.多重索引的高级操作3.1 多重索引的分组聚

vue基于ElementUI动态设置表格高度的3种方法

《vue基于ElementUI动态设置表格高度的3种方法》ElementUI+vue动态设置表格高度的几种方法,抛砖引玉,还有其它方法动态设置表格高度,大家可以开动脑筋... 方法一、css + js的形式这个方法需要在表格外层设置一个div,原理是将表格的高度设置成外层div的高度,所以外层的div需要

SpringBoot实现动态插拔的AOP的完整案例

《SpringBoot实现动态插拔的AOP的完整案例》在现代软件开发中,面向切面编程(AOP)是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的AOP实现中,切... 目录引言一、AOP 概述1.1 什么是 AOP1.2 AOP 的典型应用场景1.3 为什么需要动态插

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情