调整索引速度

编辑

使用批量请求

编辑

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

使用多个工作线程/线程向 Elasticsearch 发送数据

编辑

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

请务必注意 TOO_MANY_REQUESTS (429) 响应代码(Java 客户端中的 EsRejectedExecutionException),这是 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 通过跨节点同步来维护集群状态,因此持续出现热点的节点可能会导致整体集群性能下降。

其他优化

编辑

调整磁盘使用率中概述的许多策略也提供了索引速度的提高。