【Elasticsearch系列十五】强大特性

news2024/11/13 12:03:46

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术,jvm,并发编程 redis,kafka,Spring,微服务等
    • 常用开发工具系列:常用的开发工具,IDEA,Mac,Alfred,Git,typora 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 新空间代码工作室:提供各种软件服务,承接各种毕业设计,毕业论文等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

      • 1.隐藏特性
      • 2.单 node 创建 index
      • 3.横向扩容
      • 4.数据路由
      • 5.增删改内部机制
      • 6.查询的内部机制
      • 7.bulk api 奇特的 json 格式
      • 8.写入机制
      • 9.bulk 性能问题

1.隐藏特性

  • 分布式机制:分布式数据存储及共享。
  • 分片机制:数据存储到哪个分片,副本数据写入。
  • 集群发现机制:cluster discovery。新启动 es 实例,自动加入集群。
  • shard 负载均衡:大量数据写入及查询,es 会将数据平均分配。
  • shard 副本:新增副本数,分片重分配。

扩容:

  • 垂直扩容:使用更加强大的服务器替代老服务器。但单机存储及运算能力有上线。且成本直线上升。如 10t 服务器 1 万。单个 10T 服务器可能 20 万。
  • 水平扩容:采购更多服务器,加入集群。大数据。

rebalance:

新增或滅少 es 实例时,es 集群会将数据重新分配。

master节点:

  • 创建删除节点
  • 创建蒯除索引

节点对等:

  • 节点对等,每个节点都能接收所有的请求
  • 自动请求路由
  • 响应收集

shard&replica机制:

  1. 每个 index 包含一个或多个 shard
  2. 每个 shard 都是一个最小工作单元,承载部分数据,lucene 实例,完整的建立索引和处理请求的能力
  3. 增减节点时,shard 会自动在 nodes 中负载均衡
  4. primary shard 和 replica shard,每个 document 肯定只存在于某一个 primary shard 以及其对应的 replica shard 中,不可能存在于多个 primary shard
  5. replica shard 是 primary shard 的副本,负责容错,以及承担读请求负载
  6. primary shard 的数量在创建索引的时候就固定了,replica shard 的数量可以随时修改
  7. primary shard 的默认数量是 1,replica 默认是 1,默认共有 2 个 shard,1 个 primary shard , 1 个 replica shard 注意:es7 以前 primary shard 的默认数量是 5,replica 默认是 1,默认有 10 个 shard,5 个 primary shard,5 个 replica shard
  8. primary shard 不能和自己的 replica shard 放在同一个节点上(否则节点宕机,primary shard 和副本都丢失,起不到容错的作用),但是可以和其他 primary shard 的 replica shard 放在同一个节点上

2.单 node 创建 index

number_of_shards 是指索引要做多少个分片,只能在创建索引时指定,后期无法修改。
number_of_replicas 是指每个分片有多少个副本,后期可以动态修改

  1. 单 node 环境下,创建一个 index,有 3 个 primary shard,3 个 replica shard
  2. 集群 status 是 yellow
  3. 这个时候,只会将 3 个 primary shard 分配到仅有的一个 node 上去,另外 3 个 replica shard 是无法分配的
  4. 集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承接任何请求
PUT /test_index1
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}

3.横向扩容

  • 分片自动负载均衡,分片向空闲机器转移。
  • 每个节点存储更少分片,系统资源给与每个分片的资源更多,整体集群性能提高。
  • 扩容极限:节点数大于整体分片数,则必有空闲机器。
  • 容错性:只要一个索引的所有主分片在,集群就就可以运行。

4.数据路由

一个文档,最终会落在主分片的一个分片上,到底应该在哪一个分片?这就是数据路由。

路由算法:

shard = hash(routing) % number_of_primary_shards

哈希值对主分片数取模。

举例:

对一个文档经过 crud 时,都会带一个路由值 routing number。默认为文档_id(可能是手动指定,也可能是自动生成)。

存储 1 号文档,经过哈希计算,哈希值为 2,此索引有 3 个主分片,那么计算 2%3=2,就算出此文档在 P2 分片上。

决定一个 document 在哪个 shard 上,最重要的一个值就是 routing 值,默认是_id,也可以手动指定,相同的 routing 值,每次过来,从 hash 函数中,产出的 hash 值一定是相同的

手动指定routing number

PUT /test_index/_doc/15?routing=num
{
  "num": 0,
  "tags": []
}

场景:在程序中,架构师可以手动指定已有数据的一个属性为路由值,好处是可以定制一类文档数据存储到一个分片中。缺点是设计不好,会造成数据倾斜。

所以,不同文档尽量放到不同的索引中。剩下的事情交给 es 集群自己处理。

涉及到以往数据的查询搜索,所以一旦建立索引,主分片数不可变。

检索文件的步骤:

从主分片或者副本分片检索文档的步骤顺序:

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

注意:

  • 在处理读取请求时,协调节点在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡。
  • 在文档被检索时,已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。在这种情况下,副本分片可能会报告文档不存在,但是主分片可能成功返回文档。一旦索引请求成功返回给用户,文档在主分片和副本分片都是可用的

5.增删改内部机制

增删改可以看做 update,都是对数据的改动。一个改动请求发送到 es 集群,经历以下四个步骤:

  1. 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node(协调节点)

  2. coordinating node,对 document 进行路由,将请求转发给对应的 node(有 primary shard)

  3. 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node

  4. coordinating node,如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。

6.查询的内部机制

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

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

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

  4. coordinate node 返回 document 给客户端

  5. 特殊情况:document 如果还在建立索引过程中,可能只有 primary shard 有,任何一个 replica shard 都没有,此时可能会导致无法读取到 document,但是 document 完成索引建立之后,primary shard 和 replica shard 就都有了。

7.bulk api 奇特的 json 格式

POST /_bulk
{"action": {"meta"}}\n
{"data"}\n
{"action": {"meta"}}\n
{"data"}\n
[
  {
    "action": {
      "method": "create"
    },
    "data": {
      "id": 1,
      "field1": "java",
      "field1": "spring"
    }
  },
  {
    "action": {
      "method": "create"
    },
    "data": {
      "id": 2,
      "field1": "java",
      "field1": "spring"
    }
  }
]

首先,bulk 中的每个操作都可能要转发到不同的 node 的 shard 去执行

如果采用比较良好的 json 数组格式,允许任意的换行,整个可读性非常棒,读起来很爽,es 拿到那种标准格式的 json 串以后,要按照下述流程去进行处理

  1. 将 json 数组解析为 JSONArray 对象,这个时候,整个数据,就会在内存中出现一份一模一样的拷贝,一份数据是 json 文本,一份数据是 JSONArray 对象

  2. 解析 json 数组里的每个 json,对每个请求中的 document 进行路由

  3. 为路由到同一个 shard 上的多个请求,创建一个请求数组。100 请求中有 10 个是到 P1.

  4. 将这个请求数组序列化

  5. 将序列化后的请求数组发送到对应的节点上去

耗费更多内存,更多的 jvm gc 开销,之前提到过 bulk size 最佳大小的那个问题,一般建议说在几千条那样,然后大小在 10MB 左右,所以说,可怕的事情来了。假设说现在 100 个 bulk 请求发送到了一个节点上去,然后每个请求是 10MB,100 个请求,就是 1000MB = 1GB,然后每个请求的 json 都 copy 一份为 jsonarray 对象,此时内存中的占用就会翻倍,就会占用 2GB 的内存,甚至还不止。因为弄成 jsonarray 之后,还可能会多搞一些其他的数据结构,2GB+的内存占用。

占用更多的内存可能就会积压其他请求的内存使用量,比如说最重要的搜索请求,分析请求,等等,此时就可能会导致其他请求的性能急速下降。

另外的话,占用内存更多,就会导致 java 虚拟机的垃圾回收次数更多,跟频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致 es 的 java 虚拟机停止工作线程的时间更多。

现在的奇特格式:

POST /_bulk
{ "delete": { "_index": "test_index",  "_id": "5" }} \n
{ "create": { "_index": "test_index",  "_id": "14" }}\n
{ "test_field": "test14" }\n
{ "update": { "_index": "test_index",  "_id": "2"} }\n
{ "doc" : {"test_field" : "bulk test"} }\n
  1. 不用将其转换为 json 对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割 json

  2. 对每两个一组的 json,读取 meta,进行 document 路由

  3. 直接将对应的 json 发送到 node 上去

最大的优势在于,不需要将 json 数组解析为一个 JSONArray 对象,形成一份大数据的拷贝,浪费内存空间,尽可能地保证性能。

8.写入机制

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

如果 buffer 快满了,或者到一定时间,就会将内存 buffer 数据 refresh 到一个新的 segment file 中,但是此时数据不是直接进入 segment file 磁盘文件,而是先进入 os cache 。这个过程就是 refresh

每隔 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 中,这个数据就可以被搜索到了。

为什么叫 es 是准实时的?NRT ,全称 near real-time 。默认是每隔 1 秒 refresh 一次的,所以 es 是准实时的,因为写入的数据 1 秒之后才能被看到。可以通过 es 的 restful api 或者 java api手动执行一次 refresh 操作,就是手动将 buffer 中的数据刷入 os cache 中,让数据立马就可以被搜索到。只要数据被输入 os cache 中,buffer 就会被清空了,因为不需要保留 buffer 了,数据在 translog 里面已经持久化到磁盘去一份了。

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

commit 操作发生第一步,就是将 buffer 中现有数据 refreshos cache 中去,清空 buffer。然后,将一个 commit point 写入磁盘文件,里面标识着这个 commit point 对应的所有 segment file ,同时强行将 os cache 中目前所有的数据都 fsync 到磁盘文件中去。最后清空 现有 translog 日志文件,重启一个 translog,此时 commit 操作完成。

这个 commit 操作叫做 flush 。默认 30 分钟自动执行一次 flush ,但如果 translog 过大,也会触发 flush 。flush 操作就对应着 commit 的全过程,我们可以通过 es api,手动执行 flush 操作,手动将 os cache 中的数据 fsync 强刷到磁盘上去。

translog 日志文件的作用是什么?你执行 commit 操作之前,数据要么是停留在 buffer 中,要么是停留在 os cache 中,无论是 buffer 还是 os cache 都是内存,一旦这台机器死了,内存中的数据就全丢了。所以需要将数据对应的操作写入一个专门的日志文件 translog 中,一旦此时机器宕机,再次重启的时候,es 会自动读取 translog 日志文件中的数据,恢复到内存 buffer 和 os cache 中去。

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

实际上你在这里,如果面试官没有问你 es 丢数据的问题,你可以在这里给面试官炫一把,你说,其实 es 第一是准实时的,数据写入 1 秒后可以搜索到;可能会丢失数据的。有 5 秒的数据,停留在 buffer、translog os cache、segment file os cache 中,而不在磁盘上,此时如果宕机,会导致 5 秒的数据丢失

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

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

9.bulk 性能问题

Elasticsearch bulk 操作的性能问题可能有很多原因,以下是一些常见的原因及对应的解决方案:

  1. 索引分片过多:如果索引的分片过多,会导致 bulk 操作的性能下降。因为 bulk 操作会同时操作多个分片,分片过多会导致操作变慢。解决方案是减少索引的分片数,通常建议不要超过 5 个分片。
  2. 磁盘 I/O 瓶颈:如果磁盘 I/O 性能不足,会导致 bulk 操作的性能下降。可以通过优化磁盘 I/O 性能来提高 bulk 操作的性能,例如使用更快的磁盘、使用 RAID 阵列等。
  3. 索引过大:如果索引过大,会导致 bulk 操作的性能下降。因为 bulk 操作需要同时操作多个文档,文档数量过多会导致操作变慢。可以通过分割索引或者使用时间序列索引等方式来解决问题。
  4. 网络带宽瓶颈:如果网络带宽不足,会导致 bulk 操作的性能下降。可以通过优化网络带宽来提高 bulk 操作的性能,例如使用更快的网络、增加网络带宽等。
  5. 索引设置不合理:如果索引的设置不合理,也会导致 bulk 操作的性能下降。例如,如果禁用了副本,可以通过启用副本来提高 bulk 操作的性能。
  6. 索引的文档大小不合适:如果索引的文档大小过大或者过小,也会影响 bulk 操作的性能。可以根据实际情况调整文档大小,通常建议文档大小控制在 1MB 左右。
    以上是一些可能导致 Elasticsearch bulk 操作性能下降的原因及对应的解决方案,可以根据实际情况进行优化。

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

没想到【C# ASP.NET + Vue】也能打造如此强大的健身房管理系统!告别传统管理,体验智能化的会员服务,课程安排竟然如此简单

🎓 作者:计算机毕设小月哥 | 软件开发专家 🖥️ 简介:8年计算机软件程序开发经验。精通Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等技术栈。 🛠️ 专业服务 🛠️ 需求定制化开发源码提…

多模态文档理解:一文读懂mPLUG-DocOwl系列模型

〔探索AI的无限可能,微信关注“AIGCmagic”公众号,让AIGC科技点亮生活〕 本文作者:AIGCmagic社区 刘一手 前言 随着人工智能技术的发展,多模态大型语言模型(MLLMs)在视觉-文本理解领域取得了显著进展。m…

yolov8多任务模型-目标检测+车道线检测+可行驶区域检测-yolo多检测头代码+教程

你只需看一次:实时且通用的多任务模型 A-YOLOM 插图 贡献 轻量化集成模型:我们开发了一种轻量级模型,能够将三个任务整合到一个统一的模型中。这对于需要实时处理的多任务场景尤其有利。自适应连接模块:特别为分割架构的颈部区域…

js中的 赋值 浅拷贝 和 深拷贝 详细解读

js数据类型主要分基本数据类型和引用数据类型。前者包括Number,String等,后者主要是Object,因此以下会针对不同的数据类型来分析,需要的朋友可以参考一下 基本数据类型(Primary Data Types): String(字符串) Number&…

--芯片测试--

目录 芯片逻辑是什么 芯片如何选型? 测试策略有什么 Alpha测试和Beta测试的区别? 主要区别 TOPS是什么 如何计算TOPS MAC单元是什么 频率的单位是什么 如何解决跨时钟域问题? 解释一下对异步电路的理解,以及如何实现同步…

【北京迅为】《STM32MP157开发板使用手册》-第四十三章 软件定时器实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐…

seL4 Capabilities(翻自官网)(一)

官网教程链接: Capability 初始化Capabilities tutorials // 先使用repo拉取一下tutorials,然后执行repo sync,所有的教程都在里面,学习某个的时候只需要改变的是 --tut 后面的参数 ./init --tut capabilities # building the tutorial exe…

电商商品详情API接口对电商跨境电商企业运营的好处

为了获取更大利益,电商商家经常需要使用价格,ERP接口系统。价格接口对电商商家有多方面的好处,主要体现在以下几个方面: 1、价格接口系统可以帮助品牌和商家实现更加科学和精准的定价策略。通过实时获取多个主流电商平台&#xf…

我与Linux的爱恋:进程优先级|进程切换

​ ​ 🔥个人主页:guoguoqiang. 🔥专栏:Linux的学习 文章目录 1.进程优先级1.什么是进程优先级?2.进程优先级的类型3.进程优先级的作用4.进程优先级的实现5.进程优先级的重要性6.查看系统进程7.修改进程优先级8.优先…

通过蓝图Blueprint完成项目拆分、模块化以及模块化后项目结构分析

1、不拆分项目之前的写法 在上一篇Flask入门和视图中我们讲解了Flask项目的一个启动流程,引入Flask、创建Flask对象,然后由路由进入在视图函数中通过模版渲染或者json系列化的方式返回页面或者数据。我们发现这些所有的操作都是在一个页面中完成的&…

信息化时代下的高标准农田灌区:变革与机遇并存

在信息化时代的浪潮中,高标准农田灌区的建设与管理正经历着前所未有的变革,这既是一个挑战重重的历程,也孕育着无限的发展机遇。随着物联网、大数据、云计算以及人工智能等先进技术的飞速发展与融合应用,传统的农田灌溉模式正在被…

【Docker】安装全流程与配置完整镜像源(可安装 nginx)

目录 一、卸载历史版本(选)二、配置 yum 源三、安装 docker四、配置 docker 镜像源加速(选、强烈建议)4.1 配置阿里镜像加速4.2 配置其他镜像源 五、启动 docker参考文章与视频 本文基于 Linux - CentOS 7 操作系统。 一、卸载历史…

PG198-jesd204-phy阅读笔记

简介 介绍 JESD204 PHY IP核实现了JESD204的物理接口,简化在发送和接收核心之间共享串行收发器信息通道。此内核一般不单独使用,只能与JESD204或JESD204C内核结合使用。 特性 根据JESD204B和JESD204C草案设计   支持1至12lane配置   JESD204 IP支持…

clousx6整点报时指令怎么写?

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&am…

对称加密算法使用示例

Demo包括以下对称加密算法组合 备注:XTS仅支持AES128和AES256,不支持AES192 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import cmac from cryptography.hazmat.primitives.…

SpringBoot 基于 Vue 的地方美食分享网站

摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地…

smardaten无代码这么牛逼?逻辑编排不用代码!

目录 前言 经典案例 ①计划编排:数据操作自动化 ②工单派工:流程变更自动化 smardaten能力解析 一、逻辑控制篇 (1)变量定义与操作 (2)数据校验与反馈 (3)动态数据获取与回填…

企业微信oauth2提示应用无法使用

问题描述: 生成oauth2之后,我a公司是服务商,我给b公司的人去点授权链接会提示这个 应用服务商还没有在企业微信为你开通接口调用许可」,导致无法使用此应用,请联系服务商开通 正文 你先要知道一件事!&…

基于SpringBoot+Vue的“课件通”中小学教学课件共享平台

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

后端原型设计

一:导航设计 1.1 横向导航栏 常用于浏览器对客的系统。 1.2 纵向导航栏 纵向导航左边可以进行一级菜单和二级菜单,每个二级菜单右边还可以继续再使用标签栏进行导航三级分类。 头条号和CSDN都是采用该方式。 1.3 横纵结合导航栏 横向为一级菜单&…