调整索引速度

edit

调整索引速度

edit

使用批量请求

edit

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

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

edit

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

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

与批量请求的规模类似,只有通过测试才能确定最佳的工人数量。这可以通过逐步增加工人数量来测试,直到集群上的I/O或CPU达到饱和。

取消或增加刷新间隔

edit

使更改对搜索可见的操作——称为刷新——是昂贵的,并且在有持续索引活动时频繁调用它可能会降低索引速度。

默认情况下,Elasticsearch 每隔一秒定期刷新索引,但仅在最近30秒内收到一次或多次搜索请求的索引上进行。

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

另一方面,如果你的索引经常收到搜索请求,这种默认行为意味着Elasticsearch将每1秒刷新你的索引。如果你能承受增加文档被索引和变得可见之间的时间,增加index.refresh_interval到一个较大的值,例如30s,可能会帮助提高索引速度。

禁用副本以进行初始加载

edit

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

如果在索引设置中配置了index.refresh_interval,在初始加载期间取消设置它可能会有所帮助,并在初始加载完成后将其恢复到原始值。

禁用交换

edit

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

将内存分配给文件系统缓存

edit

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

使用自动生成的ID

edit

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

使用更快的硬件

edit

如果索引操作是I/O密集型的,考虑增加文件系统缓存的大小(见上文)或使用更快的存储设备。Elasticsearch通常会创建具有顺序写入的单个文件。然而,索引操作涉及同时写入多个文件,并且还涉及随机和顺序读取的混合,因此固态硬盘(SSD)往往比机械硬盘(HDD)表现更好。

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

本地与远程存储

edit

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

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

索引缓冲区大小

edit

如果你的节点正在进行大量的索引操作,请确保 indices.memory.index_buffer_size 足够大,以便为每个进行大量索引的分片提供最多 512 MB 的索引缓冲区(超过这个大小,索引性能通常不会显著提升)。Elasticsearch 会根据这个设置(Java 堆内存的百分比或绝对字节大小),并将其作为所有活动分片之间的共享缓冲区。非常活跃的分片自然会比进行轻量级索引的分片使用更多的缓冲区。

默认值是 10%,这通常已经足够:例如,如果你给 JVM 分配了 10GB 的内存,它将分配 1GB 给索引缓冲区,这足以承载两个重度索引的分片。

使用跨集群复制防止搜索窃取索引的资源

edit

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

避免热点

edit

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

其他优化

edit

许多在《磁盘使用调优》中概述的策略也能提高索引速度。