Elasticsearch-增删改查数据工作原理

这篇具有很好参考价值的文章主要介绍了Elasticsearch-增删改查数据工作原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

集群

集群的基本概念:

  • 集群:ES 集群由一个或多个 Elasticsearch 节点组成,每个节点配置相同的 cluster.name 即可加入集群,默认值为 “elasticsearch”。
  • 节点:一个 Elasticsearch 服务启动实例就是一个节点(Node)。节点分为主节点(Master),投票节点(Voting),协调节点(Coordinating),候选节点(Master-eligible)和数据节点(Data)。
  • 分片:ES 支持 PB 级全文搜索,当索引上的数据量太大的时候,ES 通过水平拆分的方式将一个索引上的数据拆分出来分配到不同的数据块上,拆分出来的数据库块称之为一个分片。
  • 副本:副本就是对分片的 Copy,每个主分片都有一个或多个副本分片,当主分片异常时,副本可以提供数据的查询等操作。

如下图可以看出为了达到高可用,Master 节点会避免将主分片和副本分片放在同一个节点上。

Elasticsearch-增删改查数据工作原理,Elasticsearch,elasticsearch,大数据,搜索引擎

路由

1.  写请求首先会被打到协调节点,协调节点根据路由算法决定数据写入的主分片位置,并在主节点上执行写入操作。

路由算法:

shardId = hash(_routing) % num_primary_shards

通过该公式可以保证使用相同routing的文档被分配到同一个shard上。_routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值,可以用在INDEX, UPDATE,GET, SEARCH, DELETE等各种操作中手动设置。

routing_partition_size参数

ES还提供了一个 index.routing_partition_size参数(仅当使用routing参数时可用),用于将routing相同的文档映射到集群分片的一个子集上,这样一方面可以减少查询的分片数,另一方面又可以在一定程度上防止数据倾斜。引入该参数后计算公式如下

shardId = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards

2.  主分片执行写入操作,如下图S0主分片写入之后,同步到副本分片

Elasticsearch-增删改查数据工作原理,Elasticsearch,elasticsearch,大数据,搜索引擎

索引写入

主分片写入

当接收到请求时,执行如下步骤:

    ①判断操作类型:如果是 Bulk Request 会遍历请求中的子操作,根据不同的操作类型跳转到不同的处理逻辑。

    ②操作转换:将 Update 操作转换为 Index 和 Delete 操作。

    ③解析文档(Parse Doc):解析文档的各字段。

    ④更新 Mapping:如果请求中有新增字段,会根据 dynamic mapping 或 dynamic template 生成对应的 mapping,如果 mapping 中有 dynamic mapping 相关设置则按设置处理。

    ⑤获取 sequence Id 和 Version:从 SequenceNumberService 获取一个 SequenceID 和 Version。SequenceID 用于初始化 LocalCheckPoint,version 是根据当前 versoin+1 用于防止并发写导致数据不一致(乐观锁)。

    ⑥写入 Lucene:对索引文档 uid 加锁,然后判断 uid 对应的 version v2 和之前 update 转换时的 version v1 是否一致,不一致则返回第二步重新执行。在 version 一致的情况下根据id的情况执行添加或者更新操作。如果同 id 的 doc 已经存在,则调用 updateDocument 接口。

    ⑦写入 translog:写入 Lucene 的 Segment 后,会以 key value 的形式写 Translog, Key 是 Id,Value 是索引文档的内容。当查询的时候,如果请求的是 GetDocById 则可以直接根据 _id 从 translog 中获取。写入 translog 的操作会在下面的章节中详细讲解。

    ⑧重构 bulk request:已经多个操作中的 update 操作转换为 index、delete 操作,最终都以 index 或 delete 操作的方式组成 bulk request 请求。

    ⑨落盘 Translog:默认情况下,translog 要在此处落盘完成,如果对可靠性要求不高,可以设置 translog 异步落盘,同时存在数据有丢失的风险。

    ⑩发送请求给副本分片:将构造好的 bulk request 发送给各个副本分片,并且等待副本分片返回,然后再响应协调节点。如果某个分片执行失败,主分片会给主节点发请求移除该分片。

    ⑪等待 replica 响应:当所有的副本分片返回请求时,更新主分片的 LocalCheckPoint。如果设置了index.write.wait_for_active_shards=1,那么写完主节点,直接返回客户端,异步同步到从分片。如果 index.write.wait_for_active_shards=all,那么必须要把所有的副本写入完成才返回客户端。wait_for_active_shards最大值只能是 number_of_replicas +1 ,详情见官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.5/docs-index_.html#index-wait-for-active-shards

Elasticsearch 文件合并与刷新

    在了解了文件写入流程以后,再来近距离观察一下写入的细节,看看索引是如何通过内存最终写入磁盘的。

Elasticsearch-增删改查数据工作原理,Elasticsearch,elasticsearch,大数据,搜索引擎

 如图 2 所示,将每一步写入操作进行拆解如下:

    ①写入请求会将索引(Index)存放到内存区域,叫做 Index Buffer。这边的内存是ES JVM内存。此时的索引文件暂时是不能被ES搜索到的。

    ②当达到默认的时间:1 秒钟(参数refresh_interval=1s)或者内存的数据达到一定量(默认值是 JVM 所占内存容量的 10%)时,会触发一次刷新(Refresh),将内存中的数据生成到一个新的段上并缓存到文件系统缓存(FileSystem Cache)上,并将Index Buffer 的数据会被清空。这时虽然新段未被提交到磁盘,但是此时的数据就可以被 ES 搜索到了且不能被修改。

    ③ES 每次 refresh 都会生成一个 Segment 文件,这样下来 Segment 文件会越来越多。由于每个 Segment 都会占用文件句柄、内存、CPU 资源,假设每次搜索请求都会访问对应 Segment 获取数据,这就意味着 Segment 越多会加大搜索请求的负担,导致请求变慢。为了提高搜索性能 ES 会定期对 Segment 进行合并(Merge)操作,也就是将多个小 Segment 合并成一个 Segment。那么搜索请求就直接访问合并之后的 Segment,从而提高搜索性能。 

    ④上面 3 个步骤都是在内存中完成的,此时数据还没有写到磁盘中。 随着新文档索引不断被写入,当translog日志数据大小超过 512M (由 index.translog.flush_threshold_size 控制)或者时间超过 30 分钟时,会触发一次 Flush。此时 ES 会创建一个 Commit Point 文件,该文件用来标识被 Flush 到磁盘上的 Segment。

Elasticsearch 数据存储可靠性

延续上一节的例子,在原有的基础上加入 Translog 的部分。如图 3 所示,在整个 ES 写入流程中加入 Translog,目的是为了提高 ES 的数据存储可靠性。

Elasticsearch-增删改查数据工作原理,Elasticsearch,elasticsearch,大数据,搜索引擎

    索引文档最开始是存放在内存的 Index Buffer 中,当执行了 Refresh 操作会将其保存为 Segment,此时就可以供用户查询了。但是 Segment 在 Flush 之前仍然存在于内存中,如果此时服务器宕机,而 ES 还没有 Flush 操作保存在内存中的 Segment 数据将会丢失。为了提高 ES 的数据存储可靠性,引入了 Translog。在每次用户请求 Index Buffer 进行操作的时候都会写一份操作记录到 Translog 中,Translog 使用特有的机制保存到磁盘中。上一节提到的 Flush 操作,当 Flush 操作将 Segment 进行落盘同时还会将 Translog 的文件进行落盘,之后会将内存中原有的Translog 移除,在内存中会重新创建一个新的 Translog。

translog相关配置:

##translog的刷盘策略durability为request表示同步(默认),async表示异步index.translog.durability: async
##translog刷盘间隔时间。默认为5s,不可低于100msindex.translog.sync_interval: 120s
##超过这个大小会导致flush操作,产生新的Lucene分段。默认值为512MBindex.translog.flush_threshold_size: 1024mb

通过这种方式当断电或需要重启时,ES 不仅要根据提交点去加载已经持久化过的段,还需要工具 Translog 里的记录,把未持久化的数据重新持久化到磁盘上,避免了数据丢失的可能。

图中 Translog 存在于内存和磁盘中,分别有两个线将其相连,表示了 Translog 同步的两种方式:

  • 在 ES 处理用户请求时追加 Translog,追加的内容就是对ES的请求操作。此时会根据配置同步或者异步的方式将操作记录追加信息保存到磁盘中。

  • 另一种 Translog 从内存到磁盘的操作是在 Flush 发生的时候,上节中介绍过,Flush 操作会把 Segment 保存到磁盘同时还会将 Translog 的文件进行落盘。落盘以后存在与内存中的 Translog 就会被移除。

索引检索

在执行文档的CRUD操作时,通过文档ID就能计算出文档存储在哪个分片中,所以只要将客户端请求转发给对应的分片(或其副本)所在的节点进行处理即可。

而执行文档搜索操作时只会提供搜索条件,并不包含文档ID,无法直接知道哪些分片包含搜索结果,需要先搜索所有的分片(或其副本),还要对每个分片上的结果进行汇总以得到最终结果。所以,文档的搜索过程会分为如下两步执行:

  1. 搜索所有的分片(或其副本),确定哪些文档属于搜索结果;

  2. 从相关分片上读取文档数据,再汇总组装成最终的结果;

将第一步称为query,第二步称为fetch,整个搜索过程称为query-then-fetch

以分页查询为例,from + size 分页方式是 ES 最基本的分页方式,类似于关系型数据库中的 limit 方式。from 参数表示:分页起始位置;size 参数表示:每页获取数据条数。例如:

{
  "query": {
    "match_all": {}
  },
  "from": 10,
  "size": 20
}

Query阶段

Elasticsearch-增删改查数据工作原理,Elasticsearch,elasticsearch,大数据,搜索引擎

如上图所示,Query 阶段大致分为 3 步:

  • 第一步:Client 发送查询请求到 Server 端,Node1 接收到请求然后创建一个大小为 from + size的优先级队列用来存放结果,此时 Node1 被称为 coordinating node(协调节点);

  • 第二步:Node1 将请求广播到涉及的 shard (主分片或副本分片,根据随机或轮询算法)上,每个 shard 内部执行搜索请求,然后将执行结果存到自己内部的大小同样为 from+size 的优先级队列里;

  • 第三步:每个 shard 将暂存的自身优先级队列里的结果返给 Node1,Node1 拿到所有 shard 返回的结果后,对结果进行一次合并,产生一个全局的优先级队列,存在 Node1 的优先级队列中。(如上图中,Node1 会拿到 (from + size) * 6 条数据,这些数据只包含 doc 的唯一标识_id 和用于排序的_score,然后 Node1 会对这些数据合并排序,选择前 from + size 条数据存到优先级队列);

Fetch阶段

Elasticsearch-增删改查数据工作原理,Elasticsearch,elasticsearch,大数据,搜索引擎

如上图所示,当 Query 阶段结束后立马进入 Fetch 阶段,Fetch 阶段也分为 3 步:

  • 第一步:Node1 根据刚才合并后保存在优先级队列中的 from+size 条数据的 id 集合,发送请求到对应的 shard 上查询 doc 数据详情;

  • 第二步:各 shard 接收到查询请求后,查询到对应的数据详情并返回为 Node1;(Node1 中的优先级队列中保存了 from + size 条数据的_id,但是在 Fetch 阶段并不需要取回所有数据,只需要取回从 from 到 from + size 之间的 size 条数据详情即可,这 size 条数据可能在同一个 shard 也可能在不同的 shard,因此 Node1 使用 multi-get 来提高性能)

  • 第三步:Node1 获取到对应的分页数据后,返回给 Client;

索引修改和删除

    索引文件分段存储并且不可修改,那么新增、更新和删除如何处理呢?

  • 删除操作 :commit 的时候会生成一个 .del 文件,里面将某个 doc 标识为 deleted状态,那么搜索的时候根据 .del 文件就知道这个 doc 是否被删除了,最终结果被返回前从结果集中移除。

  • 更新操作 :就是将原来的 doc 标识为 deleted 状态,然后新写入一条数据。

merge 操作时会将多个 segment file 合并成一个,同时将标识为 deleted 的 doc「物理删除」 ,将新的 segment file 写入磁盘,最后打上 commit point 标识所有新的 segment file文章来源地址https://www.toymoban.com/news/detail-614075.html

到了这里,关于Elasticsearch-增删改查数据工作原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch 分布式全文搜索引擎原理解析

    作者:禅与计算机程序设计艺术 Elasticsearch是一个开源的分布式全文搜索引擎,它可以近实时地存储、检索数据。本系列文章将从以下几个方面对Elasticsearch进行深入分析: Elasticsearch的主要组成部分 索引、类型和映射(Mapping) 搜索请求处理流程 查询缓存机制 Elasticsearch集群

    2024年02月05日
    浏览(49)
  • ElasticSearch底层读写工作原理

    目录 ES底层读写工作原理分析 ES写入数据的过程 ES读取数据的过程 根据id查询数据的过程 根据查询数据的过程 写数据底层原理          写请求是写入 primary shard,然后同步给所有的 replica shard;读请求可以从 primary shard 或 replica shard 读取,采用的是随机轮询算法。

    2024年02月21日
    浏览(44)
  • ElasticSearch搜索引擎:数据的写入流程

    (1)ES 客户端选择一个节点 node 发送请求过去,这个节点就是协调节点 coordinating node  (2)协调节点对 document 进行路由,通过 hash 算法计算出数据应该落在哪个分片 shard 上,然后根据节点上维护的 shard 信息,将请求转发到对应的实际处理节点node上 shard = hash(document_id) %

    2023年04月14日
    浏览(68)
  • 基于Elasticsearch与Hbase组合框架的大数据搜索引擎

    本项目为学校大数据工程实训项目,共开发4周,答辩成绩不错。代码仓库放文章尾,写的不好,代码仅供参考。 对于结构化数据 ,因为它们具有特定的结构,所以我们一般都是可以通过关系型数据库(MySQL,Oracle 等)的二维表(Table)的方式存储和搜索,也可以建立索引。

    2024年02月09日
    浏览(65)
  • Elasticsearch (ES) 搜索引擎: 数据类型、动态映射、多类型(子字段)

    原文链接:https://xiets.blog.csdn.net/article/details/132348634 版权声明:原创文章禁止转载 专栏目录:Elasticsearch 专栏(总目录) ES 映射字段的 数据类型 ,官网文档参考:Field data types。 下面是 ES 常用的一些基本数据类型。 字符串 类型: keyword :类型。 text :文本类型。

    2024年03月23日
    浏览(67)
  • elasticsearch(ES)分布式搜索引擎04——(数据聚合,自动补全,数据同步,ES集群)

    **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近

    2024年02月08日
    浏览(51)
  • 微服务04 分布式搜索引擎 elasticsearch DSL数据聚合 自动补全 数据同步 集群 Sentinel

    聚合(aggregations)可以让我们极其 方便的实现对数据的统计、分析、运算 。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些 统计功能的比数据库的sql要方便的多,而且查询速度非常快 ,可以实现近

    2024年02月11日
    浏览(51)
  • 《Spring Boot 实战派》--13.集成NoSQL数据库,实现Elasticsearch和Solr搜索引擎

             关于搜索引擎 我们很难实现 Elasticseach 和 Solr两大搜索框架的效果;所以本章针对两大搜索框架,非常详细地讲解 它们的原理和具体使用方法, 首先 介绍什么是搜索引擎 、如何用 MySQL实现简单的搜索引擎,以及Elasticseach 的 概念和接口类; 然后介绍Elasticseach

    2023年04月09日
    浏览(91)
  • 微服务04 分布式搜索引擎 elasticsearch DSL数据聚合 自动补全 数据同步 集群 微服务保护 Sentinel

    聚合(aggregations)可以让我们极其 方便的实现对数据的统计、分析、运算 。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些 统计功能的比数据库的sql要方便的多,而且查询速度非常快 ,可以实现近

    2024年02月15日
    浏览(56)
  • 使用Logstash同步mysql数据到Elasticsearch(亲自踩坑)_将mysql中的数据导入es搜索引擎利用logstash(1)

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新大数据全套学习资料》,

    2024年04月28日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包