Elasticsearch
徐绍玉 Lv1

1. 什么是Elasticsearch?

你知道,为了搜索(和分析)

Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana 使您能够以交互方式探索、可视化和共享对数据的洞察,并管理和监控堆栈。Elasticsearch 是索引、搜索和分析魔法发生的地方。

Elasticsearch 为所有类型的数据提供近乎实时的搜索和分析。无论您拥有结构化或非结构化文本、数值数据还是地理空间数据,Elasticsearch 都可以以支持快速搜索的方式高效地存储和索引它。您可以超越简单的数据检索和聚合信息来发现数据中的趋势和模式。随着您的数据和查询量的增长,Elasticsearch 的分布式特性使您的部署能够随之无缝增长。

虽然并非所有问题都是搜索问题,但 Elasticsearch 提供了在各种用例中处理数据的速度和灵活性:

  • 向应用或网站添加搜索框
  • 存储和分析日志、指标和安全事件数据
  • 使用机器学习实时自动建模数据的行为
  • 使用 Elasticsearch 作为存储引擎自动化业务工作流
  • 使用 Elasticsearch 作为地理信息系统 (GIS) 管理、集成和分析空间信息
  • 使用 Elasticsearch 作为生物信息学研究工具存储和处理遗传数据

我们不断对人们使用搜索的新颖方式感到惊讶。但是,无论您的用例是否与其中之一类似,或者您正在使用 Elasticsearch 来解决新问题,您在 Elasticsearch 中处理数据、文档和索引的方式都是相同的。

1.1 数据输入:文档和索引

Elasticsearch 是一个分布式文档存储。Elasticsearch 不是将信息存储为列状数据的行,而是存储已序列化为 JSON 文档的复杂数据结构。当集群中有多个 Elasticsearch 节点时,存储的文档分布在整个集群中,并且可以从任何节点立即访问。

存储文档后,它会被编入索引,并且可以近乎实时地进行全面搜索——在1 秒内。Elasticsearch 使用一种称为倒排索引的数据结构,它支持非常快速的全文搜索。倒排索引列出出现在任何文档中的每个唯一单词,并标识每个单词出现在的所有文档。

索引可以被认为是文档的优化集合,每个文档都是字段的集合,这些字段是包含数据的键值对。默认情况下,Elasticsearch 索引每个字段中的所有数据,每个索引字段都有一个专用的、优化的数据结构。例如,文本字段存储在倒排索引中,数值和地理字段存储在 BKD 树中。使用每个字段的数据结构来组合和返回搜索结果的能力使 Elasticsearch 如此之快。

Elasticsearch 还具有无模式的能力,这意味着可以在不明确指定如何处理文档中可能出现的每个不同字段的情况下为文档编制索引。启用动态映射后,Elasticsearch 会自动检测并将新字段添加到索引中。这种默认行为使索引和探索数据变得容易——只需开始索引文档,Elasticsearch 就会检测并将布尔值、浮点和整数值、日期和字符串映射到适当的 Elasticsearch 数据类型。

但是,最终,您比 Elasticsearch 更了解您的数据以及您希望如何使用它。您可以定义规则来控制动态映射并显式定义映射以完全控制字段的存储和索引方式。

定义您自己的映射使您能够:

  • 区分全文字符串字段和精确值字符串字段
  • 执行特定于语言的文本分析
  • 优化部分匹配的字段
  • 使用自定义日期格式
  • 使用无法自动检测到的 数据类型geo_pointgeo_shape

为了不同的目的以不同的方式索引相同的字段通常很有用。例如,您可能希望将字符串字段索引为用于全文搜索的文本字段和用于排序或聚合数据的关键字字段。或者,您可以选择使用多个语言分析器来处理包含用户输入的字符串字段的内容。

在索引期间应用于全文字段的分析链也在搜索时使用。当您查询全文字段时,在索引中查找术语之前,查询文本会经过相同的分析。

1.2 信息输出:搜索和分析

虽然您可以将 Elasticsearch 用作文档存储并检索文档及其元数据,但真正的强大之处在于能够轻松访问构建在 Apache Lucene 搜索引擎库上的全套搜索功能。

Elasticsearch 提供了一个简单、一致的 REST API 来管理您的集群以及索引和搜索您的数据。出于测试目的,您可以直接从命令行或通过 Kibana 中的开发人员控制台轻松提交请求。在您的应用程序中,您可以将 Elasticsearch 客户端 用于您选择的语言:Java、JavaScript、Go、.NET、PHP、Perl、Python 或 Ruby。

搜索您的数据

Elasticsearch REST API 支持结构化查询、全文查询和将两者结合的复杂查询。结构化查询类似于您可以在 SQL 中构造的查询类型。例如,您可以搜索索引中的genderage字段并按字段employee对匹配项进行排序hire_date。全文查询查找与查询字符串匹配的所有文档,并按相关性排序返回它们——它们与您的搜索词的匹配程度。

除了搜索单个术语外,您还可以执行短语搜索、相似性搜索和前缀搜索,并获得自动完成建议。

有要搜索的地理空间数据或其他数字数据吗?Elasticsearch 在支持高性能地理和数值查询的优化数据结构中索引非文本数据。

您可以使用 Elasticsearch 的综合 JSON 样式查询语言 ( Query DSL )访问所有这些搜索功能。您还可以构建SQL 样式的查询以在 Elasticsearch 内部搜索和聚合本地数据,而 JDBC 和 ODBC 驱动程序支持广泛的第三方应用程序通过 SQL 与 Elasticsearch 交互。

分析您的数据

Elasticsearch 聚合使您能够构建复杂的数据摘要并深入了解关键指标、模式和趋势。聚合不仅可以找到众所周知的“大海捞针”,还可以回答以下问题:

  • 大海捞针有多少针?
  • 针的平均长度是多少?
  • 按制造商划分的针的中位数长度是多少?
  • 在过去的六个月中,每一年都向大海捞针添加了多少针?

您还可以使用聚合来回答更微妙的问题,例如:

  • 您最受欢迎的针头制造商是哪些?
  • 是否有任何异常或异常的针团?

因为聚合利用了用于搜索的相同数据结构,所以它们也非常快。这使您能够实时分析和可视化数据。您的报告和仪表板会随着数据的变化而更新,以便您可以根据最新信息采取行动。

更重要的是,聚合与搜索请求一起运行。您可以在单个请求中对相同数据同时搜索文档、过滤结果和执行分析。并且由于聚合是在特定搜索的上下文中计算的,因此您不仅会显示所有 70 号针的计数,还显示了与用户搜索条件匹配的 70 号针的计数——例如,所有尺寸 70不粘绣花针。

但是等等,还有更多

想要自动化时间序列数据的分析吗?您可以使用 机器学习功能创建数据中正常行为的准确基线并识别异常模式。通过机器学习,您可以检测:

  • 与值、计数或频率的时间偏差相关的异常
  • 统计稀有度
  • 某个群体成员的异常行为

最好的部分是?您无需指定算法、模型或其他与数据科学相关的配置即可执行此操作。

1.3 可扩展性和弹性:集群、节点和分片

Elasticsearch 旨在始终可用并根据您的需求进行扩展。它通过自然分布来做到这一点。您可以将服务器(节点)添加到集群以增加容量,Elasticsearch 会自动在所有可用节点之间分配您的数据和查询负载。无需大修您的应用程序,Elasticsearch 知道如何平衡多节点集群以提供可扩展性和高可用性。节点越多越好。

这是如何运作的?在幕后,Elasticsearch 索引实际上只是一个或多个物理分片的逻辑分组,其中每个分片实际上是一个独立的索引。通过将索引中的文档分布在多个分片中,并将这些分片分布在多个节点上,Elasticsearch 可以确保冗余,这既可以防止硬件故障,又可以在将节点添加到集群时增加查询容量。随着集群的增长(或缩小),Elasticsearch 会自动迁移分片以重新平衡集群。

有两种类型的分片:主分片和副本。索引中的每个文档都属于一个主分片。副本分片是主分片的副本。副本提供数据的冗余副本,以防止硬件故障并增加处理读取请求(如搜索或检索文档)的容量。

索引中的主分片数量在创建索引时是固定的,但副本分片的数量可以随时更改,而不会中断索引或查询操作。

这取决于……

关于分片大小和为索引配置的主分片数量,有许多性能考虑和权衡。分片越多,维护这些索引的开销就越大。分片大小越大,当 Elasticsearch 需要重新平衡集群时,移动分片所需的时间就越长。

查询大量小分片会使每个分片的处理速度更快,但更多查询意味着更多开销,因此查询较少数量的较大分片可能会更快。简而言之……视情况而定。

作为起点:

  • 旨在将平均分片大小保持在几 GB 到几十 GB 之间。对于具有基于时间的数据的用例,通常会看到 20GB 到 40GB 范围内的分片。
  • 避免大量碎片问题。一个节点可以容纳的分片数量与可用的堆空间成正比。作为一般规则,每 GB 堆空间的分片数应小于 20。

为您的用例确定最佳配置的最佳方法是 使用您自己的数据和查询进行测试

发生灾害时

出于性能原因,集群中的节点需要位于同一网络上。跨不同数据中心的节点平衡集群中的分片只需要太长时间。但是高可用性架构要求您避免将所有鸡蛋放在一个篮子里。在一个位置发生重大中断的情况下,另一个位置的服务器需要能够接管。无缝。答案?跨集群复制 (CCR)。

CCR 提供了一种将索引从主集群自动同步到可用作热备份的辅助远程集群的方法。如果主集群出现故障,辅助集群可以接管。您还可以使用 CCR 创建辅助集群,以便为您的用户提供地理位置邻近的读取请求。

跨集群复制是主动-被动的。主集群上的索引是活动的领导者索引,处理所有写请求。复制到辅助集群的索引是只读的跟随者。

护理和喂养

与任何企业系统一样,您需要工具来保护、管理和监控您的 Elasticsearch 集群。集成到 Elasticsearch 中的安全、监控和管理功能使您能够将Kibana 用作管理集群的控制中心。类似的特征数据汇总指标生命周期管理 可帮助您明智随着时间的推移管理您的数据。

2. 设置Elasticsearch

2.1 安装 Elasticsearch

Elasticsearch 以以下包格式提供:

Linux 和 MacOStar.gz档案:在 Linux 或 MacOS 上从存档安装 Elasticsearch

docker:使用 Docker 安装 Elasticsearch

2.2 配置 Elasticsearch

Elasticsearch 提供了良好的默认值,并且只需要很少的配置。可以使用集群更新设置API在正在运行的集群上更改大多数设置 。

配置文件应包含特定于节点的设置(例如node.name和 路径),或节点为了能够加入集群而需要的设置,例如cluster.namenetwork.host

Elasticsearch 有三个配置文件:

  • elasticsearch.yml 用于配置 Elasticsearch
  • jvm.options 用于配置 Elasticsearch JVM 设置
  • log4j2.properties 用于配置 Elasticsearch 日志记录

** 配置文件格式编辑

配置格式为YAML。以下是更改数据和日志目录路径的示例:

1
2
3
path:
data: /var/lib/elasticsearch
logs: /var/log/elasticsearch

设置也可以按如下方式展平:

1
2
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

在 YAML 中,您可以将非标量值格式化为序列:

1
2
3
4
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com

虽然不太常见,但您也可以将非标量值格式化为数组:

1
discovery.seed_hosts: ["192.168.1.10:9300", "192.168.1.11", "seeds.mydomain.com"]

集群和节点设置类型

集群和节点设置可以根据它们的配置方式进行分类:

  • 动态的

    您可以使用集群更新设置 API配置和更新正在运行的集群上的动态设置 。您还可以在未启动或关闭的节点上使用本地配置动态设置 elasticsearch.yml。使用集群更新设置 API 进行的更新可以是持久的,适用于集群重新启动,也可以是瞬态的,在集群重新启动后重置。您还可以通过null使用 API为其分配一个值来重置临时或持久设置。如果您使用多种方法配置相同的设置,Elasticsearch 会按以下优先顺序应用设置:瞬态设置持久设置elasticsearch.yml 环境默认设置值例如,您可以应用临时设置来覆盖永久设置或elasticsearch.yml设置。但是,对elasticsearch.yml 设置的更改不会覆盖已定义的瞬态或持久设置。最好使用集群更新设置 API 设置动态的、集群范围的设置,并且elasticsearch.yml仅用于本地配置。使用集群更新设置 API 可确保所有节点上的设置都相同。如果您不小心elasticsearch.yml在不同的节点上配置了不同的设置,则可能很难注意到差异。

  • 静止的

    静态设置只能在未启动或关闭的节点上使用 elasticsearch.yml.必须在集群中的每个相关节点上设置静态设置。

1. 重要的 Elasticsearch 配置

Elasticsearch 只需很少的配置即可开始使用,但在生产中使用集群之前必须考虑许多事项:

我们的Elastic Cloud服务会自动配置这些项目,默认情况下使您的集群做好生产准备。

** 路径设置**

Elasticsearch 将您索引的数据写入索引并将数据流写入data 目录。Elasticsearch 将自己的应用程序日志写入一个logs目录,其中包含有关集群运行状况和操作的信息。

对于Mac系统.tar.gzLinux的.tar.gz,和 的Windows.zip安装,data并且logs是子目录$ES_HOME默认。但是,$ES_HOME升级过程中存在删除风险的文件。

在生产中,我们强烈建议您将path.datapath.logsin 设置elasticsearch.yml$ES_HOME. 默认情况下,DockerDebianRPMmacOS HomebrewWindows .msi安装将数据和日志写入到外部位置$ES_HOME

为了避免错误,只有 Elasticsearch 应该打开目录中的path.data 文件。path.data从可能打开和锁定其文件的其他服务(例如防病毒程序或备份程序)中排除该目录。

支持path.datapath.logs值因平台而异:

Linux 和 macOS 安装支持 Unix 风格的路径:

1
2
3
path:
data: /var/data/elasticsearch
logs: /var/log/elasticsearch

多个数据路径

7.13.0 中已弃用。

如果需要,您可以在path.data. Elasticsearch 跨所有提供的路径存储节点的数据,但将每个分片的数据保存在同一路径上。

Elasticsearch 不会跨节点的数据路径平衡分片。单个路径中的高磁盘使用率会触发整个节点的高磁盘使用率水印。如果触发,即使节点的其他路径有可用磁盘空间,Elasticsearch 也不会向节点添加分片。如果您需要额外的磁盘空间,我们建议您添加新节点而不是额外的数据路径。

Linux 和 macOS 安装支持多个 Unix 风格的路径path.data

1
2
3
4
5
路径:
数据:
- /mnt/elasticsearch_1
- /mnt/elasticsearch_2
- /mnt/elasticsearch_3

集群名称设置

一个节点只有cluster.name在与集群中的所有其他节点共享时才能加入集群。默认名称是elasticsearch,但您应该将其更改为描述集群用途的适当名称。

1
cluster.name: logging-prod
1
2
警告:
不要在不同环境中重复使用相同的集群名称。否则,节点可能会加入错误的集群。

节点名称设置

Elasticsearchnode.name用作特定 Elasticsearch 实例的人类可读标识符。该名称包含在许多 API 的响应中。当 Elasticsearch 启动时,节点名称默认为机器的主机名,但可以在 elasticsearch.yml

1
node.name: prod-data-2

网络主机设置

默认情况下,Elasticsearch 只绑定到环回地址,例如127.0.0.1[::1]。这足以在单个服务器上运行一个或多个节点的集群进行开发和测试,但 弹性生产集群必须涉及其他服务器上的节点。有许多网络设置,但通常您需要配置的是network.host

1
network.host: 192.168.1.10
1
2
警告:
当您为 提供值时network.host,Elasticsearch 假定您正在从开发模式转移到生产模式,并将许多系统启动检查从警告升级到异常。查看开发模式和生产模式之间的差异 。

发现和集群形成设置

在进入生产之前配置两个重要的发现和集群形成设置,以便集群中的节点可以相互发现并选举一个主节点。

discovery.seed_hosts

开箱即用,无需任何网络配置,Elasticsearch将结合到现有的环回地址和扫描本地端口93009305与同一台服务器上运行的其他节点连接。此行为提供了无需进行任何配置的自动集群体验。

当您想与其他主机上的节点形成集群时,请使用 静态 discovery.seed_hosts设置。此设置提供集群中其他节点的列表,这些节点符合主节点条件并且可能处于活动状态且可联系以播种发现过程。此设置接受集群中所有符合主节点条件的节点的 YAML 序列或地址数组。每个地址可以是 IP 地址或通过 DNS 解析为一个或多个 IP 地址的主机名。

1
2
3
4
5
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
- [0:0:0:0:0:ffff:c0a8:10c]:9301
  • 端口是可选的,默认为9300,但可以被覆盖
  • 如果一个主机名解析为多个 IP 地址,该节点将尝试发现所有解析地址处的其他节点。
  • IPv6 地址必须用方括号括起来。

如果您的符合主节点的节点没有固定的名称或地址,请使用 替代主机提供程序来动态查找它们的地址。

cluster.initial_master_nodes

当您第一次启动 Elasticsearch 集群时, 集群引导步骤会确定在第一次选举中计票的主合格节点集。在开发模式下,没有配置发现设置,这一步由节点自己自动执行。

由于自动引导本质上不安全的,因此在生产模式下启动新集群时,您必须明确列出应在第一次选举中计算其选票的主合格节点。您可以使用cluster.initial_master_nodes设置来设置此列表 。

1
2
警告:
第一次成功形成集群后,cluster.initial_master_nodes从每个节点的配置中删除设置。重新启动集群或向现有集群添加新节点时,请勿使用此设置。
1
2
3
4
5
6
7
8
9
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
- [0:0:0:0:0:ffff:c0a8:10c]:9301
cluster.initial_master_nodes:
- master-node-a
- master-node-b
- master-node-c

通过它们的 标识初始主节点node.name,默认为它们的主机名。确保中的值 完全cluster.initial_master_nodes匹配node.name。如果您使用完全限定域名 (FQDN),例如master-node-a.example.com您的节点名称,则您必须使用此列表中的 FQDN。相反,如果node.name 是没有任何尾随限定符的裸主机名,则还必须省略cluster.initial_master_nodes.

堆大小设置

默认情况下,Elasticsearch 会根据节点的角色和总内存自动设置 JVM 堆大小 。我们建议为大多数生产环境使用默认大小。

自动堆大小调整需要捆绑的 JDK,或者如果使用自定义 JRE 位置,则需要 Java 14 或更高版本的 JRE。

如果需要,您可以通过手动设置 JVM 堆大小来覆盖默认 大小

JVM 堆转储路径设置

默认情况下,Elasticsearch 将 JVM 配置为将内存不足异常时的堆转储到默认数据目录。在RPMDebian软件包上,数据目录是/var/lib/elasticsearch. 在 Linux 和 MacOS以及Windows发行版上,该data目录位于 Elasticsearch 安装的根目录下。

如果此路径不适合接收堆转储,请修改中的 -XX:HeapDumpPath=...条目jvm.options

  • 如果指定目录,JVM 将根据正在运行的实例的 PID 为堆转储生成文件名。
  • 如果指定固定文件名而不是目录,则当 JVM 需要对内存不足异常执行堆转储时,该文件不得存在。否则,堆转储将失败。

GC 日志设置

默认情况下,Elasticsearch 启用垃圾收集 (GC) 日志。这些配置 jvm.options并输出到与 Elasticsearch 日志相同的默认位置。默认配置每 64 MB 轮换一次日志,最多可消耗 2 GB 的磁盘空间。

您可以使用JEP 158: Unified JVM Logging 中描述的命令行选项重新配置 JVM 日志 记录。除非您jvm.options直接更改默认文件,否则除了您自己的设置之外,还会应用 Elasticsearch 默认配置。要禁用默认配置,首先通过提供-Xlog:disable选项禁用日志记录 ,然后提供您自己的命令行选项。这将禁用所有JVM 日志记录,因此请务必查看可用选项并启用您需要的所有内容。

临时目录设置

默认情况下,Elasticsearch 使用启动脚本在系统临时目录正下方创建的私有临时目录。

在某些 Linux 发行版上,系统实用程序会清除/tmp最近未访问过的文件和目录。如果长时间不使用需要临时目录的功能,此行为会导致在 Elasticsearch 运行时删除私有临时目录。如果随后使用需要此目录的功能,则删除私有临时目录会导致问题。

如果您使用.deb.rpm包安装 Elasticsearch并在 下运行它systemd,则 Elasticsearch 使用的私有临时目录将被排除在定期清理之外。

如果您打算.tar.gz在 Linux 或 MacOS 上长时间运行发行版,请考虑为 Elasticsearch 创建一个专用临时目录,该目录不在将清除旧文件和目录的路径下。此目录应设置权限,以便只有运行 Elasticsearch 的用户才能访问它。然后,$ES_TMPDIR在启动 Elasticsearch 之前将环境变量设置 为指向该目录。

集群备份

在灾难中,快照可以防止永久性数据丢失。 快照生命周期管理是对集群进行定期备份的最简单方法。有关更多信息,请参阅备份集群

备份集群的唯一可靠且受支持的方法是拍摄快照。您不能通过复制其节点的数据目录来备份 Elasticsearch 集群。不支持从文件系统级备份恢复任何数据的方法。如果您尝试从这样的备份中恢复集群,它可能会失败并报告损坏或丢失文件或其他数据不一致,或者它可能会成功地丢失一些数据。

2. 安全设置

一些设置是敏感的,依靠文件系统权限来保护它们的值是不够的。对于这个用例,Elasticsearch 提供了一个密钥库和管理密钥库中设置的elasticsearch-keystore工具

只有一些设置被设计为从密钥库中读取。但是,密钥库没有阻止不受支持的设置的验证。向密钥库添加不受支持的设置会导致 Elasticsearch 无法启动。要查看密钥库中是否支持设置,请查找设置参考中的“安全”限定符。

所有对 keystore 的修改只有在重启 Elasticsearch 后才会生效。

这些设置,就像elasticsearch.yml配置文件中的常规设置一样,需要在集群中的每个节点上指定。目前,所有安全设置都是特定于节点的设置,在每个节点上必须具有相同的值。

可重新加载的安全设置

就像 中的设置值一样elasticsearch.yml,对密钥库内容的更改不会自动应用于正在运行的 Elasticsearch 节点。重新读取设置需要重新启动节点。但是,某些安全设置被标记为 可重新加载。此类设置可以重新读取并应用到正在运行的节点上

所有安全设置的值,无论是否可重新加载,在所有集群节点上都必须相同。在进行所需的安全设置更改后,使用bin/elasticsearch-keystore add命令调用:

1
POST _nodes / reload_secure_settings { "secure_settings_password" : "keystore-password" }

此 API 在每个集群节点上解密并重新读取整个密钥库,但仅应用可重新加载的安全设置。对其他设置的更改在下次重新启动之前不会生效。一旦调用返回,重新加载就完成了,这意味着依赖于这些设置的所有内部数据结构都已更改。一切都应该看起来好像设置从一开始就具有新值。

有可重新加载的安全设置:

默认情况下,当您拥有基本许可证或试用许可证时,将禁用 Elasticsearch 安全功能。要启用安全功能,请使用该xpack.security.enabled 设置。

您可以配置xpack.security设置以 启用匿名访问和执行消息身份验证、 设置文档和字段级安全性配置领域使用 SSL 加密通信以及 审核安全事件

所有这些设置都可以添加到elasticsearch.yml配置文件中,但您添加到 Elasticsearch 密钥库的安全设置除外。有关创建和更新 Elasticsearch 密钥库的更多信息,请参阅 安全设置

3. 集群级分片分配和路由设置

分片分配是将分片分配给节点的过程。这可能发生在初始恢复、副本分配、重新平衡或添加或删除节点时。

master 的主要作用之一是决定将哪些分片分配给哪些节点,以及何时在节点之间移动分片以重新平衡集群。

有许多设置可用于控制分片分配过程:

除此之外,还有一些其他杂项集群级别设置

集群级分片分配设置

您可以使用以下设置来控制分片分配和恢复:

  • cluster.routing.allocation.enable

    (动态) 为特定类型的分片启用或禁用分配:all -(默认)允许为各种分片分配分片。primaries - 只允许为主分片分配分片。new_primaries - 仅允许为新索引的主分片分配分片。none - 任何索引都不允许进行任何类型的分片分配。此设置不会影响重新启动节点时本地主分片的恢复。具有未分配主分片副本的重新启动节点将立即恢复该主分片,假设其分配 ID 与集群状态中的一个活动分配 ID 匹配。

  • cluster.routing.allocation.node_concurrent_incoming_recoveries

    (动态) 一个节点上允许发生多少并发传入分片恢复。传入恢复是在节点上分配目标分片(很可能是副本,除非分片正在重新定位)的恢复。默认为2.

  • cluster.routing.allocation.node_concurrent_outgoing_recoveries

    (动态) 一个节点上允许发生多少并发传出分片恢复。传出恢复是在节点上分配源分片(很可能是主分片,除非分片正在重新定位)的恢复。默认为2.

  • cluster.routing.allocation.node_concurrent_recoveries

    动态)设置cluster.routing.allocation.node_concurrent_incoming_recoveries和的 快捷方式cluster.routing.allocation.node_concurrent_outgoing_recoveries

  • cluster.routing.allocation.node_initial_primaries_recoveries

    动态)虽然副本的恢复是通过网络进行的,但节点重启后未分配的主节点的恢复使用来自本地磁盘的数据。这些应该很快,所以更多的初始主恢复可以在同一节点上并行发生。默认为4.

  • cluster.routing.allocation.same_shard.host

    动态)允许根据主机名和主机地址执行检查以防止在单个主机上分配同一分片的多个实例。默认为false,意味着默认情况下不执行任何检查。此设置仅适用于在同一台计算机上启动多个节点的情况。

分片重新平衡设置

当集群在每个节点上具有相同数量的分片而没有集中在任何节点上的任何索引的分片时,集群是平衡的。Elasticsearch 运行一个称为重新平衡的自动过程,它在集群中的节点之间移动分片以改善其平衡。重新平衡遵循所有其他分片分配规则,例如分配过滤强制意识,这可能会阻止它完全平衡集群。在这种情况下,重新平衡会努力在您配置的规则内实现最平衡的集群。如果您使用数据层然后 Elasticsearch 会自动应用分配过滤规则将每个分片放置在适当的层中。这些规则意味着平衡器在每一层内独立工作。

您可以使用以下设置来控制集群中分片的重新平衡:

  • cluster.routing.rebalance.enable

    (动态) 为特定类型的分片启用或禁用重新平衡:all -(默认)允许对所有类型的分片进行分片平衡。primaries - 只允许主分片的分片平衡。replicas - 仅允许对副本分片进行分片平衡。none - 任何索引都不允许进行任何类型的分片平衡。

  • cluster.routing.allocation.allow_rebalance

    (动态) 指定何时允许分片重新平衡:always - 始终允许重新平衡。indices_primaries_active - 仅当集群中的所有主节点都已分配时。indices_all_active -(默认)仅当集群中的所有分片(主分片和副本)都被分配时。

  • cluster.routing.allocation.cluster_concurrent_rebalance

    (动态) 允许控制在集群范围内允许多少并发分片重新平衡。默认为2. 请注意,由于集群中的不平衡,此设置仅控制并发分片重定位的数量。由于分配过滤强制感知,此设置不会限制分片重定位。

** 分片平衡启发式设置**

重新平衡的工作原理是根据每个节点的分片分配计算每个节点的权重,然后在节点之间移动分片以减少较重节点的权重并增加较轻节点的权重。当没有任何可能的分片移动可以使任何节点的权重与任何其他节点的权重接近超过可配置阈值时,集群就处于平衡状态。以下设置允许您控制这些计算的详细信息。

  • cluster.routing.allocation.balance.shard

    (动态) 定义节点上分配的分片总数的权重因子 (float)。默认为0.45f. 提高这个值会增加集群中所有节点的分片数量均衡的趋势。

  • cluster.routing.allocation.balance.index

    (动态) 定义在特定节点 (float) 上分配的每个索引的分片数的权重因子。默认为0.55f. 提高这个值会增加集群中所有节点每个索引的分片数量均衡的趋势。

  • cluster.routing.allocation.balance.threshold

    动态)应该执行的操作的最小优化值(非负浮点数)。默认为1.0f. 提高这个值将导致集群在优化分片平衡方面不那么积极。

无论平衡算法的结果如何,由于强制感知或分配过滤,可能不允许重新平衡。

基于磁盘的分片分配设置

基于磁盘的分片分配器确保所有节点都有足够的磁盘空间,而不会执行不必要的分片移动。它根据称为低水印高水印的一对阈值分配分片。它的主要目标是确保没有节点超过高水位线,或者至少任何此类超额只是暂时的。如果一个节点超过了高水位线,那么 Elasticsearch 将通过将它的一些分片移动到集群中的其他节点来解决这个问题。

节点时不时地暂时超过高水位线是正常的。

分配器还试图通过禁止将更多分片分配给超过低水位线的节点来使节点远离高水位线。重要的是,如果您的所有节点都超过了低水位线,则无法分配新的分片,并且 Elasticsearch 将无法在节点之间移动任何分片以将磁盘使用率保持在高水位线以下。您必须确保您的集群总共有足够的磁盘空间,并且始终有一些节点低于低水位线。

由基于磁盘的分片分配器触发的分片移动还必须满足所有其他分片分配规则,例如 分配过滤强制感知。如果这些规则过于严格,那么它们还可以防止控制节点磁盘使用所需的分片移动。如果您使用数据层,那么 Elasticsearch 会自动配置分配过滤规则以将分片放置在适当的层中,这意味着基于磁盘的分片分配器在每个层内独立工作。

如果节点填满其磁盘的速度比 Elasticsearch 将分片移动到其他地方的速度快,则存在磁盘完全填满的风险。为了防止这种情况,作为最后的手段,一旦磁盘使用量达到洪水阶段水印,Elasticsearch 将阻止写入受影响节点上的分片索引。它还将继续将分片移动到集群中的其他节点上。当受影响节点上的磁盘使用率低于高水位线时,Elasticsearch 会自动删除写入块。

集群中的节点使用不同数量的磁盘空间是正常的。集群的平衡仅取决于每个节点上的分片数量以及这些分片所属的索引。它既不考虑这些分片的大小,也不考虑每个节点上的可用磁盘空间,原因如下:

  • 磁盘使用情况会随着时间而变化。平衡单个节点的磁盘使用需要更多的分片移动,甚至可能浪费地撤消早期的移动。移动分片会消耗 I/O 和网络带宽等资源,并且可能会从文件系统缓存中驱逐数据。在可能的情况下,最好将这些资源用于处理您的搜索和索引编制。
  • 只要没有磁盘太满,每个节点上磁盘使用量均等的集群的性能通常不会比磁盘使用量不均的集群好。

分片分配意识

您可以使用自定义节点属性作为感知属性,让 Elasticsearch 在分配分片时将您的物理硬件配置考虑在内。如果 Elasticsearch 知道哪些节点位于同一物理服务器上、同一机架中或同一区域中,则它可以分发主分片及其副本分片,以最大程度地降低在发生故障时丢失所有分片副本的风险。

当使用动态 cluster.routing.allocation.awareness.attributes设置启用分片分配感知时 ,分片仅分配给为指定的感知属性设置了值的节点。如果使用多个感知属性,Elasticsearch 在分配分片时会分别考虑每个属性。

默认情况下,Elasticsearch 使用自适应副本选择 来路由搜索或 GET 请求。但是,由于存在分配感知属性,Elasticsearch 将更喜欢使用位于相同位置(具有相同感知属性值)的分片来处理这些请求。可以通过export ES_JAVA_OPTS="$ES_JAVA_OPTS -Des.search.ignore_awareness_attributes=true" 在属于集群的每个节点上指定系统属性来禁用此行为。

属性值的数量决定了在每个位置分配了多少分片副本。如果每个位置的节点数量不平衡并且有很多副本,则可能会留下未分配的副本分片。

启用分片分配意识

要启用分片分配感知:

  1. 使用自定义节点属性指定每个节点的位置。例如,如果您希望 Elasticsearch 将分片分布在不同的机架上,您可以设置一个rack_id在每个节点的elasticsearch.yml 配置文件中调用的意识属性。

    1
    node.attr.rack_id: rack_one

    您还可以在启动节点时设置自定义属性:

    1
    ./bin/elasticsearch -Enode.attr.rack_id=rack_one
  2. 通过cluster.routing.allocation.awareness.attributes每个主合格节点的elasticsearch.yml配置文件中进行设置,告诉 Elasticsearch 在分配分片时考虑一个或多个感知属性 。

    1
    cluster.routing.allocation.awareness.attributes: rack_id 

    将多个属性指定为逗号分隔的列表。

    您还可以使用 cluster-update-settings API 来设置或更新集群的感知属性。

在此示例配置中,如果您使用node.attr.rack_idset to启动两个节点 rack_one并创建一个具有 5 个主分片和每个主分片的 1 个副本的索引,则所有主分片和副本都将在两个节点之间分配。

如果您添加两个node.attr.rack_id设置为 的节点rack_two,Elasticsearch 会将分片移动到新节点,确保(如果可能)同一分片的两个副本不在同一个机架中。

如果rack_two失败并关闭其两个节点,默认情况下 Elasticsearch 会将丢失的分片副本分配给rack_one. 为了防止在同一位置分配特定分片的多个副本,您可以启用强制感知。

强迫意识

默认情况下,如果一个位置发生故障,Elasticsearch 会将所有丢失的副本分片分配给其余位置。虽然您可能在所有位置都有足够的资源来托管主分片和副本分片,但单个位置可能无法托管所有分片。

为了防止在发生故障时单个位置过载,您可以设置为cluster.routing.allocation.awareness.force不分配副本,直到另一个位置的节点可用。

集群级分片分配过滤

您可以使用集群级别的分片分配过滤器来控制 Elasticsearch 从任何索引分配分片的位置。这些集群范围的过滤器与按索引分配过滤分配感知结合应用

碎片分配过滤器可根据自定义节点的属性或内置 _name_host_ip_publish_ip_ip_host_id_tier属性。

这些cluster.routing.allocation设置是动态的,使实时索引能够从一组节点移动到另一组节点。只有在不破坏其他路由约束的情况下才可能重新定位分片,例如永远不要在同一节点上分配主分片和副本分片。

集群级分片分配过滤的最常见用例是当您想要停用节点时。要在关闭节点之前将分片移出节点,您可以创建一个过滤器,通过其 IP 地址排除节点:

1
2
3
4
5
6
PUT _cluster/settings
{
"transient" : {
"cluster.routing.allocation.exclude._ip" : "10.0.0.1"
}
}

集群分片限制

根据集群中的节点数量,集群中的分片数量存在软限制。这是为了防止可能无意中破坏集群稳定的操作。

此限制旨在作为安全网,而不是尺寸建议。您的集群可以安全支持的确切分片数量取决于您的硬件配置和工作负载,但在几乎所有情况下都应保持远低于此限制,因为默认限制设置得相当高。

如果操作(例如创建新索引、恢复索引的快照或打开关闭的索引)会导致集群中的分片数量超过此限制,则该操作将失败并显示指示分片限制的错误。

如果集群已经超过限制,由于节点成员的变化或设置的变化,所有创建或打开索引的操作都将失败,直到限制如下所述增加,或者关闭删除一些索引 以带来数量低于限制的碎片。

集群分片限制对于普通(非冻结)索引默认为每个非冻结数据节点 1,000 个分片,对于冻结索引每个冻结数据节点默认为 3000 个分片。所有开放索引的主分片和副本分片都计入限制,包括未分配的分片。例如,具有 5 个主分片和 2 个副本的开放索引计为 15 个分片。封闭索引不影响分片计数。

4. 跨集群复制设置

远程恢复设置

以下设置可用于对远程恢复期间传输的数据进行速率限制 :

  • ccr.indices.recovery.max_bytes_per_sec(动态)

    限制每个节点上的总入站和出站远程恢复流量。由于此限制适用于每个节点,但可能有许多节点同时执行远程恢复,因此远程恢复字节总数可能远高于此限制。如果您将此限制设置得太高,那么正在进行的远程恢复可能会消耗过多的带宽(或其他资源),这可能会破坏集群的稳定性。领导者和追随者集群都使用此设置。例如,如果20mb在领导者上设置为,则20mb/s即使追随者正在请求并且可以接受,领导者也只会发送给追随者60mb/s。默认为40mb.

高级远程恢复设置

可以设置以下专家设置来管理远程恢复消耗的资源:

  • ccr.indices.recovery.max_concurrent_file_chunks(动态)

    控制每次恢复可以并行发送的文件块请求数。由于多个远程恢复可能已经并行运行,因此增加此专家级设置可能仅在单个分片的远程恢复未达到配置的总入站和出站远程恢复流量的情况下有所帮助ccr.indices.recovery.max_bytes_per_sec。默认为5. 最大允许值为10

  • ccr.indices.recovery.chunk_size(动态)

    控制文件传输期间跟随者请求的块大小。默认为 1mb.

  • ccr.indices.recovery.recovery_activity_timeout(动态)

    控制恢复活动的超时时间。此超时主要适用于领导集群。在恢复过程中,leader 集群必须打开内存中的资源来向follower 提供数据。如果leader在这段时间内没有收到follower的recovery请求,就会关闭资源。默认为 60 秒。

  • ccr.indices.recovery.internal_action_timeout(动态)

    控制远程恢复过程中各个网络请求的超时时间。单个操作超时可能会导致恢复失败。默认为 60 秒。

4. 节点

任何时候启动 Elasticsearch 实例时,都在启动一个node。连接节点的集合称为集群。如果您正在运行 Elasticsearch 的单个节点,那么您将拥有一个由一个节点组成的集群。

默认情况下,集群中的每个节点都可以处理HTTP 和传输流量。传输层专门用于节点之间的通信;HTTP 层由 REST 客户端使用。

所有节点都知道集群中的所有其他节点,并且可以将客户端请求转发到适当的节点。

节点角色

您可以通过node.roles在 中设置来定义节点的角色elasticsearch.yml。如果您设置了node.roles,则节点只会被分配您指定的角色。如果您没有设置node.roles,节点将被分配以下角色:

  • master
  • data
  • data_content
  • data_hot
  • data_warm
  • data_cold
  • data_frozen
  • ingest
  • ml
  • remote_cluster_client
  • transform

如果设置了node.roles,请确保指定集群需要的每个节点角色。每个集群都需要以下节点角色:

  • master
  • data_contentdata_hotdata

一些 Elastic Stack 功能还需要特定的节点角色:

  • 跨集群搜索和跨集群复制需要该remote_cluster_client角色。
  • 堆栈监控和摄取管道需要该ingest角色。
  • Fleet、Elastic Security 应用程序和转换需要该transform角色。该remote_cluster_client角色还需要使用具有这些功能的跨集群搜索。
  • 机器学习功能,例如异常检测,需要这个ml角色。

随着集群的增长,特别是如果您有大型机器学习作业或连续转换,请考虑将符合主节点的专用节点与专用数据节点、机器学习节点和转换节点分开。

  • 主节点

    具有master角色的节点,使其有资格被 选为控制集群节点

  • 数据节点

    具有data角色的节点。数据节点保存数据并执行数据相关操作,例如 CRUD、搜索和聚合。具有data角色的节点可以填充任何专门的数据节点角色。

  • 摄取节点

    具有ingest角色的节点。摄取节点能够将 摄取管道应用于文档,以便在索引之前转换和丰富文档。对于繁重的摄取负载,使用专用摄取节点并且不包括ingest来自具有masterdata角色的节点的角色是有意义的。

  • 远程合格节点

    具有remote_cluster_client角色的节点,使其有资格充当远程客户端。

  • 机器学习节点

    具有ml角色的节点。如果要使用机器学习功能,集群中必须至少有一个机器学习节点。有关更多信息,请参阅 Elastic Stack 中的机器学习设置机器学习

  • 变换节点

    具有transform角色的节点。如果要使用转换,则集群中必须至少有一个转换节点。有关更多信息,请参阅 转换设置转换数据

1
2
3
4
5
6
协调节点
搜索请求或批量索引请求等请求可能涉及保存在不同数据节点上的数据。例如,搜索请求分两个阶段执行,这两个阶段由接收客户端请求的节点协调——协调节点。

在分散阶段,协调节点将请求转发给持有数据的数据节点。每个数据节点在本地执行请求并将其结果返回给协调节点。在收集阶段,协调节点将每个数据节点的结果缩减为单个全局结果集。

每个节点都是隐式的协调节点。这意味着具有显式空角色列表的node.roles节点将仅充当协调节点,不能禁用。因此,这样的节点需要有足够的内存和 CPU 才能处理收集阶段。

主节点

主节点负责轻量级集群范围的操作,例如创建或删除索引、跟踪哪些节点是集群的一部分以及决定将哪些分片分配给哪些节点。拥有一个稳定的主节点对于集群健康很重要。

任何不是仅投票节点的主合格节点都可以通过主选举过程选举成为主节点。

主节点必须有一个path.data目录,其内容在重启后仍然存在,就像数据节点一样,因为这是存储集群元数据的地方。集群元数据描述了如何读取存储在数据节点上的数据,因此如果丢失,则无法读取存储在数据节点上的数据。

专用主节点

被选中的主节点对集群的健康很重要 履行职责所需的资源。 If the elected master 节点因其他任务而过载,则集群将无法正常运行。 这 避免使用其他任务使 master 过载的最可靠方法是 将所有master-eligible节点配置为 专用master-eligible节点 只有 master角色,使他们能够专注于管理 簇。 符合主条件的节点仍将表现为 协调节点 将请求从客户端路由到 集群中的其他节点,但你应该 使用专用的主节点 以此目的。

一个小型或轻负载的集群可能运行良好,如果其符合主节点的节点 有其他角色和职责,但是一旦您的集群包含更多 与少数节点相比,使用专用的主节点通常更有意义 节点。

要创建一个专用的主节点,请设置:

1
node.roles: [ master ]

仅投票主合格节点

仅投票的主合格节点是参与 主选举, 但不会作为集群的 选举主节点。 特别是,仅投票节点可以充当决胜局 在选举中。

使用术语“符合条件的”来描述一个 仅投票节点,因为这样的节点实际上没有资格成为主节点 根本。 这个术语是历史的不幸后果: 主合格节点是那些参与选举并执行的节点 集群状态发布期间的某些任务,仅投票节点具有

要将符合主节点的节点配置为仅投票节点,请包括 mastervoting_only在角色列表中。 例如创建一个仅投票数据 节点:

1
node.roles: [ data, master, voting_only ]
1
2
警告
只有具有 master角色可以被标记为具有 voting_only角色。

高可用性 (HA) 集群需要至少三个符合主节点条件的节点,在 其中至少有两个不是仅投票节点。 这样的集群将能够 即使其中一个节点发生故障,也会选择一个主节点。

仅投票主合格节点也可以填补集群中的其他角色。 例如,一个节点可能既是数据节点又是仅投票的主节点 节点。 一个 专门的 投票,仅主节点的资格是,只有投票 在集群中不填充其他角色的符合主节点的节点。 创建一个 专用的仅投票主合格节点,设置:

1
node.roles: [ master, voting_only ]

数据节点

数据节点保存包含已编入索引的文档的分片。 数据 节点处理数据相关的操作,如 CRUD、搜索和聚合。 这些操作是 I/O 密集型、内存密集型和 CPU 密集型的。 重要的是要 监控这些资源并在它们过载时添加更多数据节点。

拥有专用数据节点的主要好处是主节点的分离 和数据角色。

要创建专用数据节点,请设置:

1
node.roles: [ data ]

在多层部署架构中,您使用专门的数据角色来 将数据节点分配到特定层: data_content, data_hot, data_warm, data_cold, 或者 data_frozen. 一个节点可以属于多个层,但一个节点 具有专用数据角色之一的不能具有通用数据角色 data角色。

内容数据节点

内容数据节点容纳用户创建的内容。 它们支持像 CRUD 这样的操作, 搜索和聚合。

要创建专用内容节点,请设置:

1
node.roles: [ data_content ]

热点数据节点

热数据节点在进入 Elasticsearch 时存储时间序列数据。热层必须快速读取和写入,并且需要更多的硬件资源(例如 SSD 驱动器)。

要创建专用热节点,请设置:

1
node.roles: [ data_hot ]

暖数据节点

暖数据节点存储不再定期更新但仍在查询的索引。查询量的频率通常低于索引处于热层时的频率。性能较低的硬件通常可用于此层中的节点。

要创建专用的暖节点,请设置:

1
node.roles: [ data_warm ]

冷数据节点

冷数据节点存储访问频率较低的只读索引。此层使用性能较低的硬件,并且可以利用可搜索的快照索引来最小化所需的资源。

要创建专用冷节点,请设置:

1
node.roles: [ data_cold ]

冻结数据节点

冻结层专门存储部分安装的索引。我们建议您在冻结层中使用专用节点。

要创建专用的冻结节点,请设置:

1
node.roles: [ data_frozen ]

摄取节点

摄取节点可以执行由一个或多个摄取处理器组成的预处理管道。根据摄取处理器执行的操作类型和所需资源,拥有仅执行此特定任务的专用摄取节点可能是有意义的。

要创建专用摄取节点,请设置:

1
node.roles: [ ingest ]

仅协调节点

如果您取消了处理主职责、保存数据和预处理文档的能力,那么您就剩下一个只能路由请求、处理搜索减少阶段和分发批量索引的协调节点。本质上,仅协调节点的行为就像智能负载均衡器。

通过从数据和符合主节点的节点卸载协调节点角色,仅协调节点可以使大型集群受益。他们加入集群并接收完整的集群状态,就像其他每个节点一样,他们使用集群状态将请求直接路由到适当的地方。

1
node.roles: [ ]

远程合格节点

远程合格节点充当跨集群客户端并连接到 远程集群。连接后,您可以使用跨集群搜索来搜索远程集群。您还可以使用跨集群复制在集群之间同步数据。

1
node.roles: [ remote_cluster_client ]

机器学习节点

机器学习节点运行作业并处理机器学习 API 请求。有关更多信息,请参阅 机器学习设置

remote_cluster_client角色是可选的,但强烈推荐。否则,在机器学习作业或数据馈送中使用时,跨集群搜索将失败。如果您在异常检测作业中使用跨集群搜索,则remote_cluster_client所有符合主节点条件的节点上也需要该角色。否则,数据馈送将无法启动。

要创建专用机器学习节点,请设置:

1
node.roles: [ ml, remote_cluster_client]

变换节点

转换节点运行转换并处理转换 API 请求。有关更多信息,请参阅转换设置

要创建专用变换节点,请设置:

1
node.roles: [ transform, remote_cluster_client ]

改变节点的角色

每个数据节点在磁盘上维护以下数据:

  • 分配给该节点的每个分片的分片数据,
  • 与分配给该节点的每个分片对应的索引元数据,以及
  • 集群范围的元数据,例如设置和索引模板。

同样,每个符合主节点的节点在磁盘上维护以下数据:

  • 集群中每个索引的索引元数据,以及
  • 集群范围的元数据,例如设置和索引模板。

每个节点在启动时检查其数据路径的内容。如果它发现意外数据,它将拒绝启动。这是为了避免导入可能导致红色集群运行状况的不需要的悬空索引。更准确地说,没有data角色的节点在启动时如果在磁盘上找到任何分片数据将拒绝启动,而没有角色masterdata角色的节点如果在启动时在磁盘上有任何索引元数据将拒绝启动。

可以通过调整其elasticsearch.yml文件并重新启动它来更改节点的角色 。这称为重新调整节点的用途。为了满足上述对意外数据的检查,您必须执行一些额外的步骤来准备节点,以便在没有datamaster角色的情况下启动节点时重新调整用途。

  • 如果您想通过删除data角色来重新调整数据节点的用途,那么您应该首先使用分配过滤器将所有分片数据安全地迁移到集群中的其他节点上。
  • 如果您想重新调整节点的用途,使其既没有data也没有master角色,那么最简单的方法是启动一个带有空数据路径和所需角色的全新节点。您可能会发现首先使用分配过滤器将分片数据迁移到集群中的其他位置是最安全的 。

如果无法执行这些额外步骤,那么您可以使用该elasticsearch-node repurpose工具删除任何阻止节点启动的多余数据。

节点数据路径设置

path.data

每个数据和主节点都需要访问数据目录,其中将存储分片、索引和集群元数据。的path.data默认$ES_HOME/data,但可以在被配置elasticsearch.yml的配置文件的绝对路径或相对于一路径$ES_HOME如下:

1
path.data:  /var/elasticsearch/data

像所有节点设置一样,它也可以在命令行中指定为:

1
./bin/elasticsearch -Epath.data=/var/elasticsearch/data

5. 网络

每个 Elasticsearch 节点都有两个不同的网络接口。客户端使用其HTTP 接口向 Elasticsearch 的 REST API 发送请求,但节点使用传输接口与其他节点通信。传输接口还用于与远程集群的通信 ,并由已弃用的 Java 传输客户端使用

您可以使用这些network.*设置同时配置这两个接口 。如果您有一个更复杂的网络,您可能需要使用http.*transport.* 设置独立配置接口。在可能的情况下,使用network.*适用于两个接口的设置来简化您的配置并减少重复。

默认情况下 Elasticsearch 只绑定到localhost这意味着它不能被远程访问。这种配置对于由一个或多个运行在同一主机上的节点组成的本地开发集群来说已经足够了。要形成跨多个主机的集群,或者远程客户端可以访问的集群,您必须调整一些 网络设置,例如network.host.

1
2
小心网络配置!
永远不要将未受保护的节点暴露给公共互联网。如果这样做,您就允许世界上的任何人下载、修改或删除集群中的任何数据。

将 Elasticsearch 配置为绑定到非本地地址会将一些警告转换为致命异常。如果节点在配置其网络设置后拒绝启动,则您必须在继续之前解决记录的异常。

常用网络设置

大多数用户只需要配置以下网络设置。

  • network.host

    (静态) 为 HTTP 和传输流量设置此节点的地址。该节点将绑定到该地址,并将其用作其发布地址。接受 IP 地址、主机名或特殊值。默认为_local_.

  • http.port

    静态)为 HTTP 客户端通信绑定的端口。接受单个值或范围。如果指定了范围,则节点将绑定到范围内的第一个可用端口。默认为9200-9300.

  • transport.port

    静态)为节点之间的通信绑定的端口。接受单个值或范围。如果指定了范围,则节点将绑定到范围内的第一个可用端口。在每个符合主节点的节点上,将此设置设置为单个端口,而不是范围。默认为9300-9400.

更多网络配置参考官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html

6. 缓存

当针对一个索引或多个索引运行搜索请求时,每个涉及的分片在本地执行搜索并将其本地结果返回给协调节点协调节点将这些分片级别的结果组合成一个“全局”结果集。

分片级请求缓存模块在每个分片上缓存本地结果。这允许经常使用(并且可能很重)的搜索请求几乎立即返回结果。请求缓存非常适合日志用例,其中只有最新的索引正在被主动更新——旧索引的结果将直接从缓存中提供。

默认情况下,请求缓存只会缓存搜索请求 where 的结果size=0,所以它不会缓存hits,但会缓存hits.total聚合建议

大多数使用的查询now(请参阅Date Math)无法缓存。

使用非确定性 API 调用的脚本查询,例如 缓存Math.random()或未new Date()缓存。

缓存失效

缓存是智能的——它保持与未缓存搜索相同的近乎实时的承诺。

每当分片刷新以获取对文档的更改或更新映射时,缓存的结果都会自动失效。换句话说,您将始终从缓存中获得与未缓存搜索请求相同的结果。

刷新间隔越长,即使文档发生更改,缓存条目保持有效的时间就越长。如果缓存已满,则将逐出最近最少使用的缓存键。

缓存可以通过clear-cacheAPI手动过期:

1
POST / my-index-000001,my-index-000002 / _cache / clear ? 请求=真 

启用和禁用缓存

默认情况下启用缓存,但可以在创建新索引时禁用,如下所示:

1
PUT / my-index-000001 { "settings" : { "index.requests.cache.enable" : false } } 

缓存键

整个 JSON 主体用作缓存键。这意味着如果 JSON 发生变化——例如,如果键以不同的顺序输出——那么缓存键将不会被识别。

大多数 JSON 库都支持规范模式,以确保 JSON 密钥始终以相同的顺序发出。可以在应用程序中使用这种规范模式来确保请求始终以相同的方式序列化。

缓存设置

缓存在节点级别进行管理,并具有默认的最大1% 堆大小。这可以在config/elasticsearch.yml文件中更改:

1
indices.requests.cache.size: 2%

此外,您可以使用该indices.requests.cache.expire设置为缓存结果指定 TTL,但没有理由这样做。请记住,刷新索引时,陈旧的结果会自动失效。提供此设置只是为了完整起见。

监控缓存使用情况

缓存的大小(以字节为单位)和驱逐的数量可以通过索引查看,使用indices-statsAPI:

1
GET /_stats/request_cache?human

7. 其他设置

断路器设置

Elasticsearch 包含多个断路器,用于防止操作导致 OutOfMemoryError。每个断路器指定它可以使用多少内存的限制。此外,还有一个父级断路器,用于指定可跨所有断路器使用的内存总量。

发现和集群形成设置

参考官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery-settings.html

字段数据缓存设置

缓存中的条目构建起来很昂贵,因此默认行为是将缓存加载到内存中。默认缓存大小不受限制,这会导致缓存不断增长,直到达到现场数据断路器设置的限制。可以配置此行为。

如果设置了缓存大小限制,缓存将开始清除缓存中最近最少更新的条目。此设置可以自动避免断路器限制,代价是根据需要重建缓存。

如果达到断路器限制,将阻止进一步增加缓存大小的请求。在这种情况下,您应该手动清除缓存

  • indices.fielddata.cache.size

    静态)字段数据缓存的最大大小,例如38%节点堆空间,或绝对值,例如12GB。默认为无界。如果选择设置它,它应该小于现场数据断路器限制。

索引缓冲区设置

索引缓冲区用于存储新索引的文档。当它填满时,缓冲区中的文档被写入磁盘上的一个段。它在节点上的所有分片之间进行划分。

以下设置是静态的,必须在集群中的每个数据节点上进行配置:

  • indices.memory.index_buffer_size

    静态)接受百分比或字节大小值。它默认为10%,这意味着10%分配给节点的总堆中的将用作所有分片共享的索引缓冲区大小。

  • indices.memory.min_index_buffer_size

    (静态) 如果index_buffer_size指定为百分比,则此设置可用于指定绝对最小值。默认为48mb.

  • indices.memory.max_index_buffer_size

    (静态) 如果index_buffer_size指定为百分比,则此设置可用于指定绝对最大值。默认为无界。

监控设置

默认情况下,启用 Elasticsearch 监控功能,但禁用数据收集。要启用数据收集,请使用xpack.monitoring.collection.enabled设置。

除非另有说明,否则可以使用cluster-update-settings API在实时集群上动态更新这些设置。

要调整如何监控数据显示在监控界面,配置 xpack.monitoring设置kibana.yml。要控制如何从 Logstash 收集监控数据,请在logstash.yml.

有关更多信息,请参阅监控集群

节点查询缓存设置

过滤上下文中使用的查询结果缓存在节点查询缓存中,以便快速查找。每个节点有一个查询缓存,由所有分片共享。缓存使用 LRU 驱逐策略:当缓存已满时,将驱逐最近最少使用的查询结果,为新数据让路。您无法检查查询缓存的内容。

在过滤器上下文之外使用的术语查询和查询不符合缓存条件。

默认情况下,缓存最多可容纳 10000 个查询,最多占总堆空间的 10%。为了确定查询是否符合缓存条件,Elasticsearch 维护了一个查询历史记录来跟踪出现的情况。

如果一个段包含至少 10000 个文档,并且该段至少占分片总文档的 3%,则缓存是在每个段的基础上完成的。因为缓存是按段进行的,合并段会使缓存的查询无效。

以下设置是静态的,必须在集群中的每个数据节点上进行配置:

  • indices.queries.cache.size

    静态)控制过滤器缓存的内存大小。接受百分比值(如5%)或精确值(如 )512mb。默认为10%.

以下设置是可以在每个索引的基础上配置的索引设置。只能在索引创建时或 关闭索引上设置

  • index.queries.cache.enabled

    (静态) 控制是否启用查询缓存。接受true(默认)或 false

搜索设置

可以设置以下专家设置来管理全局搜索和聚合限制。

  • indices.query.bool.max_clause_count

    静态,整数)Lucene BooleanQuery 可以包含的最大子句数。默认为1024.此设置限制了 Lucene BooleanQuery 可以拥有的子句数量。默认值 1024 相当高,通常应该足够了。这个限制不仅会影响 Elasticsearchsbool查询,很多其他的查询也会在内部重写为 Lucene 的 BooleanQuery。设置限制是为了防止搜索变得过大并占用过多的 CPU 和内存。如果您正在考虑增加此设置,请确保您已用尽所有其他选项以避免必须这样做。较高的值会导致性能下降和内存问题,尤其是在负载高或资源少的集群中。

  • search.max_buckets

    ( Dynamic , integer)单个响应中允许的最大聚合桶数。默认为 65,536。尝试返回超过此限制的请求将返回错误。

  • indices.query.bool.max_nested_depth

    静态,整数)布尔查询的最大嵌套深度。默认为20.此设置限制了 bool 查询的嵌套深度。布尔查询的深层嵌套可能会导致堆栈溢出。

快照生命周期管理设置

  • slm.history_index_enabled

    ( Static , Boolean) 控制 SLM 是否将作为 SLM 策略的一部分所采取的操作的历史记录记录到slm-history-*索引中。默认为true.

  • slm.retention_schedule

    ( Dynamic , cron scheduler value ) 控制保留任务的运行时间。可以是定期或绝对时间表。支持cron 调度程序支持的所有值。默认为每天凌晨 1:30 UTC: 0 30 1 * * ?

  • slm.retention_duration

    ( Dynamic , time value ) 限制 SLM 应该花多长时间删除旧快照。默认为一小时:1h.

  • repositories.url.allowed_urls *标志云*

    (静态) 指定可以从中恢复快照的只读 URL 存储库

线程池

一个节点使用多个线程池来管理内存消耗。与许多线程池相关联的队列使挂起的请求能够被保留而不是被丢弃。

有几个线程池,但重要的包括:

  • generic

    对于通用操作(例如,后台节点发现)。线程池类型是scaling.

  • search

    用于计数/搜索/建议操作。线程池类型 fixed_auto_queue_size的大小为,初始队列大小为 。 int((# of allocated processors * 3) / 2) + 1``1000

  • search_throttled

    对于计数/搜索/建议/获取操作search_throttled indices。线程池类型fixed_auto_queue_size的大小为1,初始队列大小为100

  • get

    用于获取操作。线程池类型fixed 的大小为# of allocated processors,queue_size 为1000

  • analyze

    用于分析请求。线程池类型fixed大小为1,队列大小为16

  • write

    对于单文档索引/删除/更新和批量请求。线程池类型fixed的大小为# of allocated processors,queue_size 为10000。此池的最大大小为 1 + # of allocated processors.

  • snapshot

    用于快照/恢复操作。线程池类型scaling的保活时间为5m,最大为。 min(5, (# of allocated processors) / 2)

更多线程池配置参考官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html

观察着设置

您可以配置 Watcher 设置以设置 Watcher 并通过电子邮件SlackPagerDuty发送通知 。

所有这些设置都可以添加到elasticsearch.yml配置文件中,但您添加到 Elasticsearch 密钥库的安全设置除外。有关创建和更新 Elasticsearch 密钥库的更多信息,请参阅 安全设置。还可以使用集群更新设置 API集群更新动态设置

您可以在 中配置以下 Slack 通知设置 elasticsearch.yml。有关通过 Slack 发送通知的更多信息,请参阅配置 Slack 操作

您可以在 elasticsearch.yml. 有关使用通知在 Jira 中创建问题的更多信息,请参阅配置 Jira 操作

高级配置

通常不建议修改高级设置,这可能会对性能和稳定性产生负面影响。在大多数情况下,建议使用 Elasticsearch 提供的默认值。

如果需要,您可以通过添加自定义选项文件(首选)或设置ES_JAVA_OPTS环境变量来覆盖默认 JVM 选项。

默认情况下,Elasticsearch 会根据节点的角色和总内存自动设置 JVM 堆大小 。对于大多数生产环境,建议使用默认大小。

2.3 重要系统配置

理想情况下,Elasticsearch 应该在服务器上单独运行并使用所有可用资源。为此,您需要将操作系统配置为允许运行 Elasticsearch 的用户访问比默认允许更多的资源。

默认情况下,Elasticsearch 假定您在开发模式下工作。如果上述任何设置未正确配置,则会在日志文件中写入警告,但您将能够启动和运行 Elasticsearch 节点。

一旦您配置了类似 的网络设置network.host,Elasticsearch 就会假定您正在进入生产环境,并将上述警告升级为异常。这些异常将阻止您的 Elasticsearch 节点启动。这是一项重要的安全措施,可确保您不会因为服务器配置错误而丢失数据。

1. 配置系统设置

在 Linux 系统上,ulimit可用于临时更改资源限制。通常需要root在切换到将运行 Elasticsearch 的用户之前设置限制。例如,要将打开的文件句柄数 ( ulimit -n) 设置为 65,536,您可以执行以下操作:

1
2
3
sudo su  
ulimit -n 65535
su elasticsearch

/etc/security/limits.conf

在 Linux 系统上,可以通过编辑/etc/security/limits.conf文件为特定用户设置永久限制。要将用户的最大打开文件数设置elasticsearch为 65,535,请将以下行添加到limits.conf文件中:

1
elasticsearch  -  nofile  65535

2. 禁用交换

大多数操作系统尝试将尽可能多的内存用于文件系统缓存,并急切地换出未使用的应用程序内存。这可能会导致部分 JVM 堆甚至其可执行页面被换出到磁盘。

交换对性能和节点稳定性非常不利,应该不惜一切代价避免。它可能导致垃圾收集持续几分钟而不是几毫秒,并可能导致节点响应缓慢甚至与集群断开连接。在弹性分布式系统中,让操作系统杀死节点更有效。

有三种方法可以禁用交换。首选选项是完全禁用交换。如果这不是一个选项,则是否更喜欢最小化交换与内存锁定取决于您的环境。

禁用所有交换文件

通常 Elasticsearch 是唯一运行在机器上的服务,它的内存使用由 JVM 选项控制。应该不需要启用交换。

在 Linux 系统上,您可以通过运行以下命令暂时禁用交换:

1
sudo swapoff -a

这不需要重新启动 Elasticsearch。

要永久禁用它,您需要编辑/etc/fstab文件并注释掉包含单词swap.

配置 swappiness

Linux 系统上可用的另一个选项是确保将 sysctl 值 vm.swappiness设置为1。这减少了内核交换的倾向,并且在正常情况下不应该导致交换,同时仍然允许整个系统在紧急情况下交换。

3. 文件描述符

Elasticsearch使用了很多文件描述符或文件句柄。耗尽文件描述符可能是灾难性的,并且很可能会导致数据丢失。确保将运行 Elasticsearch 的用户的打开文件描述符数量限制增加到 65,536 或更高。

对于.zip.tar.gz包,ulimit -n 65535在启动 Elasticsearch 之前设置为 root,或者设置nofile65535in /etc/security/limits.conf

在 macOS 上,您还必须将 JVM 选项传递-XX:-MaxFDLimit 给 Elasticsearch,以便它利用更高的文件描述符限制。

RPM 和 Debian 软件包已将文件描述符的最大数量默认为 65535,不需要进一步配置。

您可以max_file_descriptors使用Nodes stats API检查每个节点的配置,使用:

1
GET _nodes / stats / process ?filter_path = **.max_file_descriptors 

4. 虚拟内存

Elasticsearchmmapfs默认使用一个目录来存储它的索引。操作系统对 mmap 计数的默认限制可能太低,这可能会导致内存不足异常。

在 Linux 上,您可以通过运行以下命令来增加限制 root

1
sysctl -w vm.max_map_count=262144

要永久设置此值,请更新 中的vm.max_map_count设置 /etc/sysctl.conf。要在重新启动后进行验证,请运行sysctl vm.max_map_count.

5. 线程数

Elasticsearch 使用多个线程池来进行不同类型的操作。重要的是它能够在需要时创建新线程。确保Elasticsearch 用户可以创建的线程数至少为 4096。

这可以通过ulimit -u 4096在启动 Elasticsearch 之前设置为 root来完成,或者设置nproc4096in /etc/security/limits.conf

作为服务运行时的包分发systemd将自动配置 Elasticsearch 进程的线程数。不需要额外的配置。

6. DNS 缓存设置

Elasticsearch 运行时有一个安全管理器。有了安全管理器,JVM 默认会无限期缓存正主机名解析,默认缓存负主机名解析 10 秒。Elasticsearch 使用默认值覆盖此行为,将正查找缓存 60 秒,并将负查找缓存 10 秒。这些值应该适用于大多数环境,包括 DNS 解析随时间变化的环境。如果没有,你可以编辑值es.networkaddress.cache.ttl,并es.networkaddress.cache.negative.ttlJVM选项。需要注意的是价值 networkaddress.cache.ttl=networkaddress.cache.negative.ttl=Java安全策略由Elasticsearch忽略,除非你删除的设置 es.networkaddress.cache.ttles.networkaddress.cache.negative.ttl

7. JNA 临时目录未挂载noexec

Elasticsearch 使用 Java Native Access (JNA) 库来执行一些与平台相关的本机代码。在 Linux 上,支持此库的本机代码在运行时从 JNA 存档中提取。此代码被提取到 Elasticsearch 临时目录,该目录默认为 的子目录, /tmp并且可以使用ES_TMPDIR变量进行配置。或者,可以使用 JVM 标志来控制此位置 -Djna.tmpdir=<path>。由于本机库作为可执行文件映射到 JVM 虚拟地址空间中,因此不得使用此代码提取到的位置的底层挂载点进行挂载,noexec因为这会阻止 JVM 进程将此代码映射为可执行文件。在一些强化的 Linux 安装中,这是默认的挂载选项/tmp. 底层挂载被挂载的一个迹象noexec是,在启动时 JNA 将无法加载,java.lang.UnsatisfiedLinkerError但会出现一条异常消息failed to map segment from shared object。请注意,异常消息可能因 JVM 版本而异。此外,依赖于通过 JNA 执行本机代码的 Elasticsearch 组件将失败并显示消息,表明它是because JNA is not available. 如果您看到此类错误消息,则必须重新挂载用于 JNA 的临时目录才能不使用noexec.

8. TCP 重传超时

每对 Elasticsearch 节点通过多个 TCP 连接进行通信,这些 TCP 连接 保持打开状态,直到其中一个节点关闭或节点之间的通信因底层基础设施故障而中断。

TCP 通过隐藏通信应用程序的临时网络中断,在偶尔不可靠的网络上提供可靠的通信。在通知发件人任何问题之前,您的操作系统会多次重新传输任何丢失的消息。Elasticsearch 必须等待重传发生,并且只有在操作系统决定放弃时才能做出反应。因此,用户还必须等待一系列重传完成。

大多数 Linux 发行版默认重新传输任何丢失的数据包 15 次。重传会呈指数衰减,因此这 15 次重传需要 900 多秒才能完成。这意味着 Linux 需要花费数分钟才能使用此方法检测网络分区或故障节点。Windows 默认只有 5 次重新传输,这对应于大约 6 秒的超时。

Linux 默认允许通过网络进行通信,这些网络可能会经历很长时间的丢包,但这种默认设置对于大多数 Elasticsearch 安装使用的高质量网络来说是过度的,甚至是有害的。当集群检测到节点故障时,它会通过重新分配丢失的分片、重新路由搜索以及可能选择新的主节点来做出反应。高可用集群必须能够及时发现节点故障,这可以通过减少允许的重传次数来实现。与远程集群的连接 也应该比 Linux 默认允许的更快地检测故障。因此 Linux 用户应该减少 TCP 重传的最大次数。

您可以5通过运行以下命令来减少 TCP 重传的最大数量root。五次重传对应于大约六秒的超时。

1
sysctl -w net.ipv4.tcp_retries2=5

要永久设置此值,请更新 中的net.ipv4.tcp_retries2设置 /etc/sysctl.conf。要在重新启动后进行验证,请运行 sysctl net.ipv4.tcp_retries2.

Elasticsearch 还实现了自己的内部健康检查,其超时时间比 Linux 上的默认重传超时要短得多。由于这些是应用程序级别的健康检查,因此它们的超时必须考虑到应用程序级别的影响,例如垃圾收集暂停。您不应减少与这些应用程序级健康检查相关的任何超时。

您还必须确保您的网络基础设施不会干扰节点之间的长期连接,即使这些连接看起来是空闲的。在达到一定年龄时断开连接的设备是 Elasticsearch 集群问题的常见来源,不得使用。

2.4 Bootstrap 检查

总的来说,我们有很多用户遇到意外问题的经验,因为他们没有配置 重要的设置。在以前版本的 Elasticsearch 中,其中一些设置的错误配置被记录为警告。可以理解,用户有时会错过这些日志消息。为了确保这些设置得到应有的关注,Elasticsearch 在启动时进行了引导检查。

这些引导程序检查会检查各种 Elasticsearch 和系统设置,并将它们与 Elasticsearch 操作安全的值进行比较。如果 Elasticsearch 处于开发模式,则任何失败的引导程序检查都会在 Elasticsearch 日志中显示为警告。如果 Elasticsearch 处于生产模式,任何失败的引导程序检查都会导致 Elasticsearch 拒绝启动。

有一些引导程序检查总是被强制执行,以防止 Elasticsearch 在不兼容的设置下运行。这些检查是单独记录的。

开发与生产模式

默认情况下,Elasticsearch 绑定到用于HTTP 和传输(内部)通信的环回地址 。这对于下载和使用 Elasticsearch 以及日常开发来说都很好,但对于生产系统来说却毫无用处。要加入集群,必须可以通过传输通信访问 Elasticsearch 节点。要通过非环回地址加入集群,节点必须将传输绑定到非环回地址并且不使用单节点发现。因此,如果一个 Elasticsearch 节点不能通过非环回地址与另一台机器形成集群,我们认为它处于开发模式,否则如果它可以通过非环回地址加入集群,则认为它处于生产模式。

请注意,HTTP 和传输可以通过http.host和独立配置 transport.host;这对于将单个节点配置为可通过 HTTP 访问以用于测试目的而无需触发生产模式非常有用。

单节点发现

我们认识到一些用户需要将传输绑定到外部接口以测试他们对传输客户端的使用。对于这种情况,我们提供发现类型single-node(通过设置discovery.type为 进行 配置single-node);在这种情况下,一个节点将选举自己成为主节点,并且不会与任何其他节点一起加入集群。

强制引导程序检查

如果您在生产中运行单个节点,则可以逃避引导程序检查(通过不将传输绑定到外部接口,或通过将传输绑定到外部接口并将发现类型设置为 single-node)。对于这种情况,你可以通过系统属性设置强制引导检查的执行es.enforce.bootstrap.checks,以trueJVM选项。如果您处于这种特定情况,我们强烈建议您这样做。此系统属性可用于独立于节点配置强制执行引导程序检查。

1. 堆大小检查

默认情况下,Elasticsearch 会根据节点的角色和总内存自动调整 JVM 堆的大小 。如果您手动覆盖默认大小并以不同的初始和最大堆大小启动 JVM,则 JVM 可能会在系统使用期间调整堆大小时暂停。如果启用 bootstrap.memory_lock,JVM 会在启动时锁定初始堆大小。如果初始堆大小不等于最大堆大小,则某些 JVM 堆在调整大小后可能不会被锁定。为避免这些问题,请使用等于最大堆大小的初始堆大小启动 JVM。

2. 文件描述符检查

文件描述符是用于跟踪打开的“文件”的 Unix 构造。但在 Unix 中,一切都是文件。例如,“文件”可以是物理文件、虚拟文件(例如,/proc/loadavg)或网络套接字。Elasticsearch 需要大量文件描述符(例如,每个分片由多个段和其他文件组成,以及与其他节点的连接等)。此引导程序检查在 OS X 和 Linux 上强制执行。要通过文件描述符检查,您可能必须配置文件描述符

3. 内存锁检查

当 JVM 进行主要的垃圾收集时,它会接触堆的每一页。如果这些页面中的任何一个被换出到磁盘,它们将不得不被换回内存。这会导致大量磁盘抖动,而 Elasticsearch 更愿意将其用于服务请求。有多种方法可以将系统配置为禁止交换。一种方法是通过mlockall(Unix)或虚拟锁(Windows)请求JVM将堆锁定在内存中。这是通过 Elasticsearch 设置完成的 bootstrap.memory_lock。但是,在某些情况下,此设置可以传递给 Elasticsearch,但 Elasticsearch 无法锁定堆(例如,如果elasticsearch 用户没有memlock unlimited)。该内存锁定检查验证,如果bootstrap.memory_lock设置已启用,即 JVM 能够成功锁定堆。要通过内存锁定检查,您可能需要配置bootstrap.memory_lock.

4. 最大线程数检查

Elasticsearch 通过将请求分解为多个阶段并将这些阶段交给不同的线程池执行程序来执行请求。Elasticsearch 中有针对各种任务的不同线程池执行器。因此,Elasticsearch 需要能够创建大量线程。最大线程数检查确保Elasticsearch进程在正常使用情况下有权创建足够多的线程。此检查仅在 Linux 上强制执行。如果您在 Linux 上,要通过最大线程数检查,您必须配置您的系统以允许 Elasticsearch 进程创建至少 4096 个线程的能力。这可以通过/etc/security/limits.conf 使用nproc设置来完成(请注意,您可能还必须增加root用户的限制)。

5. 最大文件大小检查

作为单个分片组件的段文件和作为 translog 组件的 translog 生成可能会变得很大(超过数 GB)。在 Elasticsearch 进程可以创建的文件的最大大小受到限制的系统上,这可能会导致写入失败。因此,这里最安全的选项是最大文件大小不受限制,这就是最大文件大小引导程序检查强制执行的内容。要通过最大文件检查,您必须将系统配置为允许 Elasticsearch 进程写入无限大小的文件。这可以通过 /etc/security/limits.conf使用fsize设置来完成unlimited(请注意,您可能还必须增加root用户的限制)。

6. 最大大小虚拟内存检查

Elasticsearch 和 Lucene 用于mmap将索引的部分映射到 Elasticsearch 地址空间中的效果很好。这将某些索引数据保留在 JVM 堆之外,但保留在内存中以便快速访问。为了使其有效,Elasticsearch 应该有无限的地址空间。最大大小虚拟内存检查强制 Elasticsearch 进程具有无限的地址空间,并且仅在 Linux 上强制执行。要通过最大大小虚拟内存检查,您必须配置您的系统以允许 Elasticsearch 进程拥有无限地址空间的能力。这可以通过添加<user> - as unlimited/etc/security/limits.conf. 这也可能需要您增加root用户的限制。

7. 最大地图计数检查

继续上一点,为了mmap有效地使用,Elasticsearch 还需要能够创建许多内存映射区域。最大映射计数检查检查内核是否允许进程具有至少 262,144 个内存映射区域,并且仅在 Linux 上强制执行。要通过最大地图计数检查,您必须将vm.max_map_countvia配置sysctl为至少262144.

或者,仅当您使用mmapfshybridfs作为索引的存储类型时才需要最大地图计数检查 。如果您不允许使用,mmap则不会强制执行此引导程序检查。

8. 客户端 JVM 检查

OpenJDK 派生的 JVM 提供了两种不同的 JVM:客户端 JVM 和服务器 JVM。这些 JVM 使用不同的编译器从 Java 字节码生成可执行的机器代码。客户端 JVM 针对启动时间和内存占用进行了调整,而服务器 JVM 则针对最大化性能进行了调整。两个 VM 之间的性能差异可能很大。客户端 JVM 检查确保 Elasticsearch 不在客户端 JVM 内运行。要通过客户端 JVM 检查,您必须使用服务器 VM 启动 Elasticsearch。在现代系统和操作系统上,服务器 VM 是默认设置。

9. 使用串行收集器检查

针对不同工作负载的 OpenJDK 派生 JVM 有各种垃圾收集器。特别是串行收集器最适合单逻辑 CPU 机器或极小的堆,这两种机器都不适合运行 Elasticsearch。将串行收集器与 Elasticsearch 结合使用可能会对性能造成破坏性影响。串行收集器检查确保 Elasticsearch 未配置为与串行收集器一起运行。要通过串行收集器检查,您不能使用串行收集器启动 Elasticsearch(无论它是来自您正在使用的 JVM 的默认值,还是您已明确指定它-XX:+UseSerialGC)。请注意,Elasticsearch 附带的默认 JVM 配置将 Elasticsearch 配置为在 JDK14 及更高版本中使用 G1GC 垃圾收集器。对于较早的 JDK 版本,配置默认为 CMS 收集器。

10. 系统调用过滤器检查

Elasticsearch 会根据操作系统(例如 Linux 上的 seccomp)安装各种风格的系统调用过滤器。安装这些系统调用过滤器是为了防止执行与分叉相关的系统调用的能力,作为抵御对 Elasticsearch 的任意代码执行攻击的防御机制。系统调用过滤器检查确保如果启用了系统调用过滤器,则它们已成功安装。要通过系统调用过滤器检查,您必须修复系统上阻止系统调用过滤器安装的任何配置错误(检查您的日志),或者自担风险通过设置bootstrap.system_call_filter为 来禁用系统调用过滤器false

11. OnError 和 OnOutOfMemoryError 检查

如果 JVM 遇到致命错误 ( ) 或 ( ) ,则 JVM 选项OnErrorOnOutOfMemoryError启用执行任意命令。但是,默认情况下,Elasticsearch 系统调用过滤器 (seccomp) 处于启用状态,这些过滤器可防止分叉。因此,使用or 和系统调用过滤器是不兼容的。该和 检查防止Elasticsearch从如果这两个JVM选项的使用和系统调用过滤器可启动。始终执行此检查。要通过此检查,请不要启用 或;相反,升级到 Java 8u92 并使用 JVM 标志。虽然这不具有nor的全部功能,但启用 seccomp 将不支持任意分叉。OnError``OutOfMemoryError``OnOutOfMemoryError``OnError``OnOutOfMemoryError``OnError``OnOutOfMemoryError``OnError``OnOutOfMemoryError``ExitOnOutOfMemoryError``OnError``OnOutOfMemoryError

12. G1GC 检查

众所周知,JDK 8 附带的 HotSpot JVM 的早期版本存在一些问题,当启用 G1GC 收集器时,这些问题可能会导致索引损坏。受影响的版本早于 JDK 8u40 附带的 HotSpot 版本。G1GC 检查检测这些 HotSpot JVM 的早期版本。

13. 发现配置检查

默认情况下,当 Elasticsearch 首次启动时,它会尝试发现在同一主机上运行的其他节点。如果在几秒钟内没有发现任何选定的主节点,那么 Elasticsearch 将形成一个集群,其中包含发现的任何其他节点。在开发模式下无需任何额外配置即可形成此集群很有用,但这不适用于生产,因为可能形成多个集群并因此丢失数据。

此引导程序检查可确保发现未使用默认配置运行。可以通过设置至少以下属性之一来满足它:

  • discovery.seed_hosts
  • discovery.seed_providers
  • cluster.initial_master_nodes

2.5 发现和集群形成

发现和集群形成过程负责发现节点,选举一个master,形成一个集群,并在每次集群状态发生变化时发布集群状态。

以下过程和设置是发现和集群形成的一部分:

  • 发现

    发现是节点在 master 未知时相互查找的过程,例如当一个节点刚刚启动或前一个 master 发生故障时。

  • 基于法定人数的决策

    即使某些节点不可用,Elasticsearch 如何使用基于仲裁的投票机制来做出决策。

  • 投票配置

    Elasticsearch 如何在节点离开和加入集群时自动更新投票配置。

  • 引导集群

    当 Elasticsearch 集群第一次启动时,需要引导集群。在开发模式下,没有配置发现设置,这由节点本身自动执行。由于这种自动引导本质上不安全的,因此在生产模式下运行节点 需要通过cluster.initial_master_nodes 设置显式配置引导 。

  • 添加和删除符合主节点的节点

    建议在集群中拥有少量且固定数量的符合 master 资格的节点,并且仅通过添加和删除不符合 master 资格的节点来扩展和缩小集群。然而,在某些情况下,可能需要在集群中添加或删除一些符合主节点的节点。本节介绍了添加或删除主节点的过程,包括同时删除一半以上的主节点时需要执行的额外步骤。

  • 发布集群状态

    集群状态发布是选定的主节点更新集群中所有其他节点上的集群状态的过程。

  • 集群故障检测

    Elasticsearch 执行健康检查以检测和删除故障节点。

  • 设置

    有一些设置使用户能够影响发现、集群形成、主选举和故障检测过程。

1. 发现

发现是集群形成模块寻找与形成集群的其他节点的过程。当你启动一个 Elasticsearch 节点或当一个节点认为主节点失败并继续运行直到找到主节点或选择新的主节点时,这个过程就会运行。

这个过程从一个或多个种子主机提供者种子地址 列表开始,以及最后一个已知集群中任何符合主节点的节点的地址。该过程分为两个阶段:首先,每个节点通过连接到每个地址来探测种子地址,并尝试识别它所连接的节点并验证它是否符合主节点资格。其次,如果成功,它与远程节点共享其所有已知的符合主控资格的对等体的列表,并且远程节点依次与其对等体进行响应。然后该节点探测它刚刚发现的所有新节点,请求它们的对等节点,等等。

如果该节点不符合主节点资格,则它会继续此发现过程,直到它发现了一个选定的主节点。如果未发现选定的主节点,则该节点将重试,之后discovery.find_peers_interval默认为1s

如果节点符合主节点条件,则它将继续此发现过程,直到它发现了一个选定的主节点,或者发现了足够多的无主节点符合主节点条件的节点来完成选择。如果这些都没有发生得足够快,那么节点将重试,之后 discovery.find_peers_interval默认为1s

种子宿主提供商

默认情况下,集群形成模块提供两个种子主机提供程序来配置种子节点列表:一个基于设置的种子主机提供程序和一个基于文件的种子主机提供程序。它可以通过发现插件扩展到支持云环境和其他形式的种子主机提供商。种子主机提供程序使用discovery.seed_providers 设置进行配置,默认设置为基于设置的主机提供程序。此设置接受不同提供程序的列表,允许您使用多种方法为集群查找种子主机。

每个种子主机提供商都会生成种子节点的 IP 地址或主机名。如果它返回任何主机名,则使用 DNS 查找将这些主机名解析为 IP 地址。如果主机名解析为多个 IP 地址,则 Elasticsearch 会尝试在所有这些地址上查找种子节点。如果主机提供者到那时没有明确给出节点的 TCP 端口,它将隐式使用由 给出的端口范围中的第一个端口transport.profiles.default.port,或者由 transport.portiftransport.profiles.default.port未设置。并发查找的数量由 discovery.seed_resolver.max_concurrent_resolvers哪个默认10为 控制,每次查找的超时由discovery.seed_resolver.timeout 哪个默认为 控制5s。请注意,DNS 查找受JVM DNS 缓存的约束 。

基于设置的种子主机提供商

基于设置的种子主机提供程序使用节点设置来配置种子节点地址的静态列表。这些地址可以作为主机名或 IP 地址提供;指定为主机名的主机在每轮发现期间解析为 IP 地址。

使用discovery.seed_hosts 静态设置设置主机列表。例如:

1
2
3
4
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com

基于文件的种子主机提供商

基于文件的种子主机提供程序通过外部文件配置主机列表。Elasticsearch 在这个文件发生变化时重新加载它,这样种子节点列表就可以动态变化,而无需重新启动每个节点。例如,这为在 Docker 容器中运行的 Elasticsearch 实例提供了一种方便的机制,可以在节点启动时可能不知道这些 IP 地址时动态提供要连接的 IP 地址列表。

要启用基于文件的发现,请fileelasticsearch.yml文件中按如下方式配置主机提供程序:

1
discovery.seed_providers: file

然后以$ES_PATH_CONF/unicast_hosts.txt下面描述的格式创建一个文件。每当对unicast_hosts.txt文件进行更改时,Elasticsearch 都会选取新的更改并使用新的主机列表。

请注意,基于文件的发现插件会扩充 中的单播主机列表 elasticsearch.yml:如果 中存在有效的种子地址, discovery.seed_hosts那么除了 中提供的地址之外,Elasticsearch 还会使用这些地址unicast_hosts.txt

unicast_hosts.txt文件每行包含一个节点条目。每个节点条目由主机(主机名或 IP 地址)和可选的传输端口号组成。如果指定了端口号, is 必须紧跟在主机之后(在同一行),以:. 如果未指定端口号,Elasticsearch 将隐式使用由 指定的端口范围中的第一个端口 transport.profiles.default.port,或者由transport.portif transport.profiles.default.port未设置。

例如,这是一个unicast_hosts.txt具有四个参与发现的节点的集群的示例,其中一些节点未在默认端口上运行:

1
2
3
4
5
10.10.10.5
10.10.10.6:9305
10.10.10.5:10005
# an IPv6 address
[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301

允许使用主机名而不是 IP 地址,并且如上所述由 DNS 解析。IPv6 地址必须在括号中给出,如果需要,在括号之后加上端口。

您还可以向该文件添加注释。所有注释都必须出现在以 开头的行中#(即注释不能从一行的中间开始)。

2. 基于仲裁的决策

基于法定人数的决策

选举主节点和更改集群状态是符合主节点条件的节点必须协同执行的两项基本任务。即使某些节点出现故障,这些活动也能稳健运行,这一点很重要。Elasticsearch 通过将每个操作视为在收到来自法定人数的响应后成功来实现这种健壮性,法定人数是集群中符合主节点的节点的子集。只需要节点的一个子集进行响应的优点是,这意味着某些节点可能会发生故障,而不会阻止集群取得进展。仲裁是经过仔细选择的,因此集群不会出现“裂脑”场景,即它被分成两部分,这样每个部分可能会做出与另一部分不一致的决定。

Elasticsearch 允许您向正在运行的集群添加和删除符合主节点的节点。在许多情况下,您只需根据需要启动或停止节点即可完成此操作。请参阅添加和删除节点

随着节点的添加或删除,Elasticsearch 通过更新集群的投票配置来保持最佳容错水平,投票配置是一组符合主节点的节点,在做出选择新主节点或提交新集群状态等决策时,这些节点的响应会被计算在内。只有在投票配置中超过一半的节点做出响应后,才会做出决定。通常投票配置与当前集群中所有符合主节点的节点的集合相同。但是,在某些情况下,它们可能会有所不同。

为了确保集群保持可用,您不能同时停止投票配置中的一半或更多节点。只要超过一半的投票节点可用,集群仍然可以正常工作。这意味着如果有三个或四个符合主节点条件的节点,集群可以容忍其中一个节点不可用。如果有两个或更少的符合主节点条件的节点,它们必须全部保持可用。

节点加入或离开集群后,所选主机必须发布集群状态更新,以调整投票配置以匹配,这可能需要很短的时间来完成。在从集群中删除更多节点之前,等待此调整完成非常重要。

主选举

Elasticsearch使用一个选择过程来商定一个选定的主节点,无论是在启动时还是在现有选定的主节点失败时。 任何符合 master 资格的节点都可以开始选举,通常第一次选举会成功。选举通常只有在两个节点几乎同时开始选举时才会失败,因此在每个节点上随机安排选举以减少发生这种情况的可能性。节点将重试选举,直到选举出一个主节点,在失败时退出,以便最终选举成功(具有任意高的概率)。主选举的调度由主选举设置控制

集群维护、滚动重启和迁移

许多集群维护任务涉及暂时关闭一个或多个节点,然后重新启动它们。默认情况下,如果 Elasticsearch 的主节点之一脱机(例如在滚动重启期间),则它可以保持可用 。此外,如果多个节点停止然后再次启动,那么它将自动恢复,例如在完整的集群重新启动期间 。在这些情况下,无需对此处描述的 API 采取任何进一步操作,因为主节点集不会永久更改。

3. 投票配置

每个 Elasticsearch 集群都有一个投票配置,这是一组符合 主节点条件的节点,在做出选择新主节点或提交新集群状态等决策时,这些节点的响应会被计算在内。只有在投票配置中的大多数(超过一半)节点做出响应后,才会做出决定。

通常投票配置与当前集群中所有符合主节点的节点的集合相同。但是,在某些情况下,它们可能会有所不同。

为确保集群保持可用,您不得同时停止投票配置中的一半或更多节点。只要有一半以上的投票节点可用,集群就可以正常工作。例如,如果有 3 个或 4 个符合 master 条件的节点,则集群可以容忍一个不可用的节点。如果有两个或更少的符合主节点条件的节点,它们必须全部保持可用。

在节点加入或离开集群后,Elasticsearch 会自动对投票配置进行相应的更改,以确保集群尽可能具有弹性。在从集群中删除更多节点之前,等待此调整完成非常重要。有关更多信息,请参阅添加和删除节点

当前投票配置存储在集群状态中,因此您可以按如下方式检查其当前内容:

1
GET /_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config

当前的投票配置不一定与集群中所有可用的主节点的集合相同。更改投票配置涉及投票,因此在节点加入或离开集群时需要一些时间来调整配置。此外,在某些情况下,最具弹性的配置包括不可用节点或不包括某些可用节点。在这些情况下,投票配置不同于集群中可用的主节点集。

较大的投票配置通常更具弹性,因此 Elasticsearch 通常更喜欢在加入集群后将符合 master 资格的节点添加到投票配置中。类似地,如果投票配置中的节点离开集群,并且集群中有另一个不处于投票配置中的主节点,那么最好交换这两个节点。因此,投票配置的大小不变,但其弹性增加。

在节点离开集群后从投票配置中自动删除节点并不是那么简单。不同的策略有不同的优点和缺点,因此正确的选择取决于集群的使用方式。您可以使用cluster.auto_shrink_voting_configuration设置来控制投票配置是否自动收缩 。

如果cluster.auto_shrink_voting_configuration设置为true(这是默认值和推荐值)并且集群中至少有三个符合主节点的节点,只要除了一个符合主节点的节点之外的所有节点都是健康的,Elasticsearch 仍然能够处理集群状态更新。

在某些情况下,Elasticsearch 可能会容忍多个节点的丢失,但这并不能保证在所有故障序列下都能做到。如果 cluster.auto_shrink_voting_configuration设置为false,您必须手动从投票配置中删除离开的节点。使用 投票排除 API来实现所需的弹性水平。

无论如何配置,Elasticsearch 都不会出现“裂脑”不一致的情况。该cluster.auto_shrink_voting_configuration 设置仅在某些节点发生故障时影响其可用性,以及在节点加入和离开集群时必须执行的管理任务。

偶数个主节点

集群中通常应该有奇数个符合主节点的节点。如果有偶数,Elasticsearch 会将其中一个从投票配置中排除,以确保其大小为奇数。这种省略不会降低集群的容错能力。事实上,稍微改进一下:如果集群受到网络分区的影响,该分区将其分为两个大小相同的一半,那么其中一半将包含大多数投票配置并且能够继续运行。如果所有符合主节点的选票都被计算在内,那么任何一方都不会包含绝对多数的节点,因此集群将无法取得任何进展。

例如,如果集群中有四个符合主节点的节点,并且投票配置包含所有这些节点,则任何基于仲裁的决策都需要至少三个节点的投票。这种情况意味着集群只能容忍一个主节点的丢失。如果这个集群被分成相等的两半,那么任何一半都不会包含三个符合主节点的节点,集群将无法取得任何进展。然而,如果投票配置只包含四个主节点中的三个,集群仍然只能完全容忍一个节点的丢失,但基于仲裁的决策需要三个投票节点中的两个投票。在偶数分裂的情况下,一半将包含三个投票节点中的两个,这样一半将保持可用。

设置初始投票配置

当一个全新的集群第一次启动时,它必须选举它的第一个主节点。为了进行这次选举,它需要知道哪些选票应该计入主节点的集合。这种初始投票配置称为引导配置,并在 集群引导过程中设置

引导程序配置准确识别哪些节点应该在第一次选举中投票是很重要的。仅根据集群中应该有多少个节点来配置每个节点是不够的。同样重要的是要注意引导程序配置必须来自集群外部:集群没有安全的方法可以自行正确确定引导程序配置。

如果引导配置设置不正确,当您启动一个全新的集群时,您可能会意外地形成两个独立的集群而不是一个。这种情况可能会导致数据丢失:您可能会在发现任何问题之前就开始使用这两个集群,并且以后无法将它们合并在一起。

为了说明将每个节点配置为期望某个集群大小的问题,假设启动一个三节点集群,其中每个节点都知道它将成为三节点集群的一部分。三个节点中的大多数是两个,所以通常前两个发现彼此的节点形成一个集群,第三个节点稍后会加入它们。但是,假设错误地启动了四个节点而不是三个。在这种情况下,有足够的节点来形成两个独立的集群。当然,如果每个节点都是手动启动的,那么启动的节点不太可能太多。但是,如果您使用的是自动编排器,则肯定有可能遇到这种情况——特别是如果编排器对网络分区等故障没有弹性。

只有在整个集群第一次启动时才需要初始仲裁。加入建立群集的新节点可以安全地获取所需的所有信息。以前是集群一部分的节点将在重新启动时将所需的所有信息存储到磁盘中

4. 引导集群

首次启动 Elasticsearch 集群需要在集群中的一个或多个主节点上明确定义初始主节点集。这称为集群引导。这仅在集群第一次启动时才需要:已经加入集群的节点将此信息存储在其数据文件夹中以用于完整的集群重新启动,并且新启动的加入正在运行的集群的节点从集群选择的主节点。

初始的主节点集在cluster.initial_master_nodes设置中定义 。对于每个符合主节点的节点,这应该设置为包含以下项目之一的列表:

  • 节点名称的节点。
  • 如果node.name未设置节点的主机名,因为node.name默认为节点的主机名。您必须使用完全限定的主机名或裸主机名,具体取决于您的系统配置
  • 节点的传输发布地址的IP地址,如果不能使用node.name节点的。这通常是network.host解析到的 IP 地址, 但这 可以被覆盖
  • 节点发布地址的IP地址和端口,格式为IP:PORT,如果不能使用node.name节点的 并且有多个节点共享一个IP地址。

当您启动符合主节点的节点时,您可以在命令行或elasticsearch.yml文件中提供此设置。集群形成后,不再需要此设置。不应为不符合主控资格的节点、符合主控资格的节点加入现有集群或集群重新启动设置。

cluster.initial_master_nodes在集群中的单个符合主节点的节点上进行设置在技术上就足够了,并且只在设置值中提及该单个节点,但这在集群完全形成之前不提供容错能力。因此,最好使用至少三个符合主节点的节点进行引导,每个节点的cluster.initial_master_nodes设置都包含所有三个节点。

您必须在设置cluster.initial_master_nodes它的每个节点上设置相同的节点列表,以确保在引导期间仅形成一个集群,从而避免数据丢失的风险。

对于具有 3 个符合主节点条件的节点(节点名称为 master-amaster-bmaster-c)的集群,配置将如下所示:

1
2
3
4
cluster.initial_master_nodes:
- master-a
- master-b
- master-c

与所有节点设置一样,也可以在用于启动 Elasticsearch 的命令行上指定初始主节点集:

1
$ bin/elasticsearch -Ecluster.initial_master_nodes=master-a,master-b,master-c

cluster.initial_master_nodes列表中使用的节点名称 必须与node.name 节点的属性完全匹配。默认情况下,节点名称设置为机器的主机名,它可能是也可能不是完全限定的,具体取决于您的系统配置。如果每个节点名称都是完全限定域名, master-a.example.com那么您也必须在cluster.initial_master_nodes列表中使用完全限定域名 ;相反,如果您的节点名称是裸主机名(没有.example.com后缀),那么您必须在cluster.initial_master_nodes列表中使用裸主机名。如果您混合使用完全限定主机名和裸主机名,或者node.name和 之间存在其他一些不匹配cluster.initial_master_nodes,则集群将无法成功形成,您将看到如下日志消息。

选择集群名称

cluster.name设置使您能够创建多个相互分离的集群。节点在第一次相互连接时会验证它们对集群名称是否一致,而 Elasticsearch 只会将所有具有相同集群名称的节点组成一个集群。集群名称的默认值为elasticsearch,但建议更改此值以反映集群的逻辑名称。

开发模式下的自动引导

如果集群以完全默认的配置运行,那么它将根据在启动后的短时间内发现在同一主机上运行的节点自动引导集群。这意味着默认情况下可以在一台机器上启动多个节点并让它们自动形成一个集群,这对于开发环境和实验非常有用。但是,由于节点可能并不总是足够快地成功地发现彼此,因此不能依赖这种自动引导,也不能在生产部署中使用。

如果配置了以下任何设置,则不会进行自动引导,您必须cluster.initial_master_nodes按照集群引导部分中的说明进行配置:

  • discovery.seed_providers
  • discovery.seed_hosts
  • cluster.initial_master_nodes

如果您在没有配置这些设置的情况下启动 Elasticsearch 节点,那么它将以开发模式启动并自动引导到新集群中。如果您在不同的主机上启动一些 Elasticsearch 节点,那么默认情况下它们不会发现彼此,并且会在每个主机上形成不同的集群。Elasticsearch 不会在单独的集群形成后将它们合并在一起,即使您随后尝试将所有节点配置为单个集群也是如此。这是因为没有办法在不存在数据丢失风险的情况下将这些单独的集群合并在一起。您可以通过检查GET /每个节点上报告的集群 UUID 来判断您已经形成了单独的集群。如果您打算形成单个集群,那么您应该重新开始:

  • 关闭所有节点。
  • 通过删除其数据文件夹的内容来完全擦除每个节点 。
  • cluster.initial_master_nodes如上所述进行 配置。
  • 重新启动所有节点并验证它们是否已形成单个集群。

5. 发布集群状态

主节点是集群中唯一可以更改集群状态的节点。主节点一次处理一批集群状态更新,计算所需的更改并将更新后的集群状态发布到集群中的所有其他节点。每个发布都从主节点向集群中的所有节点广播更新的集群状态开始。每个节点都以确认响应,但尚未应用新接收的状态。一旦 master 从足够多的符合 master 资格的节点收集到确认,新的集群状态就被称为已提交,并且 master 会广播另一条消息,指示节点应用现在提交的状态。每个节点收到此消息,应用更新的状态,然后向主节点发送第二个确认。

主节点允许在有限的时间内将每个集群状态更新完全发布到所有节点。它由cluster.publish.timeout设置定义 ,默认为30s,从发布开始的时间开始计算。如果在提交新集群状态之前达到这个时间,那么集群状态更改将被拒绝,并且主节点认为自己已经失败。它停止并开始尝试选举一个新的主人。

如果新的集群状态在cluster.publish.timeout过去之前提交,则主节点认为更改已成功。它一直等到超时过去或收到集群中每个节点已应用更新状态的确认,然后开始处理和发布下一个集群状态更新。如果某些确认尚未收到(即某些节点尚未确认它们已应用当前更新),则这些节点被称为滞后,因为它们的集群状态已落后于主节点的最新状态。主节点等待滞后节点再追上一段时间,cluster.follower_lag.timeout默认为90s. 如果节点在这段时间内仍未成功应用集群状态更新,则认为它已失败并从集群中删除。

集群状态更新通常作为与之前集群状态的差异发布,这减少了发布集群状态更新所需的时间和网络带宽。例如,当仅更新集群状态中索引子集的映射时,只要这些节点具有先前的集群状态,只需将这些索引的更新发布到集群中的节点即可。如果一个节点缺少以前的集群状态,例如在重新加入集群时,主节点将向该节点发布完整的集群状态,以便它可以接收未来的更新作为差异。

Elasticsearch 是一种基于点对点的系统,其中节点之间直接通信。高吞吐量 API(索引、删除、搜索)通常不与主节点交互。主节点的职责是维护全局集群状态,并在节点加入或离开集群时重新分配分片。每次更改集群状态时,新状态都会发布到集群中的所有节点,如上所述。

6. 集群故障检测

选定的主节点定期检查集群中的每个节点,以确保它们仍然连接且健康。集群中的每个节点也会定期检查所选主节点的健康状况。这些检查分别称为跟随者检查领导者检查

Elasticsearch 允许这些检查偶尔失败或超时而不采取任何行动。只有在多次连续检查失败后,它才认为节点有故障。您可以通过cluster.fault_detection.*设置来控制故障检测行为 。

但是,如果选定的主节点检测到节点已断开连接,则这种情况将被视为立即故障。 主节点绕过超时和重试设置值并尝试从集群中删除节点。类似地,如果节点检测到所选的主节点已断开连接,则这种情况将被视为立即故障。节点绕过超时和重试设置并重新启动其发现阶段以尝试查找或选择新的主节点。

此外,每个节点通过将一个小文件写入磁盘然后再次删除它来定期验证其数据路径是否健康。如果节点发现其数据路径不正常,则将其从集群中删除,直到数据路径恢复。您可以使用monitor.fs.health设置来控制此行为 。

当节点无法在合理的时间内无法在合理的时间内应用更新的群集状态,所选的主节点也将从群集中删除节点,这是默认120s在群集状态更新开始后默认为120s。

2.6 在集群中添加和删除节点

当您启动 Elasticsearch 实例时,您正在启动一个node。Elasticsearch集群 是一组具有相同cluster.name属性的节点。当节点加入或离开集群时,集群会自动重新组织自身以在可用节点之间均匀分布数据。

如果您正在运行 Elasticsearch 的单个实例,则您拥有一个包含一个节点的集群。所有主分片都驻留在单个节点上。无法分配副本分片,因此集群状态保持为黄色。集群功能齐全,但在发生故障时有数据丢失的风险。

elas_0202

您可以向集群添加节点以提高其容量和可靠性。默认情况下,一个节点既是数据节点,又有资格被选为控制集群的主节点。您还可以为特定目的配置新节点,例如处理摄取请求。有关更多信息,请参阅 节点

当您向集群添加更多节点时,它会自动分配副本分片。当所有主分片和副本分片都处于活动状态时,集群状态变为绿色。

elas_0204

您可以在本地机器上运行多个节点,以试验由多个节点组成的 Elasticsearch 集群的行为方式。要将节点添加到本地计算机上运行的集群:

  1. 设置一个新的 Elasticsearch 实例。
  2. 使用 中的cluster.name设置 指定集群的名称elasticsearch.yml。例如,要将节点添加到logging-prod集群,请将行添加cluster.name: "logging-prod"elasticsearch.yml
  3. 启动 Elasticsearch。节点自动发现并加入指定的集群。

要将节点添加到在多台机器上运行的集群,您还必须进行 设置,discovery.seed_hosts以便新节点可以发现其集群的其余部分。

主节点

随着节点的添加或删除,Elasticsearch 通过自动更新集群的投票配置来保持最佳容错水平,这是一组符合主节点的节点,在做出选择新主节点或提交新集群状态等决策时,这些节点的响应被计算在内.

建议在集群中拥有少量且固定数量的符合 master 资格的节点,并且仅通过添加和删除不符合 master 资格的节点来扩展和缩小集群。然而,在某些情况下,可能需要在集群中添加或删除一些符合主节点的节点。

添加符合主节点的节点

如果您希望向集群添加一些节点,只需配置新节点以查找现有集群并启动它们。如果合适,Elasticsearch 会将新节点添加到投票配置中。

在选举主节点或加入现有集群时,节点向主节点发送加入请求,以便正式加入集群。

删除符合主节点的节点

删除符合主节点的节点时,不要同时删除太多节点,这一点很重要。例如,如果当前有七个符合 master 资格的节点,而您希望将其减少到三个,则不可能简单地一次停止四个节点:这样做只会留下三个节点,不到一半投票配置,这意味着集群不能采取任何进一步的行动。

更准确地说,如果您同时关闭一半或更多符合主节点条件的节点,则集群通常将变得不可用。如果发生这种情况,您可以通过再次启动已删除的节点来使集群重新联机。

只要集群中至少有3个master-eligible节点,一般来说最好一次删除一个节点,让集群有足够的时间自动调整投票配置和适应故障对新节点集的容忍度。

如果只剩下两个符合主节点条件的节点,那么这两个节点都不能安全地移除,因为两者都需要可靠地取得进展。要删除这些节点之一,您必须首先通知 Elasticsearch 它不应成为投票配置的一部分,而应将投票权赋予另一个节点。然后,您可以使排除的节点脱机,而不会阻止其他节点取得进展。添加到投票配置排除列表的节点仍然正常工作,但 Elasticsearch 尝试将其从投票配置中删除,因此不再需要其投票。重要的是,Elasticsearch 永远不会自动将投票排除列表上的节点移回投票配置。一旦排除的节点成功地从投票配置中自动重新配置,在不影响集群的主级别可用性的情况下关闭它是安全的。可以使用以下命令将节点添加到投票配置排除列表中 投票配置排除API。例如:

1
2
3
4
#添加节点,以投票的配置排除列表,并等待了该系统#来自动重新配置的节点出来的的投票配置了到了#默认的超时时间的30秒           
POST /_cluster/voting_config_exclusions?node_names=node_name
排除列表和等待为#自动重新配置达到的一个分钟的车
POST /_cluster/voting_config_exclusions?node_names=node_name&timeout=1m

应该添加到排除列表中的节点使用?node_names查询参数通过名称指定,或者使用查询参数通过它们的持久节点 ID?node_ids指定。如果对投票配置排除 API 的调用失败,您可以安全地重试。只有成功的响应才能保证节点实际上已从投票配置中删除并且不会被恢复。如果所选主节点被排除在投票配置之外,则它将让位给另一个仍在投票配置中的主合格节点(如果该节点可用)。

尽管投票配置排除 API 对于将两节点集群缩减为单节点集群最有用,但也可以使用它同时删除多个符合主节点条件的节点。将多个节点添加到排除列表会使系统尝试自动重新配置所有这些节点,使其脱离投票配置,从而在保持集群可用的同时安全关闭它们。在上面描述的示例中,将一个七主节点集群缩小到只有三个主节点,您可以将四个节点添加到排除列表中,等待确认,然后同时关闭它们。

仅当在短时间内从集群中删除至少一半符合 master 资格的节点时,才需要投票排除。删除不合格的节点时不需要它们,删除少于一半的合格节点时也不需要它们。

为节点添加排除项会在投票配置排除列表中为该节点创建一个条目,这会让系统自动尝试重新配置投票配置以删除该节点,并防止它在删除后返回投票配置。当前的排除列表存储在集群状态中,可以按如下方式检查:

1
GET /_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions

此列表的大小受cluster.max_voting_config_exclusions 设置限制,默认为10。请参阅发现和集群形成设置。由于投票配置排除项是持久的且数量有限,因此必须清除它们。通常在对集群进行一些维护时会添加一个排除项,并且在维护完成时应该清除这些排除项。在正常操作中,集群应该没有投票配置排除项。

如果某个节点因为要永久关闭而被排除在投票配置之外,则可以在它关闭并从集群中删除后将其排除。如果排除是错误创建的或仅通过指定临时需要,也可以清除排除?wait_for_removal=false

1
2
3
4
5
6
7
8
#等待从中删除具有投票配置排除的所有节点
#然后删除所有排除项,允许任何节点返回到
#未来的投票配置。
DELETE /_cluster/voting_config_exclusions

#立即删除所有投票配置排除项,允许任何节点
#以在将来返回到投票配置。
DELETE /_cluster/voting_config_exclusions?wait_for_removal=false

2.7 全集群重启和滚动重启

在某些情况下,您可能希望执行全集群重启或滚动重启。在全集群重启的情况下 ,您关闭并重新启动集群中的所有节点,而在滚动重启的情况下 ,您一次只关闭一个节点,因此服务不会中断。

禁用分片分配。

当您关闭一个数据节点时,分配过程会等待 index.unassigned.node_left.delayed_timeout(默认情况下,一分钟),然后才开始将该节点上的分片复制到集群中的其他节点,这可能涉及大量 I/O。由于节点即将重新启动,因此不需要此 I/O。您可以通过在关闭数据节点之前禁用副本分配来避免时钟竞争 :

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}

停止索引并执行同步刷新。

执行同步刷新可加速分片恢复。

1
POST _flush/synced

执行同步刷新时,请检查响应以确保没有失败。由于挂起的索引操作而失败的同步刷新操作列在响应正文中,尽管请求本身仍返回 200 OK 状态。如果失败,请重新发出请求。

请注意,不推荐使用同步刷新并将在 8.0 中删除。在 Elasticsearch 7.6 或更高版本上,刷新与同步刷新具有相同的效果。

暂时停止与活动机器学习作业和数据馈送相关的任务。(可选的)

机器学习功能需要特定订阅

关闭集群时,您有两种选择来处理机器学习作业和数据馈送:

  • 使用set upgrade mode API暂时停止与您的机器学习作业和数据馈送相关的任务,并防止打开新作业 :

    1
    POST _ml/set_upgrade_mode?enabled=true

    当您禁用升级模式时,作业将使用自动保存的最后一个模型状态恢复。此选项避免了在关闭期间管理活动作业的开销,并且比显式停止数据馈送和关闭作业更快。

  • 停止所有数据馈送并关闭所有作业。此选项保存关闭时的模型状态。在集群重新启动后重新打开作业时,它们使用完全相同的模型。但是,保存最新模型状态比使用升级模式需要更长的时间,尤其是当您有大量作业或具有大型模型状态的作业时。

关闭所有节点。

  • 如果您使用以下命令运行 Elasticsearch systemd
1
sudo systemctl stop elasticsearch.service
  • 如果您使用 SysV 运行 Elasticsearch init
1
sudo -i service elasticsearch stop
  • 如果您将 Elasticsearch 作为守护进程运行:
1
kill $(cat pid)

执行任何需要的更改。

重启节点。

如果您有专用的主节点,请先启动它们并等待它们形成集群并选择一个主节点,然后再继续处理您的数据节点。您可以通过查看日志来检查进度。

一旦有足够多的符合主节点条件的节点相互发现,它们就会形成一个集群并选举一个主节点。此时,您可以使用cat healthcat nodes API 来监视加入集群的节点:

1
2
3
GET _cat/health

GET _cat/nodes

status列中返回通过_cat/health显示每个节点的健康集群中:redyellow,或green

等待所有节点加入集群并报告黄色状态。

当一个节点加入集群时,它开始恢复本地存储的所有主分片。该_cat/healthAPI最初将报告statusred,表明并非所有的初级碎片已被分配。

一旦一个节点恢复了它的本地分片,集群status就会切换到 yellow,表明所有的主分片都已经恢复,但不是所有的副本分片都被分配了。这是意料之中的,因为您尚未重新启用分配。延迟分配副本直到所有节点都yellow允许主节点将副本分配给已经具有本地分片副本的节点。

重新启用分配。

当所有节点都加入集群并恢复了它们的主分片后,通过恢复cluster.routing.allocation.enable到默认值来重新启用分配:

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": null
}
}

重新启用分配后,集群开始将副本分片分配给数据节点。此时恢复索引和搜索是安全的,但是如果您可以等到所有主分片和副本分片成功分配并且所有节点的状态都为 ,您的集群将恢复得更快green

您可以使用_cat/health_cat/recoveryAPI监控进度:

1
2
3
GET _cat/health

GET _cat/recovery

重新启动机器学习作业。(可选的)

如果您暂时停止了与机器学习作业关联的任务,请使用 set upgrade mode API将它们返回到活动状态:

1
POST _ml/set_upgrade_mode?enabled=false

如果您在停止节点之前关闭了所有机器学习作业,请打开作业并从 Kibana 启动数据馈送,或者使用打开的作业启动数据馈送API。

2.8 远程集群

您可以将本地集群连接到其他 Elasticsearch 集群,称为远程集群。连接后,您可以使用跨集群搜索来搜索远程集群 。您还可以使用跨集群复制在集群之间同步数据。

要注册远程集群,请使用以下两种连接模式之一将本地集群连接到远程集群中的节点:

您的本地集群使用传输层与远程集群建立通信。本地集群中的协调节点与远程集群中的特定节点建立长期存在的TCP 连接。Elasticsearch 要求这些连接保持打开状态,即使这些连接空闲很长时间也是如此。

您可以使用远程集群信息 API来获取有关已注册远程集群的信息。

嗅探模式

在嗅探模式下,使用名称和种子节点列表创建集群。注册远程集群时,将从种子节点之一检索其集群状态,并选择最多三个网关节点作为远程集群请求的一部分。这种模式要求本地集群可以访问网关节点的发布地址。

嗅探模式是默认的连接模式。

网关节点的选择取决于以下条件:

  • version:远程节点必须与它们注册的集群兼容,类似于滚动升级的规则 :
    • 任何节点都可以与同一主要版本上的另一个节点通信。例如,7.0 可以与任何 7.x 节点通信。
    • 只有某个主版本的最后一个次要版本上的节点才能与下一个主版本上的节点通信。在 6.x 系列中,6.8 可以与任何 7.x 节点通信,而 6.7 只能与 7.0 通信。
    • 版本兼容性是对称的,也就是说如果6.7可以和7.0通信,7.0也可以和6.7通信。下表描述了本地和远程节点之间的版本兼容性。
  • role:永远不会选择专用主节点作为网关节点。
  • attributes:您可以标记应该选择哪些节点(请参阅全局远程集群设置),尽管此类标记节点仍然必须满足上述两个要求。

代理模式

在代理模式下,使用名称和单个代理地址创建集群。当您注册远程集群时,会向代理地址打开可配置数量的套接字连接。需要代理将这些连接路由到远程集群。代理模式不需要远程集群节点具有可访问的发布地址。

代理模式不是默认的连接模式,必须配置。与嗅探网关节点类似,远程连接遵循与滚动升级相同的版本兼容性规则 。

详细配置方式参考官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-remote-clusters.html

3. 索引模块

索引模块是为每个索引创建的模块,控制与索引相关的所有方面。

索引设置

可以为每个索引设置索引级别设置。设置可能是:

更改关闭索引上的静态或动态索引设置可能会导致不正确的设置,如果不删除和重新创建索引就无法纠正这些设置。

其他索引模块中的设置

其他索引设置在索引模块中可用:

  • 分析

    用于定义分析器、标记器、标记过滤器和字符过滤器的设置。

  • 索引分片分配

    控制分片在何处、何时以及如何分配给节点。

  • 映射

    启用或禁用索引的动态映射。

  • 合并

    控制后台合并过程如何合并分片。

  • 相似之处

    配置自定义相似性设置以自定义搜索结果的评分方式。

  • 慢日志

    控制记录查询和获取请求的速度。

  • 店铺

    配置用于访问分片数据的文件系统类型。

  • 跨日志

    控制事务日志和后台刷新操作。

  • 历史保留

    控制对索引中操作历史记录的保留。

  • 分度压力

    配置索引背压限制。

分析

索引分析模块充当分析器的 可配置注册表,可用于将字符串字段转换为单个术语,这些术语是:

  • 添加到倒排索引以使文档可搜索
  • 由高级查询使用,例如 用于生成搜索词的match查询

索引分片分配

该模块提供每个索引设置来控制分片到节点的分配:

索引级分片分配过滤

您可以使用分片分配过滤器来控制 Elasticsearch 在何处分配特定索引的分片。这些 per-index 过滤器与 集群范围的分配过滤分配意识结合应用

碎片分配过滤器可根据自定义节点的属性或内置 _name_host_ip_publish_ip_ip_host_id_tier_tier_preference 属性。索引生命周期管理使用基于自定义节点属性的过滤器来确定在阶段之间移动时如何重新分配分片。

这些cluster.routing.allocation设置是动态的,可以将实时索引从一组节点移动到另一组节点。只有在不破坏其他路由约束的情况下才可能重新定位分片,例如永远不要在同一节点上分配主分片和副本分片。

例如,您可以使用自定义节点属性来指示节点的性能特征,并使用分片分配过滤将特定索引的分片路由到最合适的硬件类别。

节点离开时延迟分配

当节点出于任何原因(有意或无意)离开集群时,主节点会做出以下反应:

  • 将副本分片提升为主分片以替换节点上的任何主分片。
  • 分配副本分片以替换丢失的副本(假设有足够的节点)。
  • 在其余节点之间均匀地重新平衡分片。

这些操作旨在通过确保尽快完全复制每个分片来保护集群免受数据丢失。

即使我们在节点级别集群级别限制并发恢复 ,这种“分片洗牌”仍然会给集群带来很多额外的负载,如果丢失的节点可能很快就会返回,这可能是不必要的。想象一下这个场景:

  • 节点 5 失去网络连接。
  • 主节点将节点 5 上的每个主节点的副本分片提升为主节点。
  • 主节点将新副本分配给集群中的其他节点。
  • 每个新副本都会通过网络制作主分片的完整副本。
  • 更多的分片被移动到不同的节点以重新平衡集群。
  • 节点 5 会在几分钟后返回。
  • 主节点通过向节点 5 分配分片来重新平衡集群。

如果 master 只等待了几分钟,那么丢失的分片就可以以最少的网络流量重新分配给节点 5。对于已自动同步刷新的空闲分片(未接收索引请求的分片),此过程会更快。

由于节点离开而变为未分配的副本分片的分配可以通过index.unassigned.node_left.delayed_timeout 动态设置延迟,默认为1m

索引恢复优先级

尽可能按优先级顺序恢复未分配的分片。索引按优先级排序如下:

  • 可选index.priority设置(先高后低)
  • 索引创建日期(先高后低)
  • 索引名称(先高后低)

这意味着,默认情况下,较新的索引将在较旧的索引之前恢复。

每个节点的总分片

集群级分片分配器尝试将单个索引的分片分布在尽可能多的节点上。但是,根据您拥有的分片和索引的数量以及它们的大小,可能无法始终均匀地分布分片。

以下动态设置允许您指定每个节点允许的单个索引的分片总数的硬限制:

  • index.routing.allocation.total_shards_per_node

    将分配给单个节点的最大分片数(副本和主分片)。默认为无界。

无论索引如何,您还可以限制节点可以拥有的分片数量:

  • cluster.routing.allocation.total_shards_per_node

    (动态) 分配给每个节点的最大主分片和副本分片数。默认为 -1(无限制)。Elasticsearch 在分片分配期间检查此设置。例如,一个集群有一个 cluster.routing.allocation.total_shards_per_node设置为100和三个节点,具有以下分片分配:节点 A:100 个分片节点 B:98 个分片节点 C:1 个分片如果节点 C 发生故障,Elasticsearch 会将其分片重新分配给节点 B。将分片重新分配给节点 A 将超出节点 A 的分片限制。

这些设置施加了硬限制,这可能导致某些分片未被分配。

索引块

索引块限制了对某个索引可用的操作类型。这些块有不同的风格,允许阻止写入、读取或元数据操作。可以使用动态索引设置来设置/删除块,或者可以使用专用 API 添加,这也确保写入块,一旦成功返回给用户,索引的所有分片都会正确地占块,例如添加写入块后,所有对索引的动态写入都已完成。

映射器

映射器模块充当在创建索引或使用更新映射 API 时添加到索引的类型映射定义的注册表。它还处理对没有预定义显式映射的类型的动态映射支持。

合并

Elasticsearch 中的一个分片是一个 Lucene 索引,一个 Lucene 索引被分解成段。段是存储索引数据的索引中的内部存储元素,并且是不可变的。较小的段会定期合并为较大的段以保持索引大小并清除删除。

合并过程使用自动限制来平衡合并和其他活动(如搜索)之间硬件资源的使用。

合并调度

合并调度程序(ConcurrentMergeScheduler)在需要时控制合并操作的执行。合并在单独的线程中运行,当达到最大线程数时,将等待进一步合并,直到合并线程可用。

合并调度器支持以下动态设置:

  • index.merge.scheduler.max_thread_count

    单个分片上可以同时合并的最大线程数。默认为 Math.max(1, Math.min(4, <<node.processors, node.processors>> / 2))适用于良好的固态磁盘 (SSD)。如果您的索引位于旋转盘片驱动器上,请将其减少到 1。

1. 相似性模块

相似度模块

相似性(评分/排名模型)定义了匹配文档的评分方式。相似性是每个字段,这意味着通过映射可以为每个字段定义不同的相似性。

配置自定义相似性被视为专家功能,并且内置相似性很可能如 中所述 similarity

BM25 相似度(默认)

基于 TF/IDF 的相似性具有内置的 tf 规范化,并且应该对短字段(如名称)工作得更好。有关更多详细信息,请参阅 Okapi_BM25。这种相似性有以下选项:

k1 控制非线性项频归一化(饱和度)。默认值为1.2
b 控制文档长度标准化 tf 值的程度。默认值为0.75
discount_overlaps 确定计算范数时是否忽略重叠标记(位置增量为 0 的标记)。默认情况下这是真的,这意味着在计算规范时重叠标记不计算在内。

DFR相似度

实现与随机性框架发散的相似性 。这种相似性有以下选项:

basic_model 可能的值:gifinine
after_effect 可能的值:bl
normalization 可能的值:noh1h2h3z

除第一个选项外的所有选项都需要标准化值。

DFI相似度

实现独立 模型发散的相似性。这种相似性有以下选项:

independence_measure 可能的值 standardized, saturated, chisquared

使用这种相似度时,强烈建议不要删除停用词以获得良好的相关性。还要注意频率低于预期频率的术语将获得等于 0 的分数。

IB相似度。

基于信息的模型。该算法基于任何符号分布 序列中的信息内容主要由其基本元素的重复使用决定的概念。对于书面文本,此挑战对应于比较不同作者的写作风格。这种相似性有以下选项:

distribution 可能的值: llspl
lambda 可能的值: dfttf
normalization DFR相似性相同。

LM Dirichlet 相似度。

LM狄利克雷相似度

论文中的评分公式给出现次数少于语言模型预测的词项分配负分,这对 Lucene 来说是非法的,因此此类词项的评分为 0。

LM Jelinek Mercer 相似度。

LM Jelinek Mercer 相似度。该算法试图捕捉文本中的重要模式,同时排除噪音。

脚本相似度

允许您使用脚本来指定应如何计算分数的相似性

2. 慢日志

搜索慢日志

分片级慢速搜索日志允许将慢速搜索(查询和获取阶段)记录到专用日志文件中。

可以为执行的查询阶段和获取阶段设置阈值,这是一个示例:

1
2
3
4
5
6
7
8
9
index.search.slowlog.threshold.query。警告:10s
index.search.slowlog.threshold.query。信息:5s
index.search.slowlog.threshold.query。调试:2s
index.search.slowlog.threshold.query。跟踪:500ms

index.search.slowlog.threshold.fetch。警告:1s
index.search.slowlog.threshold.fetch。信息:800ms
index.search.slowlog.threshold.fetch。调试:500ms
index.search.slowlog.threshold.fetch。跟踪:200ms

日志记录在分片级别范围内完成,这意味着在特定分片内执行搜索请求。它不包含整个搜索请求,可以将其广播到多个分片以执行。与请求级别相比,分片级别日志记录的一些好处是将特定机器上的实际执行关联起来。

文件中配置了搜索慢日志log4j2.properties文件。

识别搜索慢日志来源

确定是什么触发了缓慢运行的查询通常很有用。如果使用X-Opaque-ID标头发起呼叫,则用户 ID 将作为附加ID字段包含在搜索慢日志中(向右滚动)。

索引慢日志

索引慢日志,功能类似于搜索慢日志。日志文件名以_index_indexing_slowlog.log. 日志和阈值的配置方式与搜索慢日志相同。

默认情况下,Elasticsearch 将在慢日志中记录 _source 的前 1000 个字符。你可以用index.indexing.slowlog.source. 将其设置为falseor0将完全跳过记录源,而将其设置为 true将记录整个源,而不管大小。_source默认情况下,原始文件被重新格式化以确保它适合单个日志行。如果保留原始文档格式很重要,您可以通过设置index.indexing.slowlog.reformat为关闭重新格式化 false,这将导致源“按原样”记录并可能跨越多个日志行。

慢日志级别

您可以通过设置适当的阈值来模拟搜索或索引慢日志级别,从而关闭“更详细”的记录器。例如,如果我们想模拟 index.indexing.slowlog.level = INFO 那么我们需要做的就是将 index.indexing.slowlog.threshold.index.debug 和 index.indexing.slowlog.threshold.index.trace 设置为 - 1

3. 存储

store 模块允许您控制索引数据在磁盘上的存储和访问方式。

这是一个低级设置。一些存储实现具有较差的并发性或禁用堆内存使用的优化。我们建议坚持使用默认值。

文件系统存储类型

有不同的文件系统实现或存储类型。默认情况下,Elasticsearch 将根据操作环境选择最佳实现。

通过在config/elasticsearch.yml文件中配置存储类型,还可以为所有索引显式设置存储类型:

1
index.store.type: hybridfs

这是一个静态设置,可以在索引创建时基于每个索引进行设置:

1
2
3
4
5
6
PUT /my-index-000001
{
"settings": {
"index.store.type": "hybridfs"
}
}
1
2
警告:
这是仅限专家的设置,将来可能会被删除。

以下部分列出了所有支持的不同存储类型。

  • fs

    默认文件系统实现。这将根据操作环境选择最佳实现,当前hybridfs在所有支持的系统上都有,但可能会发生变化。

  • simplefs

    Simple FS 类型是SimpleFsDirectory使用随机访问文件的文件系统存储(映射到 Lucene )的直接实现。这种实现的并发性能很差(多线程会出现瓶颈)并且禁用了一些堆内存使用的优化。

  • niofs

    NIO FS 类型NIOFSDirectory使用 NIO在文件系统上存储分片索引(映射到 Lucene )。它允许多个线程同时读取同一个文件。不建议在 Windows 上使用它,因为 SUN Java 实现中存在错误,并且禁用了对堆内存使用的一些优化。

  • mmapfs

    MMap FS 类型MMapDirectory通过将文件映射到内存 (mmap)来将分片索引存储在文件系统上(映射到 Lucene )。内存映射占用了进程中虚拟内存地址空间的一部分,等于被映射文件的大小。在使用这个类之前,确保你已经允许了足够的 虚拟地址空间

  • hybridfs

    hybridfs类型是其混合niofsmmapfs,将选择用于基于所读取的访问模式每种类型的文件的最好的文件系统类型。目前只有 Lucene 术语字典、规范和文档值文件是内存映射的。所有其他文件都使用 Lucene 打开NIOFSDirectory。同样mmapfs要确保您已经允许大量的 虚拟地址空间

您可以通过设置来限制mmapfs和相关hybridfs商店类型的使用node.store.allow_mmap。这是一个布尔设置,指示是否允许内存映射。默认是允许的。此设置很有用,例如,如果您处于无法控制创建大量内存映射的能力的环境中,因此您需要禁用使用内存映射的能力。

将数据预加载到文件系统缓存中

这是一个专家设置,其细节将来可能会发生变化。

默认情况下,Elasticsearch 完全依赖操作系统文件系统缓存来缓存 I/O 操作。可以设置index.store.preload 以便告诉操作系统在打开时将热索引文件的内容加载到内存中。此设置接受以逗号分隔的文件扩展名列表:所有扩展名在列表中的文件将在打开时预加载。这对于提高索引的搜索性能很有用,尤其是在主机操作系统重新启动时,因为这会导致文件系统缓存被破坏。但是请注意,这可能会减慢索引的打开速度,因为它们只有在数据加载到物理内存后才可用。

4. Translog

对 Lucene 的更改仅在 Lucene 提交期间持久保存到磁盘,这是一项相对昂贵的操作,因此无法在每次索引或删除操作后执行。在进程退出或硬件故障的情况下,在一次提交之后和另一次提交之前发生的更改将被 Lucene 从索引中删除。

Lucene 提交太昂贵,无法对每个单独的更改执行,因此每个分片副本也会将操作写入其事务日志,称为 translog。所有的索引和删除操作都是在被内部Lucene索引处理之后,在没有被确认之前写入translog的。在发生崩溃的情况下,当分片恢复时,已确认但尚未包含在最后一次 Lucene 提交中的最近操作将从 translog 中恢复。

Elasticsearch刷新是执行 Lucene 提交并开始新的 translog 生成的过程。刷新是在后台自动执行的,以确保 translog 不会变得太大,这将使得在恢复期间重放其操作需要相当长的时间。手动执行刷新的能力也通过 API 公开,尽管很少需要这样做。

事务日志设置

translog 中的数据只有在 translog 被fsynced 和 commit时才会持久化到磁盘 。如果发生硬件故障或操作系统崩溃或 JVM 崩溃或分片故障,自上次 translog 提交以来写入的任何数据都将丢失。

默认情况下,index.translog.durability设置为request意味着 Elasticsearch 只会在 translogfsync在主服务器和每个分配的副本上成功编辑并提交后,才会向客户端报告索引、删除、更新或批量请求的成功。If index.translog.durability设置为asyncthen Elasticsearch fsyncs 并仅提交 translog index.translog.sync_interval,这意味着当节点恢复时,在崩溃之前执行的任何操作可能会丢失。

以下动态可更新的每个索引设置控制 translog 的行为:

  • index.translog.sync_interval

    fsync无论写操作 如何,translog 被写入磁盘并提交的频率。默认为5s. 100ms不允许小于的值。

  • index.translog.durability

    是否fsync在每次索引、删除、更新或批量请求后提交 translog。此设置接受以下参数:**request(默认)fsync并在每次请求后提交。在硬件故障的情况下,所有确认的写入都已经提交到磁盘。async**fsync并在后台提交每个sync_interval. 如果发生故障,自上次自动提交以来的所有已确认写入都将被丢弃。

  • index.translog.flush_threshold_size

    translog 存储所有尚未安全持久化在 Lucene 中的操作(即,不是 Lucene 提交点的一部分)。尽管这些操作可用于读取,但如果分片已停止且必须恢复,则需要重播这些操作。此设置控制这些操作的最大总大小,以防止恢复时间过长。一旦达到最大大小,就会发生刷新,生成一个新的 Lucene 提交点。默认为512mb.

5. 历史保留

Elasticsearch 有时需要重放在分片上执行的一些操作。例如,如果一个副本短暂离线,那么重放它离线时错过的一些操作可能比从头重建它更有效。类似地,跨集群复制的工作原理是在领导集群上执行操作,然后在跟随集群上重放这些操作。

在 Lucene 级别,Elasticsearch 对索引执行的写操作实际上只有两种:可能为新文档建立索引,或者可能删除现有文档。更新是通过原子地删除旧文档然后索引新文档来实现的。索引到 Lucene 中的文档已经包含重放该索引操作所需的所有信息,但对于文档删除而言并非如此。为了解决这个问题,Elasticsearch 使用了一种称为软删除的功能来保留 Lucene 索引中最近删除的内容,以便可以重放它们。

Elasticsearch 只保留索引中某些最近删除的文档,因为软删除的文档仍然占用一些空间。最终 Elasticsearch 将完全丢弃这些软删除的文档以释放该空间,以便索引不会随着时间的推移变得越来越大。幸运的是,Elasticsearch 不需要能够重放曾经在分片上执行过的每个操作,因为总是可以在远程节点上制作分片的完整副本。但是,复制整个分片可能比重放一些丢失的操作需要更长的时间,因此 Elasticsearch 会尝试保留它预计将来需要重放的所有操作。

Elasticsearch 使用一种称为分片历史保留租约的机制来跟踪它预计将来需要重播的操作。每个可能需要重放操作的分片副本必须首先为自己创建一个分片历史保留租约。例如,当使用跨集群复制时,此分片副本可能是分片的副本,也可能是跟随者索引的分片。每个保留租约都会跟踪相应分片副本尚未收到的第一个操作的序列号。当分片副本接收到新操作时,它会增加其保留租约中包含的序列号,以表明将来不需要重放这些操作。一旦软删除操作不被任何保留租约持有,Elasticsearch 就会丢弃这些操作。

如果分片副本失败,则它会停止更新其分片历史保留租约,这意味着 Elasticsearch 将保留所有新操作,以便在失败的分片副本恢复时可以重播。但是,保留租赁仅持续有限的时间。如果分片副本没有足够快地恢复,那么它的保留租约可能会过期。如果分片副本永久失败,这可以保护 Elasticsearch 免于永久保留历史记录,因为一旦保留租约到期,Elasticsearch 可以再次开始丢弃历史记录。如果分片副本在其保留租期到期后恢复,那么 Elasticsearch 将回退到复制整个索引,因为它不能再简单地重播丢失的历史记录。保留租约的到期时间默认为12h 对于大多数合理的恢复方案来说,这应该足够长。

默认情况下,软删除在最近版本中创建的索引上启用,但可以在索引创建时显式启用或禁用。如果软删除被禁用,那么有时仍然可以通过从 translog 复制丢失的操作来进行对等恢复 ,只要这些操作保留在那里。如果禁用软删除,则跨集群复制将不起作用。

6. 索引排序

在 Elasticsearch 中创建新索引时,可以配置每个 Shard 内的 Segment 的排序方式。默认情况下,Lucene 不应用任何排序。这些index.sort.*设置定义了应该使用哪些字段对每个 Segment 内的文档进行排序。

嵌套字段与索引排序不兼容,因为它们依赖于嵌套文档存储在连续 doc id 中的假设,这可能会被索引排序破坏。如果在包含嵌套字段的索引上激活索引排序,则会引发错误。

例如,以下示例显示了如何在单个字段上定义排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUT my-index-000001
{
"settings": {
"index": {
"sort.field": "date",
"sort.order": "desc"
}
},
"mappings": {
"properties": {
"date": {
"type": "date"
}
}
}
}

也可以按多个字段对索引进行排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
PUT my-index-000001
{
"settings": {
"index": {
"sort.field": [ "username", "date" ],
"sort.order": [ "asc", "desc" ]
}
},
"mappings": {
"properties": {
"username": {
"type": "keyword",
"doc_values": true
},
"date": {
"type": "date"
}
}
}
}
  • 该索引按顺序排序,username然后按date

  • username字段的升序和字段的降序date

索引排序支持以下设置:

  • index.sort.field

    用于对索引进行排序的字段列表。只有booleannumericdatekeyword与场doc_values这里是允许的。

  • index.sort.order

    用于每个字段的排序顺序。order 选项可以具有以下值:asc: 升序desc: 降序。

  • index.sort.mode

    Elasticsearch 支持按多值字段排序。mode 选项控制选择什么值来对文档进行排序。mode 选项可以具有以下值:min: 选择最低值。max: 选择最高值。

  • index.sort.missing

    missing 参数指定应如何处理缺少该字段的文档。缺失值可以具有以下值:_last: 没有字段值的文档排在最后。_first: 没有字段值的文档先排序。

索引排序只能在创建索引时定义一次。不允许在现有索引上添加或更新排序。索引排序在索引吞吐量方面也有成本,因为必须在刷新和合并时对文档进行排序。在激活此功能之前,您应该测试对您的应用程序的影响。

提前终止搜索请求

默认情况下,在 Elasticsearch 中,搜索请求必须访问与查询匹配的每个文档,以检索按指定排序排序的顶级文档。虽然当索引排序和搜索排序相同时,可以限制每个段应该访问的文档数量以检索全局排名前 N 的文档。例如,假设我们有一个索引,其中包含按时间戳字段排序的事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUT events
{
"settings": {
"index": {
"sort.field": "timestamp",
"sort.order": "desc"
}
},
"mappings": {
"properties": {
"timestamp": {
"type": "date"
}
}
}
}

此索引按时间戳降序排序(最近的在前)

您可以使用以下命令搜索最近 10 个事件:

1
2
3
4
5
6
7
GET /events/_search
{
"size": 10,
"sort": [
{ "timestamp": "desc" }
]
}

Elasticsearch 将检测每个段的顶部文档已经在索引中排序,并且只会比较每个段的前 N 个文档。收集与查询匹配的其余文档以计算结果总数并构建聚合。

如果您只查找最近 10 个事件并且对与查询匹配的文档总数不感兴趣,您可以将其设置track_total_hits 为 false:

1
2
3
4
5
6
7
8
GET /events/_search
{
"size": 10,
"sort": [
{ "timestamp": "desc" }
],
"track_total_hits": false
}

索引排序将用于对顶级文档进行排名,并且每个段将在前 10 个匹配后提前终止集合。

这一次,Elasticsearch 不会尝试计算文档数量,并且一旦每个段收集了 N 个文档,就能够终止查询。

1
2
3
4
5
6
7
8
9
{
"_shards": ...
"hits" : {
"max_score" : null,
"hits" : []
},
"took": 20,
"timed_out": false
}

由于提前终止,与查询匹配的总命中数未知。

聚合将收集与查询匹配的所有文档,而不管 track_total_hits

使用索引排序来加速连接

指数排序可以以组织Lucene的文档IDS有用(不要与混为一谈_id的方式,使连词(A和B …)更有效)。为了高效,连词依赖于这样一个事实:如果任何子句不匹配,那么整个连词也不匹配。通过使用索引排序,我们可以将不匹配的文档放在一起,这将有助于有效地跳过与连接不匹配的大范围文档 ID。

此技巧仅适用于低基数字段。一条经验法则是,您应该首先对基数较低且经常用于过滤的字段进行排序。排序顺序(ascdesc)并不重要,因为我们只关心将匹配相同子句的值彼此靠近。

例如,如果您正在为出售的汽车编制索引,那么按燃料类型、车身类型、品牌、注册年份和最后里程进行排序可能会很有趣。

7. 索引压力

将文档索引到 Elasticsearch 中会以内存和 CPU 负载的形式引入系统负载。每个索引操作包括协调、主要和副本阶段。这些阶段可以跨集群中的多个节点执行。

索引压力可以通过外部操作(例如索引请求)或内部机制(例如恢复和跨集群复制)累积。如果在系统中引入过多的索引工作,集群可能会变得饱和。这会对其他操作产生不利影响,例如搜索、集群协调和后台处理。

为了防止这些问题,Elasticsearch 在内部监控索引负载。当负载超过一定限制时,拒绝新的索引工作。

内存限制

indexing_pressure.memory.limit节点设置限制适用于优秀的索引请求的字节数。此设置默认为堆的 10%。

在每个索引阶段开始时,Elasticsearch 会计算索引请求消耗的字节数。此会计仅在索引阶段结束时发布。这意味着上游阶段将考虑听到的请求,直到所有下游阶段都完成。例如,协调请求将一直被考虑,直到主阶段和副本阶段完成。主请求将一直被考虑,直到每个同步副本响应以在必要时启用副本重试。

当未完成的协调、主要和副本索引字节数超过配置的限制时,节点将在协调或主要阶段开始拒绝新的索引工作。

当未完成的副本索引字节数超过配置限制的 1.5 倍时,节点将在副本阶段开始拒绝新的索引工作。这种设计意味着随着索引压力建立在节点上,它们自然会停止接受协调和主要工作,转而支持出色的副本工作。

indexing_pressure.memory.limit设置的 10% 默认限制非常大。只有在仔细考虑后才能更改它。只有索引请求会影响此限制。这意味着存在额外的索引开销(缓冲区、侦听器等),这些开销也需要堆空间。Elasticsearch 的其他组件也需要内存。将此限制设置得太高会拒绝其他操作和组件的操作内存。

分度压力设置

  • indexing_pressure.memory.limit *标志云*

    索引请求可能消耗的未完成字节数。当达到或超过此限制时,节点将拒绝新的协调和主要操作。当副本操作消耗此限制的 1.5 倍时,节点将拒绝新的副本操作。默认为堆的 10%。

监控

您可以使用 节点统计 API来检索索引压力指标。

4. 映射

5. 文本分析

6. 索引模版

7. 数据流

8. 摄取管道

9. 搜索您的数据

10. 查询DSL

11. 聚合

12. 均衡器

13. SQL

14. 脚本编写

15. 数据管理

16. ILM:管理索引生命周期

17. 自动缩放

18. 监控集群

19. 汇总或转换您的数据

20. 设置集群以实现高可用

21. 快照和恢复

22. 保护弹性堆栈

23. 守望者

24. 命令行工具

25. REST API

 评论