调整索引速度编辑

使用批量请求编辑

批量请求的性能远优于单个文档索引请求。为了确定最佳批量请求大小,您应该在单个节点和单个分片上运行基准测试。首先尝试一次索引 100 个文档,然后是 200 个,然后是 400 个,依此类推,在每次基准测试运行中将批量请求中的文档数量翻倍。当索引速度开始趋于平稳时,您就知道已经达到了数据最佳批量请求大小。如果出现平局,最好选择过少而不是过多文档。请注意,当许多大型批量请求同时发送时,它们可能会给集群带来内存压力,因此建议即使较大的请求似乎性能更好,也要避免超过每个请求几十兆字节。

使用多个工作线程/线程将数据发送到 Elasticsearch编辑

单个线程发送批量请求不太可能最大限度地利用 Elasticsearch 集群的索引能力。为了使用集群的所有资源,您应该从多个线程或进程发送数据。除了更好地利用集群的资源外,这还有助于降低每次 fsync 的成本。

确保注意 TOO_MANY_REQUESTS (429) 响应代码(EsRejectedExecutionException 与 Java 客户端),这是 Elasticsearch 通知您无法跟上当前索引速度的方式。发生这种情况时,您应该暂停索引一段时间,然后再尝试,理想情况下使用随机指数退避。

与调整批量请求大小类似,只有测试才能确定最佳工作线程数量。可以通过逐步增加工作线程数量来测试,直到集群的 I/O 或 CPU 饱和为止。

取消设置或增加刷新间隔编辑

使更改对搜索可见的操作(称为 刷新)成本很高,并且在进行索引活动时频繁调用它会影响索引速度。

默认情况下,Elasticsearch 每秒定期刷新索引,但仅针对在过去 30 秒内收到一个或多个搜索请求的索引。

如果您没有或很少有搜索流量(例如,每 5 分钟少于一个搜索请求)并且想要优化索引速度,这是最佳配置。此行为旨在自动优化默认情况下未执行搜索时的批量索引。为了选择退出此行为,请显式设置刷新间隔。

另一方面,如果您的索引经常收到搜索请求,则此默认行为意味着 Elasticsearch 将每 1 秒刷新一次您的索引。如果您能够承受在文档被索引和变得可见之间增加的时间量,则将 index.refresh_interval 增加到更大的值(例如 30s)可能有助于提高索引速度。

禁用初始加载的副本编辑

如果您有一大批数据要一次性加载到 Elasticsearch 中,将 index.number_of_replicas 设置为 0 可能有利于加快索引速度。没有副本意味着丢失单个节点可能会导致数据丢失,因此重要的是数据存储在其他地方,以便在出现问题时可以重试此初始加载。初始加载完成后,您可以将 index.number_of_replicas 设置回其原始值。

如果在索引设置中配置了 index.refresh_interval,则在初始加载期间将其取消设置并在初始加载完成后将其设置回其原始值可能会有进一步的帮助。

禁用交换编辑

您应该确保操作系统不会通过 禁用交换 将 java 进程交换出去。

为文件系统缓存分配内存编辑

文件系统缓存将用于缓冲 I/O 操作。您应该确保为运行 Elasticsearch 的机器至少分配一半的内存给文件系统缓存。

使用自动生成的 ID编辑

在索引具有显式 ID 的文档时,Elasticsearch 需要检查同一分片中是否已存在具有相同 ID 的文档,这是一个成本很高的操作,并且随着索引的增长而变得更加昂贵。通过使用自动生成的 ID,Elasticsearch 可以跳过此检查,从而使索引速度更快。

使用更快的硬件编辑

如果索引受 I/O 限制,请考虑增加文件系统缓存的大小(见上文)或使用更快的存储。Elasticsearch 通常会创建具有顺序写入的单个文件。但是,索引涉及同时写入多个文件,以及混合随机和顺序读取,因此 SSD 驱动器往往比旋转磁盘性能更好。

通过配置 RAID 0 阵列,将您的索引条带化到多个 SSD 上。请记住,这会增加失败的风险,因为任何一个 SSD 的故障都会破坏索引。但是,这通常是正确的权衡:优化单个分片以获得最大性能,然后在不同的节点上添加副本,以便在任何节点发生故障时都有冗余。您还可以使用 快照和恢复 来备份索引以获得进一步的保障。

本地存储与远程存储编辑

直接连接(本地)存储通常比远程存储性能更好,因为它更易于配置,并且避免了通信开销。

一些远程存储的性能非常差,尤其是在 Elasticsearch 施加的负载下。但是,通过仔细调整,有时也可以使用远程存储来实现可接受的性能。在确定特定的存储体系结构之前,请使用实际工作负载对系统进行基准测试,以确定任何调整参数的影响。如果您无法获得预期的性能,请与存储系统供应商合作以确定问题。

索引缓冲区大小编辑

如果您的节点只进行繁重的索引,请确保 indices.memory.index_buffer_size 足够大,以便为每个进行繁重索引的分片(超过此值,索引性能通常不会提高)提供最多 512 MB 的索引缓冲区。Elasticsearch 会获取该设置(java 堆的百分比或绝对字节大小),并将其用作所有活动分片之间的共享缓冲区。非常活跃的分片自然会比执行轻量级索引的分片更多地使用此缓冲区。

默认值为 10%,这通常已经足够了:例如,如果您为 JVM 提供 10GB 的内存,它将为索引缓冲区提供 1GB,这足以容纳两个正在进行大量索引的分片。

使用跨集群复制来防止搜索从索引中窃取资源编辑

在单个集群内,索引和搜索会争夺资源。通过设置两个集群,配置 跨集群复制 将数据从一个集群复制到另一个集群,并将所有搜索路由到包含跟随者索引的集群,搜索活动将不再从托管领导者索引的集群中窃取索引资源。

避免热点编辑

热点 可能会发生在节点资源、分片或请求没有均匀分布的情况下。Elasticsearch 通过在节点之间同步集群状态来维护集群状态,因此持续的热点节点会导致整体集群性能下降。

其他优化编辑

调整磁盘使用量 中概述的许多策略也可以提高索引速度。