ToB企服应用市场:ToB评测及商务社交产业平台

标题: ElasticSearch详解 [打印本页]

作者: 一给    时间: 2024-7-23 18:40
标题: ElasticSearch详解
目次

一、Elasticsearch是什么?
二、为什么要利用ElasticSearch
2.1 关系型数据库有什么问题?
2.2 ElasticSearch有什么优势?
2.3 ES利用场景
三、ElasticSearch概念、原理与实现
3.1 搜刮引擎原理
3.2 Lucene 倒排索引焦点原理
倒排索引
四、Elasticsearch 整体架构
4.1 集群节点角色
4.2 数据副本
4.3 水平扩容
4.4 故障转移
4.5 路由机制
4.6 新建、更新、删除文档
4.6.1 写数据底层原理
4.6.2 索引的不变性
4.6.3 动态索引创建过程
4.6.4 分步检察数据持久化过程
4.6.5 更新/删除数据底层原理
4.7 查询文档
4.8 更新文档
4.9 分布式检索
五、ElasticSearch实际利用过程中会有什么问题
5.1 分片的设定
5.2 ES数据近及时问题
5.3 深分页问题
六、ES性能优化
七、ElasticSearch运维


一、Elasticsearch是什么?

Elasticsearch(简称ES)是一个分布式、可扩展、及时的搜刮与数据分析引擎。ES不光仅只是全文搜刮,还支持结构化搜刮、数据分析、复杂的语言处理惩罚、地理位置和对象间关联关系等。
ES的底层依赖Lucene,Lucene可以说是当下最先进、高性能、全功能的搜刮引擎库。但是Lucene仅仅只是一个库。为了充分发挥其功能,你需要利用Java并将Lucene直接集成到应用程序中。更糟糕的是,您大概需要获得信息检索学位才华相识其工作原理,由于Lucene非常复杂。
鉴于Lucene云云强大却难以上手的特点,诞生了ES。ES也是利用Java编写的,它的内部利用Lucene做索引与搜刮,它的目的是隐藏Lucene的复杂性,取而代之的提供一套简单同等的RESTful API。
ES具有如下特点:


二、为什么要利用ElasticSearch

2.1 关系型数据库有什么问题?

传统的关系数据库提供变乱保证,具有不错的性能,高可靠性,久履历史磨练,而且利用简单,功能强大,同时也积聚了大量的乐成案例。
厥后,随着访问量的上升,几乎大部分利用 MySQL 架构的网站在数据库上都开始出现了性能问题,web 程序不再仅仅专注在功能上,同时也在追求性能。
读写分离
由于数据库的写入压力增长,读写会集在一个数据库上让数据库不堪重负,大部分网站开始利用主从复制技能来达到读写分离,以提高读写性能和读库的可扩展性。Mysql 的 master-slave 模式成为这个时候的网站标配了。
分表分库
开始盛行利用分表分库来缓解写压力和数据增长的扩展问题。这个时候,分表分库成了一个热门技能,也是业界讨论的热门技能问题。
MySQL 的扩展性瓶颈
大数据量高并发环境下的 MySQL 应用开发越来越复杂,也越来越具有技能挑战性。分表分库的规则把握都是需要履历的。虽然有像淘宝这样技能气力强大的公司开发了透明的中间件层来屏蔽开发者的复杂性,但是制止不了整个架构的复杂性。分库分表的子库到一定阶段又面临扩展问题。还有就是需求的变更,大概又需要一种新的分库方式。
关系数据库很强大,但是它并不能很好的应付全部的应用场景。MySQL 的扩展性差(需要复杂的技能来实现),大数据下 IO 压力大,表结构更改困难,正是当前利用 MySQL 的开发职员面临的问题。
2.2 ElasticSearch有什么优势?

非关系型、搜刮引擎、近及时搜刮与分析、高可用、天然分布式、横向可扩展
2.3 ES利用场景

三、ElasticSearch概念、原理与实现

3.1 搜刮引擎原理

一次完备的搜刮从用户输入要查询的关键词开始,比如想查找 Lucene 的相关学习资料,我们都会在 Google 或百度等搜刮引擎中输入关键词,比如输入“Lucene ,全文检索框架”,之后系统根据用户输入的关键词返回相关信息。一次检索大致可分为四步:
第一步:查询分析
正常情况下用户输入正确的查询,比如搜刮“里约奥运会”这个关键词,用户输入正确完成一次搜刮,但是搜刮通常都是全开放的,任何的用户输入都是有大概的,很大一部分还是非常口语化和个性化的,偶然候还会存在拼写错误,用户不鉴戒把“淘宝”打成“涛宝”,这时候需要用自然语言处理惩罚技能来做拼写纠错等处理惩罚,以正确理解用户需求。
第二步:分词技能
这一步利用自然语言处理惩罚技能将用户输入的查询语句举行分词,如标准分词会把“lucene全文检索框架”分成 lucene | 全 | 文|检|索|框|架|, IK分词会分成: lucene|全文|检索|框架|,还有简单分词等多种分词方法。
第三步:关键词检索
提交关键词后在倒排索引库中举行匹配,倒排索引就是关键词和文档之间的对应关系,就像给文档贴上标签。比如在文档会集含有 "lucene" 关键词的有文档1 、文档 6、文档9,含有 "全文检索" 关键词的有文档1 、文档6 那么做与运算,同时含有 "lucene" 和 "全文检索" 的文档就是文档1和文档6,在实际的搜刮中会有更复杂的文档匹配模型。
第四步:搜刮排序
对多个相关文档举行相关度盘算、排序,返回给用户检索效果。

3.2 Lucene 倒排索引焦点原理

Lucene 是一个成熟的权威检索库,具有高性能、可伸缩的特点,并且开源、免费。在其基础上开发的分布式搜刮引擎便是 Elasticsearch。


Elasticsearch 的搜刮原理简单过程是,索引系统通过扫描文章中的每一个词,对其创建索引,指明在文章中出现的次数和位置,当用户查询时,索引系统就会根据事先的索引举行查找,并将查找的效果反馈给用户的检索方式。
倒排索引

倒排索引是整个 ES 的焦点,正常的搜刮以一本书为例,应该是由 “目次 -> 章节 -> 页码 -> 内容” 这样的查找顺序,这样是正排索引的思想。

但是假想一下,我在一本书中快速查找 “elasticsearch” 这个关键字所在的页面该怎么办?

倒排索引的思绪是通过单词到文档ID的关系对应。


倒排索引包含两个部分:

如何理解倒排索引呢?假如现有三份数据文档,文档的内容如下分别是:

为了创建倒排索引,我们通过分词器将每个文档的内容域拆分成单独的词(我们称它为词条或 Term),创建一个包含全部不重复词条的排序列表,然后列出每个词条出现在哪个文档。
效果如下所示:
  1. Term          Doc_1    Doc_2   Doc_3
  2. -------------------------------------
  3. Java        |   X   |        |
  4. is          |   X   |   X    |   X
  5. the         |   X   |   X    |   X
  6. best        |   X   |   X    |   X
  7. programming |   x   |   X    |   X
  8. language    |   X   |   X    |   X
  9. PHP         |       |   X    |
  10. Javascript  |       |        |   X
  11. -------------------------------------
复制代码
这种结构由文档中全部不重复词的列表构成,对于其中每个词都有一个文档列表与之关联。
这种由属性值来确定记载的位置的结构就是倒排索引。带有倒排索引的文件我们称为倒排文件。
我们将上面的内容转换为图的形式来阐明倒排索引的结构信息,如下图所示:


其中主要有如下几个焦点术语需要理解:

每条记载称为一个倒排项(Posting)。倒排表记载的不单是文档编号,还存储了词频等信息。

像 B+ 树一样,可以在页里实现二分查找。


Lucene 的倒排索引,增长了最左边的一层「字典树」term index,它不存储全部的单词,只存储单词前缀,通过字典树找到单词所在的块,也就是单词的大概位置,再在块里二分查找,找到对应的单词,再找到单词对应的文档列表。
Lucene 的实现会要更加复杂,针对差别的数据结构采用差别的字典索引,利用了FST模型、BKDTree等结构。
真实的倒排记载也并非一个链表,而是采用了SkipList、BitSet等结构

四、Elasticsearch 整体架构



Document:文档,指一行数据;
Index:索引,是多个document的集合(和sql数据库的表对应);
Shard:分片,当有大量的文档时,由于内存的限定、磁盘处理惩罚能力不敷、无法富足快的响应客户端的请求等,一个节点大概不敷。这种情况下,数据可以分为较小的分片。每个分片放到差别的服务器上。
当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将效果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的
Replia:副本,为提高查询吞吐量或实现高可用性,可以利用分片副本。
副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特别的分片称为主分片。
当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。
Node:节点,形成集群的每个服务器称为节点,一个节点可以包含多个shard
Cluster:集群,ES可以作为一个独立的单个搜刮服务器。不过,为了处理惩罚大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。

4.1 集群节点角色



ES集群的服务器主要分为以下三种角色:
1)master节点:负责生存和更新集群的一些元数据信息,之后同步到全部节点,所以每个节点都需要生存全量的元数据信息:

主节点负责创建索引、删除索引、跟踪哪些节点是聚集的一部分,并决定哪些分片分配给相关的节点、追踪集群中节点的状态等,稳固的主节点对集群的健康是非常告急的。
2)data节点:负责数据存储和查询
数据节点负责数据的存储和相关的操作,比方对数据举行增、删、改、查和聚合等操作,所以数据节点(Data 节点)对呆板设置要求比较高,对 CPU、内存和 I/O 的消耗很大。
3)coordinator节点(和谐节点):
路由索引请求
聚合搜刮效果集
分发批量索引请求
4)候选主节点:
可以被推举为主节点(Master 节点),集群中只有候选主节点才有推举权和被推举权,其他节点不参与推举的工作。
master推举推举战略
1. 假如集群中存在master,认可该master,参加集群
2. 假如集群中不存在master,从具有master资格的节点中选id最小的节点作为master推举时机
假如你利用 Master 候选节点作为单播列表,你只要列出三个就可以了。这个设置在 elasticsearch.yml 文件中:
  1. discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]
复制代码
每个节点既可以是候选主节点也可以是数据节点,通过在设置文件 ../config/elasticsearch.yml 中设置即可,默认都为 true。
  1. node.master: true  //是否候选主节点
  2. node.data: true    //是否数据节点
复制代码
3. 集群启动:后台启动线程去ping集群中的节点,按照上述战略从具有master资格的节点中推举出master
4. 现有的master离开集群:后台不停有一个线程定时ping master节点,凌驾一定次数没有ping乐成之后,重新举行master的推举制止脑裂
脑裂问题是采用master-slave模式的分布式集群普遍需要关注的问题,脑裂一旦出现,会导致集群的状态出现不同等,导致数据错误甚至丢失。
5. ES制止脑裂的战略:过半原则,可以在ES的集群设置中添加一下设置,制止脑裂的发生
4.2 数据副本



ES通过副天职片的方式,保证集群数据的高可用,同时增长集群并发处理惩罚查询请求的能力,相应的,在数据写入阶段会增大集群的写入压力。
数据写入的过程中,首先被路由到主分片,写入乐成之后,将数据发送到副天职片,为了保证数据不丢失,最好保证至少一个副天职片写入乐成以后才返回客户端乐成。
4.3 水平扩容



Node 1 和 Node 2 上各有一个分片被迁移到了新的 Node 3 节点,现在每个节点上都拥有2个分片,而不是之前的3个。 这体现每个节点的硬件资源(CPU, RAM, I/O)将被更少的分片所共享,每个分片的性能将会得到提升。
分片是一个功能完备的搜刮引擎,它拥有利用一个节点上的全部资源的能力。 我们这个拥有6个分片(3个主分片和3个副天职片)的索引可以最大扩容到6个节点,每个节点上存在一个分片,并且每个分片拥有所在节点的全部资源。
但是假如我们想要扩容凌驾6个节点怎么办呢?
主分片的数量在索引创建时就已经确定了下来。实际上,这个数量界说了这个索引可以或许 存储 的最大数据量。(实际巨细取决于你的数据、硬件和利用场景。) 但是,读操作——搜刮和返回数据——可以同时被主分片 或 副天职片所处理惩罚,所以当你拥有越多的副天职片时,也将拥有越高的吞吐量。
在运行中的集群上是可以动态调解副天职片数量的,我们可以按需伸缩集群。让我们把副本数从默认的 1 增长到 2 :


4.4 故障转移

假如我们关闭第一个节点,这时集群的状态为:


我们关闭的节点是一个主节点。而集群必须拥有一个主节点来保证正常工作,所以发生的第一件事情就是推举一个新的主节点: Node 2 。
在我们关闭 Node 1 的同时也失去了主分片 1 和 2 ,并且在缺失主分片的时候索引也不能正常工作。 假云云时来检查集群的状况,我们看到的状态将会为 red :不是全部主分片都在正常工作。
荣幸的是,在别的节点上存在着这两个主分片的完备副本, 所以新的主节点立即将这些分片在 Node 2 和 Node 3 上对应的副天职片提升为主分片。
4.5 路由机制

当索引一个文档的时候,文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢?
首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从那边探求了。实际上,这个过程是根据下面这个公式决定的:
  1. shard = hash(routing) % number_of_primary_shards
复制代码
routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自界说的值。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到 余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。
这就表明了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:由于假如数量厘革了,那么全部之前路由的值都会无效,文档也再也找不到了。
4.6 新建、更新、删除文档




4.6.1 写数据底层原理

write -> refresh -> flush -> merge


4.6.2 索引的不变性

由于倒排索引的结构特性,在索引建立完成后对其举行修改将会非常复杂。再加上几层索引嵌套,更让索引的更新变成了几乎不大概的动作。
所以索性设计成不可改变的:倒排索引被写入磁盘后是不可改变的,它永远不会修改。不变性有告急的价值:
1. 不需要锁。假如你从来不更新索引,你就不需要担心多进程同时修改数据的问题。
2. 一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有富足的空间,那么大部分读请求会直接请求内存,而不会掷中磁盘。这提供了很大的性能提升。
3. 别的缓存(像filter缓存),在索引的生命周期内始终有效。它们不需要在每次数据改变时被重修,由于数据不会厘革。
4. 写入单个大的倒排索引允许数据压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的利用量。
当然,一个不变的索引也有不好的地方。主要事实是它是不可变的,你不能修改它。假如你需要让一个新的文档 可被搜刮,你需要重修整个索引。这要么对一个索引所能包含的数据量造成了很大的限定,要么对索引可被更新的频率造成了很大的限定。
怎样在保存不变性的前提下实现倒排索引的更新?答案是: 用更多的索引。
通过增长新的增补索引来反映新近的修改,而不是直接重写整个倒排索引。每一个倒排索引都会被轮流查询到—从最早的开始—查询完后再对效果举行归并。
4.6.3 动态索引创建过程




  1. shard = hash(document_id) % (num_of_primary_shards)
复制代码

  1. # 一个 Segment 的内部
  2. $ tree xgChCUdvTZ2G0dyJjGcp6A
  3. xgChCUdvTZ2G0dyJjGcp6A
  4. ├── 0
  5. │   ├── _state
  6. │   │   ├── retention-leases-42.st
  7. │   │   └── state-3.st
  8. │   ├── index
  9. │   │   ├── _1e.fdm
  10. │   │   ├── _1e.fdt
  11. │   │   ├── _1e.fdx
  12. │   │   ├── _1e.fnm
  13. │   │   ├── _1e.kdd
  14. │   │   ├── _1e.kdi
  15. │   │   ├── _1e.kdm
  16. │   │   ├── _1e.si
  17. │   │   ├── _1e_1.fnm
  18. │   │   ├── _1e_1_Lucene90_0.dvd
  19. │   │   ├── _1e_1_Lucene90_0.dvm
  20. │   │   ├── _1e_Lucene90_0.doc
  21. │   │   ├── _1e_Lucene90_0.dvd
  22. │   │   ├── _1e_Lucene90_0.dvm
  23. │   │   ├── _1e_Lucene90_0.tim
  24. │   │   ├── _1e_Lucene90_0.tip
  25. │   │   ├── _1e_Lucene90_0.tmd
  26. │   │   ├── _1f.cfe
  27. │   │   ├── _1f.cfs
  28. │   │   ├── _1f.si
  29. │   │   ├── segments_e
  30. │   │   └── write.lock
  31. │   └── translog
  32. │       ├── translog-16.tlog
  33. │       └── translog.ckp
  34. └── _state
  35.     └── state-8.st
复制代码
4.6.4 分步检察数据持久化过程

write -> refresh -> flush -> merge



一个新文档过来,会存储在 in-memory buffer 内存缓冲区中,趁便会记载 Translog(Elasticsearch 通过变乱日志,在每一次对 Elasticsearch 举行操作时记载操作)。
这个时候数据还没有到 segment,搜不到新文档。数据只有被 refresh 后,才可以被搜刮到。




refresh 默认1s,可通过 index.refresh_interval 设置。refresh 流程大致如下:


每隔一段时间,假如 translog 变得越来越大,索引会被刷新(flush);一个新的 translog 被创建,并且一个全量提交被实行


上个过程 segment 在文件系统缓存中,会有不测故障文档丢失,那么,为了保证文档不会丢失,需要将文档从文件缓存写入磁盘的过程就是 flush,写入磁盘后,清空 translog,具体过程如下:


由于主动刷新流程每秒会创建一个新的 Segment ,这样会导致短时间内的 Segment 数量暴增。而 Segment 数量太多会带来较大的麻烦。 每一个 Segment 都会消耗文件句柄、内存和cpu运行周期。更告急的是,每个搜刮请求都必须轮流检查每个Segment ;所以 Segment 越多,搜刮也就越慢。
Elasticsearch 通过在后台举行 Merge Segment 来解决这个问题,小的 Segment 被归并到 大的 Segment,然后这些大的Segment 再归并到更大的 Segment。
当索引的时候, refresh 操作会创建新的 Segment 并将Segment 打开供搜刮利用,归并进程选择一小部分巨细相似的段,并且在后台将他们归并到更大的段中。这并不会中断索引和搜刮。


归并大的段需要消耗大量的I/O和CPU资源,假如任其发展会影响搜刮性能。Elasticsearch在默认情况下会对归并流程举行资源限定,所以搜刮仍然 有富足的资源很好地实行。

4.6.5 更新/删除数据底层原理

假如是删除操作,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 。

4.7 查询文档

可以从主分片或者从别的任意副天职片检索文档


可以通过 doc id 来查询,会根据 doc id 举行 hash,判定出来当时把 doc id 分配到了哪个 shard 上面去,从谁人 shard 去查询。
  1. shard = hash(document_id) % (num_of_primary_shards)
复制代码

4.8 更新文档



以下是部分更新一个文档的步骤:
4.9 分布式检索

全部的搜刮系同一样寻常都是两阶查询,第一阶段查询到匹配的 DocID,第二阶段再查询 DocID 对应的完备文档。


查询阶段
在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副天职片)。 每个分片在本地实行搜刮并构建一个匹配文档的优先队列。


查询阶段包含以下三个步骤:
当一个搜刮请求被发送到某个节点时,这个节点就变成了和谐节点。 这个节点的任务是广播查询请求到全部相关分片并将它们的响应整合成全局排序后的效果集合,这个效果集合会返回给客户端。
和谐节点将这些分片级的效果归并到自己的有序优先队列里,它代表了全局排序效果集合。至此查询过程结束。
取回阶段
查询阶段标识哪些文档满意搜刮请求,但是我们仍然需要取回这些文档,这是取回阶段的任务。


分布式阶段由以下步骤构成:
和谐节点首先决定哪些文档确实需要被取回。比方,假如我们的查询指定了 { "from": 90, "size": 10 } ,最初的90个效果会被丢弃,只有从第91个开始的10个效果需要被取回。这些文档大概来自和最初搜刮请求有关的一个、多个甚至全部分片。
深分页
每个分片必须先创建一个 from + size 长度的队列,和谐节点需要根据 number_of_shards * (from + size) 排序文档,来找到被包含在 size 里的文档。
取决于你的文档的巨细,分片的数量和你利用的硬件,给 10,000 到 50,000 的效果文档深分页( 1,000 到 5,000 页)是完全可行的。但是利用富足大的 from 值,排序过程大概会变得非常沉重,利用大量的CPU、内存和带宽。
五、ElasticSearch实际利用过程中会有什么问题

5.1 分片的设定

分片数过小,数据写入形成瓶颈,无法水平拓展
分片数过多,每个分片都是一个lucene的索引,分片过多将会占用过多资源
如何盘算分片数
需要留意分片数量最好设置为节点数的整数倍,保证每一个主机的负载是差不多一样的,特别的,假如是一个主机部署多个实例的情况,更要留意这一点,否则大概遇到其他主机负载正常,就某个主机负载特别高的情况。
一样寻常我们根据每天的数据量来盘算分片,保持每个分片的巨细在 50G 以下比较公道。假如还不能满意要求,那么大概需要在索引层面通过拆分更多的索引或者通过别名 + 按小时 创建索引的方式来实现了。
5.2 ES数据近及时问题

ES数据写入之后,要经过一个refresh操作之后,才华够创建索引,举行查询。但是get查询很特别,数据及时可查。
ES5.0之前translog可以提供及时的CRUD,get查询会首先检查translog中有没有最新的修改,然后再尝试去segment中对id举行查找。5.0之后,为了减少translog设计的负责性以便于再其他更告急的方面对translog举行优化,所以取消了translog的及时查询功能。
get查询的及时性,通过每次get查询的时候,假如发现该id还在内存中没有创建索引,那么首先会触发refresh操作,来让id可查。
5.3 深分页问题

解决方案1:服务端缓存 Scan and scroll API
为了返回某一页记载,其实我们抛弃了其他的大部分已经排好序的效果。那么简单点就是把这个效果缓存起来,下次就可以用上了。根据这个思绪,ES提供了Scroll API。它概念上有点像传统数据库的游标(cursor)。
scroll调用本质上是及时创建了一个快照(snapshot),然后保持这个快照一个指定的时间,这样,下次请求的时候就不需要重新排序了。从这个方面上来说,scroll就是一个服务端的缓存。既然是缓存,就会有下面两个问题:
其实这里还有第三个问题,但是它不是缓存的问题,而是由于ES采用的游标机制导致的。就是你只能顺序的扫描,不能随意的跳页。而且还要求客户每次请求都要带上”游标”。
解决方案2:Search After
Scroll API相对于from+size方式当然是性能好许多,但是也有如下问题:
针对这些问题,ES 5.0 开始推出了Search After机制可以提供了更及时的游标(live cursor)。它的思想是利用上一页的分页效果来提高下一页的分页请求。
六、ES性能优化

存储装备
磁盘在现代服务器上通常都是瓶颈。Elasticsearch 重度利用磁盘,你的磁盘能处理惩罚的吞吐量越大,你的节点就越稳固。
这里有一些优化磁盘 I/O 的技巧:

内部索引优化


Elasticsearch 为了能快速找到某个 Term,先将全部的 Term 排个序,然后根据二分法查找 Term,时间复杂度为 logN,就像通过字典查找一样,这就是 Term Dictionary。
现在再看起来,似乎和传统数据库通过 B-Tree 的方式类似。但是假如 Term 太多,Term Dictionary 也会很大,放内存不实际,于是有了 Term Index。
就像字典里的索引页一样,A 开头的有哪些 Term,分别在哪页,可以理解 Term Index是一棵树。
这棵树不会包含全部的 Term,它包含的是 Term 的一些前缀。通过 Term Index 可以快速地定位到 Term Dictionary 的某个 Offset,然后从这个位置再今后顺序查找。
在内存中用 FST 方式压缩 Term Index,FST 以字节的方式存储全部的 Term,这种压缩方式可以有效的缩减存储空间,使得 Term Index 足以放进内存,但这种方式也会导致查找时需要更多的 CPU 资源。
对于存储在磁盘上的倒排表同样也采用了压缩技能减少存储所占用的空间。
调解设置参数
调解设置参数建议如下:

假如你是在做大批量导入,导入期间你可以通过设置这个值为 -1 关掉刷新,还可以通过设置 index.number_of_replicas: 0 关闭副本。别忘记在完工的时候重新开启它。

假如有 N 个分片,则和谐节点再对(from+size)×n 条数据举行二次排序,然后选择需要被取回的文档。当 from 很大时,排序过程会变得很沉重,占用 CPU 资源严重。

JVM 调优
JVM 调优建议如下:

Elasticsearch 默认安装后设置的堆内存是 1GB。可通过 ../config/jvm.option 文件举行设置,但是最好不要凌驾物理内存的50%和凌驾 32GB。

七、ElasticSearch运维

删除不消的索引
  1. 获取磁盘空间情况:
  2. GET /_cat/allocation?v
  3. 查看索引占用情况:
  4. GET _cat/indices?v
  5. 查看索引占用情况(按索引排序):
  6. GET _cat/indices?v&s=index:asc
  7. 删除索引:
  8. DELETE onebyone-bizmember-k8s-logs-2023.05.30-171317
复制代码
参考:
理解ElasticSearch工作原理
看完这篇还不会 Elasticsearch,我跪搓衣板!
elasticsearch 原理及入门


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4