ElasticSearch系列-索引原理与数据读写流程详解

2023-11-17

       


索引原理

倒排索引

倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引。通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key。ES底层在检索时底层使用的就是倒排索引。

索引模型

现有索引和映射如下:

{
  "products" : {
    "mappings" : {
      "properties" : {
        "description" : {
          "type" : "text"
        },
        "price" : {
          "type" : "float"
        },
        "title" : {
          "type" : "keyword"
        }
      }
    }
  }
}

先录入如下数据,有三个字段title、price、description等

_id title price description
1 蓝月亮洗衣液 19.9 蓝月亮洗衣液高效
2 iphone13 19.9 不错的手机
3 小浣熊干脆面 1.5 小浣熊好吃

在ES中除了text类型分词,其他类型不分词,因此根据不同字段创建索引如下:

  • title字段:

    term _id(文档id)
    蓝月亮洗衣液 1
    iphone13 2
    小浣熊干脆面 3
  • price字段

    term _id(文档id)
    19.9 [1,2]
    1.5 3
  • description字段

    term _id term _id term _id
    1 2 3
    1 2 3
    1 2 3
    1 2 3
    1 2 3
    1
    [1:1:9,2:1:6,3:1:6]
    1
    1

注意: Elasticsearch分别为每个字段都建立了一个倒排索引。因此查询时查询字段的term,就能知道文档ID,就能快速找到文档。

数据写入流程

  1. 先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件

  2. 如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh。为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。

  3. 只要数据进入os cache,此时就可以让这个segment file的数据对外提供搜索了

  4. 重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发mit操作。

  5. mit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer

  6. 将一个mit point写入磁盘文件,里面标识着这个mit point对应的所有segment file

  7. 强行将os cache中目前所有的数据都fsync到磁盘文件中

  8. 将现有的translog清空,然后再次重启启用一个translog,此时mit操作完成。默认每隔30分钟会自动执行一次mit,但是如果translog过大,也会触发mit。整个mit的过程,叫做flush操作。我们可以手动执行flush操作,就是将所有os cache数据刷到磁盘文件中去。

    es中的flush操作,就对应着mit的全过程。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个mit point,清空translog日志文件。

  9. translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。

  10. 如果是删除操作,mit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了

  11. 如果是更新操作,就是将原来的doc标识为deleted状态,然后新写入一条数据

  12. buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge

  13. 每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个mit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file。

es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge

当segment file多到一定程度的时候,es就会自动触发merge操作,将多个segment file给merge成一个segment file。

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

数据查询流程

  1. 客户端发送请求到任意一个node,成为coordinate node

  2. coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary  shard以及其所有replica中随机选择一个,让读请求负载均衡

  3. 接收请求的node返回document给coordinate node

  4. coordinate node返回document给客户端

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

今天的分享就到这里,喜欢的朋友可以点赞收藏,感谢!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ElasticSearch系列-索引原理与数据读写流程详解 的相关文章

  • ElasticSearch:Jest、Rest、TransportClient、NodeClient

    我已经浏览了官方文档https www elastic co blog found interface elasticsearch picking client https www elastic co blog found interfa
  • 按嵌套文档之一中的值对文档进行排序

    我在根据所选嵌套文档中的值对文档进行排序时遇到问题 我正在使用这样的设置 curl XPUT http 127 0 0 1 9200 test d index number of shards 1 number of replicas 1
  • Jenkins v2.212:创建扩展解析器类时出错:找不到类

    将 Jenkins 升级到 v2 212 并安装许多可用的插件更新后 某些作业开始失败并出现以下错误 12 43 35 WS CLEANUP Deleting project workspace 12 43 35 WS CLEANUP De
  • Jenkins Amazon ECR:没有基本的身份验证凭据

    我无法使用 Jenkins Pipeline 将 ocker 图像推送到 Amazon ECR 我总是得到no basic auth credentials 这是我的设置 詹金斯 2 46 2 亚马逊 ECR 插件 1 4 https wi
  • Jenkins 并行管道中的顺序阶段

    我在 Jenkins 中有一个动态脚本化管道 它有许多并行阶段 但在每个阶段内都有多个串行步骤 我已经浪费了好几天的时间试图让它工作 无论我尝试什么 所有串行子阶段都集中到一个阶段 这是我现在所拥有的 node stage Parallel
  • 致命:Jenkins IIS ID 无效

    我正在尝试设置 Jenkins 从 bitbucket 中提取并构建一个项目 我在 IIS 8 5 Server 2012 r2 上使用它 我已经设置了 Git 和 Bitbucket 插件 我已经建立了一个包含以下内容的项目 Branch
  • Jenkins 文本参数 - 特殊字符乱码(不需要的变量替换)

    我在 Jenkins Linux 下 有一份工作构建参数 https wiki jenkins ci org display JENKINS Parameterized Build类型为 文本 我使用参数来形成在构建过程中使用的文件的内容
  • 如何查找elasticsearch 6.2.1中存在的索引?

    我试图检查elasticsearch 6 2 1的RestHighLevelClient中是否存在索引 目前我正在使用以下代码 try OpenIndexRequest openIndexRequest new OpenIndexReque
  • 静态加密数据时 ElasticSearch 的工作原理

    我的数据存在于 DynamoDB 中 为了启用全文搜索 我使用 Lambda 函数将其转发到 ES 索引 但如果可能的话 我希望在不影响搜索效率的情况下对数据进行加密 但我不确定我的搜索在这里如何进行 我找不到任何文档 文章来说明当数据静态
  • Rails Searchkick / Elasticsearch has_many 和belongs_to 关联

    我尝试使用 Searchkick 运行搜索并基于多个模型返回 我的书本模型包含这个 class Book lt ActiveRecord Base searchkick has many book subjects has many sub
  • TeamCity 将功能分支推送到主分支

    有没有办法将成功构建的功能分支推送到另一个分支 我想要这样的东西 Git 存储库 Gitorious GitHub 等 分支机构 master 当前项目的代码 质量保证 代码等待 QA 的分支 功能分支 许多远程分支 开发人员可以在其中开发
  • 詹金斯没有运行任何作业

    我在尝试解决其他一些问题时成功地破坏了詹金斯 现在 每当我运行作业时 它都会立即失败并出现以下错误 java lang NullPointerException at java util TreeMap putAll TreeMap jav
  • Jenkins - 如何将文件夹/文件从 Jenkins Linux 代理部署到 Windows 服务器?

    构建完成后 我将得到包含文件的构建文件夹 我需要将它们复制到远程 Windows 服务器 我尝试使用 通过 FTP 发布 插件但似乎 该插件可供采用 因此 根据公司政策 无法安装此功能 https plugins jenkins io pu
  • 詹金斯配置文件问题

    检查依赖关系 找不到与 Nitin xxxxxxx xyzCAppStore 匹配的 iOS 配置文件 Xcode 找不到与 Nitin xxxxxxx xyzCAppStore 匹配的配置文件 安装配置文件 通过将其拖放到 Xcode 的
  • Jenkins GIT 包含从未构建过的区域

    我正在尝试使用包含区域在 Jenkins 中构建我的工作 但每当选中此选项时 民意调查结果总是说未检测到任何更改 我尝试了许多不同的路径 以及使用工作区进行 不进行强制轮询 结果是轮询从未检测到任何更改 但一旦我删除这些选项 它们就会在下一
  • 在elasticSearch中查询时定义分析器

    我对 Elasticsearch 还很陌生 只需要一些说明 我们可以在查询搜索服务器时定义一个分析器吗 我尝试使用 文本 和 字段 查询 效果很好 Query curl XPOST http localhost 9200 test user
  • 在 CI (Travis/Jenkins) 环境中使用 xcodebuild (Xcode 8) 和自动签名

    随着 Xcode 8 的发布 Apple 引入了一种管理签名配置的新方法 现在你有两个选择Manual and Automatic 根据 WWDC 2016 关于代码签名的会议 WWDC 2016 401 Xcode 应用签名的新增功能 h
  • @NonCPS 在 Jenkins 管道脚本中的作用是什么

    我在詹金斯中有一个管道脚本 我曾经遇到过这个异常 org jenkinsci plugins scriptsecurity sandbox RejectedAccessException 不允许脚本使用 groovy json JsonSl
  • Jenkins 无法访问 SVN (https://)

    我创建了 Jenkins 项目 该项目在 SVN 上有文件 https repo xxx xxx svn priv 项目名称 https repo xxx xxx svn priv projectname 证书是自签名的 我的问题是 Jen
  • 在 Elasticsearch python 客户端中使用 SQL Access

    我正在尝试使用 python 客户端进行弹性搜索 以使用 SQL 访问进行弹性搜索来查询索引 我想使用sql语法查询索引 我如何指定elasticsearch必须读取SQL语法 def searchText text t1 time tim

随机推荐