查看原文
其他

干货 | Elasticsearch 6个不明显但很重要的注意事项

zhisheng 2021-09-05

The following article is from 铭毅天下 Author 铭毅天下


公众号里回复 面经 可以查看更多 面经和面试题 文章

公众号里回复 ES 可以查看系列 ElasticSearch 文章!

公众号里回复 Flink 可以查看系列 Flink 文章!

公众号里回复 Spring 可以查看系列 Spring & SpringBoot 文章!

公众号里回复 Java 可以查看系列 Java 文章!

公众号里回复 监控 可以查看更多 监控 文章!

题记

Elasticsearch是被Netflix,微软,eBay,Facebook等Top N 顶级公司使用的搜索引擎。它很容易使用,但从长远来看相对难掌握。在本文中,我们分享了在系统中使用Elasticsearch六个不太明显但非常值得了解的注意事项。

1. Elastic Stack

Elasticsearch最初是作为独立产品开发的。它的核心作用是提供可扩展的搜索引擎服务,它提供多种语言库API,基于分布式模型创建,并对外提供REST API接口服务。

随着Elastic生态圈的发展,衍生出了与Elasticsearch并肩作战的其他工具集合。从最早的Kibana (用于可视化和数据分析)、Logstash (用于日志收集),到如下的N多工具都是Elastic公司开发的:

  • Beats - 核心功能:数据传输目的, 

  • Elastic Cloud  - 托管Elasticsearch集群, 

  • Machine Learning - 用于发现数据模式,

  • APM  - 应用程序性能监控,

  • Swiftype  - 一键式网站搜索。

工具数量每年都在增长,这使得公司能够实现新的目标并创造新的机会。

铭毅:Elastic早已不单单是Elasticsearch,而是一体化的工具集合、一体化大数据解决方案工具集。

2.两种数据集

2.1 数据集分类

基本上,你可以在Elasticsearch中索引(即存储)您想要的任何数据。但实际上有两类:静态数据和时间序列数据。它们会严重影响群集的配置和管理方式。

  • 静态数据是可能会缓慢增长或变化的数据集。像目录或物品清单。
    你可以将它们视为存储在常规数据库中的数据。如:博客文章,图书馆书籍,订单等。你可能希望在Elasticsearch中索引此类数据以启用快速搜索,常规数据库很难实现这些功能。



  • 时间序列数据集,可以是与通常快速增长的时刻相关联的事件数据,例如:日志文件或度量。
    你需要上在Elasticsearch中为它们编制索引,以进行数据分析,模式发现和系统监视。

2.2 数据集建模方式

根据您存储的数据类型,你应该以不同的方式为集群建模。

  • 对于静态数据:你应该选择固定数量的索引和分片。它们不会快速增长,您总是希望搜索数据集中的所有文档。

  • 对于时间序列数据,你应该选择基于时间的滚动索引。您会相对频繁地查询最近的数据,并且最终甚至会删除或者至少归档过时的文档以便在机器物理存储上节省资金。

铭毅:两种数据集,决定了我们数据的两种不同的建模方式。

3.搜索评分

对于每个搜索查询,Elasticsearch都会计算相关性分数。该分数基于tf-idf算法,该算法代表词项频率 - 反向文档频率。
基本上,在该算法中计算两个值。

  • 第一个:词项频率TF - 表示在文档中使用给定词项的频率。

  • 第二个 - 反向文档频率IDF - 表示给定词项在所有文档中的唯一性。

3.1 TF计算

例如,如果我们有两个文档:

文档1:To be or not to be, that is the question. 
文档2:To be. I am. You are. He, she is.

question词项的TF计算如下:

  • 对于文档1:1/10(10个词项中有1个出现) 

  • 对于文档2:0/9(9个词项中出现0次)。

3.2 IDF计算

IDF计算为整个数据集的单个值。它是所有文档与包含搜索词的文档的比率。
在我们的例子中它是:log(2/1)= 0.301
其中:

  • 2  - 所有文件的数量, 

  • 1  - 包含“question”词项的文件数量。

3.3 相关性得分结果

最后,两个文档的tf-idf分数计算为两个值的乘积:

  • 文档1:1/10 x 0.301 = 0.1 * 0.301 = 0.03

  • 文档2:0/9 x 0.301 = 0 * 0.301 = 0.00
    现在我们看到文档1的值为0.03,而文档2的值为0.00。
    因此,文档1将在结果列表中优先返回。

铭毅:实际应用中比这要复杂一些,可以结合explain:true验证一把

如下:

1PUT my_index3
2{
3  "mappings": {
4    "_doc": {
5      "properties": {
6        "title": { 
7          "type": "text"
8        }
9      }
10    }
11  }
12}
13
14POST my_index3/_doc/1
15{
16  "title":"To be or not to be, that is the question."
17}
18
19POST my_index3/_doc/2
20{
21  "title":"To be. I am. You are. He, she is."
22}
23
24POST my_index3/_search
25{
26  "explain": true, 
27  "query": {
28    "match": {
29        "title":"question"
30    }
31  }
32}

4 数据模型

Elasticsearch在性能方面有两个好处。它可以水平扩展,速度非常快。其中速度主要取决于:数据的存储方式。

4.1 索引阶段数据模型

索引文档时,它将通过三个步骤:character filters(字符过滤器),tokenizer(标记生成器)和token filters(标记过滤器)。它们用于规范化文档。
例如:一个文档

To be or not to be, that is the question.

1)可能实际存储为:
如果标点符号被删除且所有词项都是小写的:

to be or not to be that is the question

2)它也可以存储为:
如果应用了停用词过滤器,它将删除所有常用语言术语,例如:to,be,or,not,that,is,the。
仅剩下:

question

以上是索引部分。

4.2 搜索阶段数据模型

在搜索文档时会应用相同的步骤。查询也被过滤为character filters(字符过滤器),tokenizer(标记生成器)和token filters(标记过滤器)。
然后Elasticsearch正在搜索带有规范化词项的文档。 
Elasticsearch中的字段存储在倒排索引结构中,这使得快速获取匹配文档。

可以为每个字段定义特定过滤器。借助于analyzers实现定义。可以使用多个analyzers分词器分析字段以实现不同的目标。
例如:

1可以使用standard分词器逐字分词,
使用ik_max_word 细粒度分词,
使用ik_smart粗粒度分词。

然后在搜索阶段,您可以定义要扫描的字段,获得你想要的检索结果。
通过应用此行为,ElasticSearch可以比常规数据库更快地提供结果。

铭毅:模型的好坏除了提升检索效率,还能节省存储空间。

5 分片计划

5.1 我应该有多少分片和索引?

这是新手学习、实操Elasticsearch提出的最常见问题。
为什么会出现这个问题?只能在索引创建的最开始设置分片数。

所以答案真的取决于你拥有的数据集。根据经验,单分片最大应包含20-40 GB的数据。 Shards来自Apache Lucene。

考虑到Apache Lucene用于反向索引和快速搜索的所有结构和开销,划分小分片(例如100 MB或1 GB)是没有意义的。

Elastic顾问建议使用20-40 GB。请记住,分片不能进一步划分,并且始终驻留在单个节点上。这样大小的分片也可以很容易地移动到其他节点,或者如果需要,在集群内复制。具有此分片容量可以为您提供速度和内存消耗之间的折衷值。

当然,在您的特定情况下,性能指标可能显示不同的内容,因此请记住,这只是一个建议,您可能结合您的实际业务场景,希望实现其他性能目标。

5.2 实际分片注意事项

1)为了知道每个索引应该有多少分片,你可以简单地估计一下,通过将一些文档索引到一个临时索引中,看看它们消耗了多少内存,以及你希望在一段时间内有多少文档。时间指的:部分时间(在时间序列数据集中),或者全部时间(在静态数据集中)。

2)不要忘记,即使您错误配置了分片数或索引数,也可以始终将数据重新索引方式设置正确的数据,然后reindex操作完成数据迁移。

3)最后但并非最不重要的。您始终可以一次查询多个索引。
例如,您可以基于日期递增的滚动索引,并在一个查询中简单地询问上个月的所有日期的索引或者
别名实现一键查询。

1logstash_20190201_000001
2logstash_20190202_000002
3....
4logstash_20190228_000028

查询包含单分片的30个索引和包含30个分片的1个大索引的性能是一致的。

铭毅:结合业务数据量是分片的根本。

6.节点类型

Elasticsearch节点可以包括多个角色。角色包括:

  • Master:主节点,

  • Data:数据节点, 

  • Ingest:摄取节点, 

  • Coordinating-only:仅协调节点。

每个角色都有对应的用途。

6.1 主节点

作用:负责群集范围的设置和更改,例如创建或删除索引,添加或删除节点以及将分片分配给节点。
针对大数据量级规模的集群,(建议)每个集群中应至少包含3个候选主节点。系统会从所有符合主节点的节点中,选择一个节点作为主节点,其作用是执行群集范围的操作。另外两个节点纯粹是为了获得高可用性。
硬件要求:主节点对CPU,RAM和磁盘存储的要求相对较低。

6.2 数据节点

作用:用于存储和搜索数据。
硬件要求:数据节点对所有资源都有很高的要求:CPU,RAM和磁盘。您拥有的数据越多,硬件资源要求也就越高。

6.3 Ingest节点

作用:在实际索引发生之前,Ingest节点用于文档预处理。
Ingest节点拦截批量和索引查询,应用转换,然后将文档传递回索引或批量API。
硬件要求:低磁盘、中等RAM和高CPU,

6.4 仅协调节点

作用:客户端请求的负载平衡器。
它知道特定文档可以驻留的位置,并将搜索请求路由到对应节点。
【官方文档警告】
将过多的仅协调节点添加到群集会
增加整个群集的负担,因为所选主节点必须等待来自每个节点的群集状态更新的确认! 
不应过分夸大仅协调节点的好处 - 数据节点可以愉快地用于相同的目的。

硬件要求:低磁盘,中高速RAM和中高CPU。

6.5 配置大型集群的首选方法是什么?

以下是建议:
1) 三个主节点 - 维护集群状态和集群设置,
2) 两个仅协调节点 - 它们监听外部请求,并充当整个集群的智能负载平衡器,
3) 许多数据节点 - 取决于数据集需求,
4) 几个 Ingest节点(可选) - 如果您正在执行摄取管道并希望减轻其他节点对预处理文档的影响。
具体数字取决于您的特定用例+实际业务场景,并且
必须根据性能测试进行调整。

铭毅:需要根据实际业务场景、业务规模做分配。

7 小结

毕竟每个公司业务场景不一致,以上6个特性建议供选型参考。
实际中需要结合业务场景+官方文档+源代码做进一步优化。
翻译中,结合自己的实践做了部分微调+解读。

原文作者:Dariusz Mydlarz,系Elastic官方认证工程师。
原文地址:
http://t.cn/EVwtn1R

关注我

相关文章

1、渣渣菜鸡为什么要看 ElasticSearch 源码?

2、渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建

3、Elasticsearch 默认分词器

4、Elasticsearch 可用中分分词器

5、Elasticsearch 自定义分词器

6、全文搜索引擎 Elasticsearch 集群搭建入门教程

7、Elasticsearch 系列文章(三):ElasticSearch 集群监控

8、Elasticsearch 系列文章(四):ElasticSearch 单个节点监控

9、Elasticsearch 系列文章(五):ELK 实时日志分析平台环境搭建

10、教你如何在 IDEA 远程 Debug ElasticSearch

11、渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(上)

12、渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)

13、ElasticSearch 最佳性能优化

14、干货 | Elasticsearch方案选型必须了解的10件事!

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存