Elasticsearch7.X 打卡学习(随缘更新。。)

本文介绍了Elasticsearch7.X的主要概念,包括索引、映射、文档、字段、集群、节点、分片和副本。讲解了Elasticsearch7.0的重大改进,如废弃多type支持、取消_all字段、新增应用程序主动监测功能等。深入探讨了ES的数据写入和读取过程,以及倒排索引原理。还讨论了深度分页的三种方式:from+size、scroll和search_after,强调了它们的适用场景和效率问题。


ElasticSearch概念

索引(index)

类似的数据放在一个索引,非类似的数据放不同索引, 一个索引也可以理解成一个关系型数据库。

映射(mapping)

mapping定义了每个字段的类型等信息。相当于关系型数据库中的表结构。
常用数据类型:text、keyword、number、array、range、boolean、date、geo_point、ip、nested、object

text:默认会进行分词,支持模糊查询(5.x之后版本string类型已废弃,请大家使用text)。
keyword:不进行分词;keyword类型默认开启doc_values来加速聚合排序操作,占用了大量磁盘io 如非必须可以禁用doc_values。
number:如果只有过滤场景 用不到range查询的话,使用keyword性能更佳,另外数字类型的doc_values比字符串更容易压缩。
array:es不需要显示定义数组类型,只需要在插入数据时用’[]‘表示即可,’[]'中的元素类型需保持一致。
range:对数据的范围进行索引;目前支持 number range、date range 、ip range。
boolean: 只接受true、false 也可以是字符串类型的“true”、“false”
date:支持毫秒、根据指定的format解析对应的日期格式,内部以long类型存储。
geo_point:存储经纬度数据对。
ip:将ip数据存储在这种数据类型中,方便后期对ip字段的模糊与范围查询。
nested:嵌套类型,一种特殊的object类型,存储object数组,可检索内部子项。
object:嵌套类型,不支持数组。

文档(document)

一个document相当于关系型数据库中的⼀行记录。

字段(field)

相当于关系型数据库表的字段

集群(cluster)

集群由一个或多个节点组成,⼀个集群有⼀个默认名称"elasticsearch"。

节点(node)

集群的节点,⼀台机器或者一个进程

分片和副本(shard)

副本是分片的副本。分片有**主分片(primary Shard)副本分片(replica Shard)**之分。
一个Index数据在物理上被分布在多个主分片中,每个主分片只存放部分数据。
每个主分片可以有多个副本,叫副本分片,是主分片的复制。

ElasticSearch7.0重大改进

1、彻底废弃多type支持,包括api层面,之前版本可在一个索引库下创建多个type。

2、彻底废弃_all字段支持,为提升性能默认不再支持全文检索,即7.0之后版本进行该项配置会报错。

3、新增应用程序主动监测功能,搭配对应的kibana版本,用户可监测应用服务的健康状态,并在出现问题后及时发出通知。

4、取消query结果中hits count的支持(聚合查询除外),使得查询性能大幅提升(3x-7x faster)。这意味着,每次查询后将不能得到精确的结果集数量。

5、新增intervals query ,用户可设置多字符串在文档中出现的先后顺序进行检索。

6、新增script_core ,通过此操作用户可以精确控制返回结果的score分值。

7、优化集群协调子系统,缩减配置项提升稳定性。

8、新增 alias、date_nanos、features、vector等数据类型。

9、7.0自带java环境,所以我们在安装es时不再需要单独下载和配置java_home。

10、7.0将不会再有OOM的情况,JVM引入了新的circuit breaker(熔断)机制,当查询或聚合的数据量超出单机处理的最大内存限制时会被截断

ES 的一些基本原理

es 写数据过程

  • 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node (协调节点)。
  • coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。
  • 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node 。
  • coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。
    在这里插入图片描述

写数据底层原理

在这里插入图片描述

  1. 先写入内存 buffer,在 buffer 里的时候数据是搜索不到的;同时将数据写入 translog 日志文件。
  2. 如果 buffer 快满了,或者到一定时间,就会将内存 buffer 数据 refresh 到一个新的 segment file 中,但是此时数据不是直接进入 segment file 磁盘文件,而是先进入 os cache 。这个过程就是 refresh 。
  3. 每隔 1 秒钟,es 将 buffer 中的数据写入一个新的 segment file ,每秒钟会产生一个新的磁盘文件 segment file ,这个 segment file 中就存储最近 1 秒内 buffer 中写入的数据。(但是如果 buffer 里面此时没有数据,那当然不会执行 refresh 操作,如果 buffer 里面有数据,默认 1 秒钟执行一次 refresh 操作,刷入一个新的 segment file 中。)

操作系统里面,磁盘文件其实都有一个东西,叫做 os cache ,即操作系统缓存,就是说数据写入磁盘文件之前,会先进入 os cache ,先进入操作系统级别的一个内存缓存中去。只要 buffer 中的数据被 refresh 操作刷入 os cache 中,这个数据就可以被搜索到了。

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

总结一下,数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache,到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。

数据写入 segment file 之后,同时就建立好了倒排索引。

删除/更新数据底层原理

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

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

buffer 每 refresh 一次,就会产生一个 segment file ,所以默认情况下是 1 秒钟一个 segment file ,这样下来 segment file 会越来越多,此时会定期执行 merge。每次 merge 的时候,会将多个 segment file 合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉,然后将新的 segment file 写入磁盘,这里会写一个 commit point ,标识所有新的 segment file ,然后打开 segment file 供搜索使用,同时删除旧的 segment file 。

es 读数据过程

可以通过 doc id 来查询,会根据 doc id 进行 hash,判断出来当时把 doc id 分配到了哪个 shard 上面去,从那个 shard 去查询。

  • 客户端发送请求到任意一个 node,成为 coordinate node 。
  • coordinate node 对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。
  • 接收请求的 node 返回 document 给 coordinate node 。
  • coordinate node 返回 document 给客户端。

写请求是写入 primary shard,然后同步给所有的 replica shard;
读请求可以从 primary shard 或 replica shard 读取,采用的是随机轮询算法。

es 搜索数据过程

es 最强大的是做全文检索。

  • 客户端发送请求到一个 coordinate node 。
  • 协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard ,都可以。
  • query phase:每个 shard 将自己的搜索结果(其实就是一些 doc id )返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
  • fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端。

底层 lucene

lucene 就是一个 jar 包,里面包含了封装好的各种建立倒排索引的算法代码。我们用 Java 开发的时候,引入 lucene jar,然后基于 lucene 的 api 去开发就可以了。
通过 lucene,我们可以将已有的数据建立索引,lucene 会在本地磁盘上面,给我们组织索引的数据结构。

倒排索引

倒排索引就是关键词到文档 ID 的映射,每个关键词都对应着一系列的文件,这些文件中都出现了关键词。

  • 倒排索引中的所有词项对应一个或多个文档;
  • 倒排索引中的词项根据字典顺序升序排列

ElasticSearch深度分页

常见深度分页方式 from+size (效率非常低)

es 默认采用的分页方式是 from+ size 的形式,在深度分页的情况下,这种使用方式效率是非常低的。(这种方式类似于mongo的 skip + size。)

es 目前支持最大的 skip 值是 max_result_window ,默认为 10000 。也就是当 from + size > max_result_window 时,es 将返回错误

分页方式 scroll (快照+游标)

原理上是对某次查询生成一个游标 scroll_id , 后续的查询只需要根据这个游标去取数据,直到结果集中返回的 hits 字段为空,就表示遍历结束。scroll_id 的生成可以理解为建立了一个临时的历史快照

不适用用于实时的请求,因为每一个 scroll_id 不仅会占用大量的资源(特别是排序的请求),而且是生成的历史快照,对于数据的变更不会反映到快照上。这种方式往往用于非实时处理大量数据的情况,比如要进行数据迁移或者索引变更之类的。

search_after (每一页最后一条数据)

它是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改查,这些变更也会实时的反映到游标上。
为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,这种分页方式其实和目前 moa 内存中使用rbtree 分页的原理一样,官方推荐使用 _uid 作为全局唯一值,其实使用业务层的 id 也可以。

search_after 适用于深度分页+ 排序,因为每一页的数据依赖于上一页最后一条数据,所以无法跳页请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值