索引速率调优

使用批量请求

Bulk requests(批量请求)_会比单文档索引请求性能更优。确认_bulk requests( 批量请求)_的最佳大小,要在单个节点上使用单个分片进行基准测试来获取。首先尝试一次性索引 100 个 _documents(文档),然后200个,然后400个;在每个基准测试中,下一次索引的 documents(文档)数是上一次的两倍。当索引速率达到最高时,就可以确认每次 _bulk requests( 批量请求)_的最佳 _documents(文档)_数大小了。在领带情况下,最好是发生的错误越少越好而不是索引的_documents(文档)_越多越好。当心,很多客户端同时发送数据产生非常大的 _bulk requests( 批量请求)_使集群处在内存压力下;即使看起来较大的请求会更好,还是建议每个请求不要超出几十兆字节。

使用多线程向Elasticsearch发送数据

单线程的 bulk requests( 批量请求)_达不到 _Elasticsearch 集群的最大索引性能。为了充分利用集群的资源,应该使用多个线程或进程发送数据。除了更好地利用集群的资源外,这也有助于降低每个 fsync 的成本。当你看到TOO_MANY_REQUESTS(429)响应代码(EsRejectedExecutionException with the Java client),这是 Elasticsearch 告诉您无法跟上当前索引速率了。当这种情况发生的时候,先暂停索引一会,然后再次尝试,

ideally with randomized exponential backoff(理论上会有随机指数回退)。类似于调整_ bulk requests( 批量请求)的大小,只有通过测试才可以知道最适合的线程数。 这个可以通过逐渐增加线程的数量进行测试,直到集群上的 _I / O 或 CPU 饱和为止。

增大刷新间隔

默认  index.refresh_interval 是 1s,它将强制 Elasticsearch 每秒创建一个新的 segment ,增加这个值(比如 30s),允许生成较大的 segment 再刷新,将会减少将来合并的压了。 

禁用初始加载的刷新和副本

如果需要一次加载大量的数据,禁用刷新功能和副本通过设置 index.refresh_interval-1 并且设置 index.number_of_replicas0。 这将暂时使您的索引处于风险之中,因为丢失任何_ shard(分片)会导致数据丢失,但与此同时索引的更快,因为文档将仅被索引一次。一旦初始化加载完成,就可以把 index.refresh_interval 和 index.number_of_replicas _改回正常值。

禁用swapping

通过禁用交换分区来确保操作系统没有交换出java进程。

给文件系统缓存提供内存

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

使用自动生成的id

当索引一个带有 iddocument (文档)_时,_Elasticsearch 要检查在相同的 shard(分片)_上是否还有相同 _iddocument (文档)_存在,这个操作需要的花费很大,随着索引的增长操作需要的花费将会越来越大。通过使用自动生成的_idElasticsearch 可以跳过此检查,这使索引更快。

使用更快的硬件

如果索引受限于 I/O ,应该增加文件系统缓存的内存(见上文)或者购买更快的驱动设备。特别是 SDD 硬盘比普通硬盘性能更好。通常数据存储在本地,避免使用 NFS & SMB 等远程文件系统。还要小心虚拟化存储,像亚马逊的 弹性块存储Elastic Block Storage)。Elasticsearch 在虚拟存储上也有比较好的性能,具有搜索快,安装便捷的特性;然而相对于本地专用存储,他就要慢的多了。如果你在 EBS_上使用 _index ,_一定要使用 _IOPS 否则操作会很快挂掉。

通过配置RAID 0阵列,将您的索引分离到多个 SSD 。但是,这将增加失败的风险,因为任何一个 SSD 的失败都将破坏这个索引。然而,权衡之后做出如下策略:优化单个分片以实现最佳性能,然后在不同节点之间添加副本,以便任何节点故障都有冗余。您还可以使用快照和还原来备份索引进行进一步的保险。

索引缓冲区大小

如果您的节点仅进行大量索引,请确保 indices.memory.index_buffer_size 足够大,以至于每个 shard(分片)_最多可以为 512 MB 索引缓冲区进行大量索引(超出索引性能通常不会改善)。_Elasticsearch 采用该设置(java堆的百分比或绝对的字节大小),并将其用作所有活动 shard(分片)_的共享缓冲区。非常活跃的 _shard(分片)_自然会使用这个缓冲区,而不是执行少量索引的 _shard(分片)。 

通常这个默认值为10%,已经非常富余了:例如,如果给予JVM 10GB内存,则它将向索引缓冲区提供1GB,这足够两个大量索引的 shard(分片)

额外优化

调整磁盘使用的策略,也能提高索引的速率。