1. 使用bulk请求
批量请求将产生比单文档索引请求更好的性能。
如何确认批量请求的最佳大小?在带有单个shard的节点上,尝试一次索引100个文档,然后是200,然后是400,将批量请求中的文档数量增加一倍。当索引速度开始趋于平稳时,即数据的批量请求的最佳大小。
Tips:当许多请求并发地发送时,过大的批量请求可能会使集群处于内存压力之下,因此最好避免在每次请求时超过几十兆字节,即使较大的请求看起来性能更好
2. 使用多个线程发送数据至Elasticsearch
发送大量请求的单个线程不太可能最大限度地完全使用ES的索引容量。为了使用集群的所有资源,可以从多个线程或进程发送数据。除了更好地利用集群的资源之外,这应该有助于降低每个fsync的成本。
与批量请求相似,只有测试才能确定最佳线程数量。这可以通过逐步增加线程数量来测试,直到集群上的I/O或CPU饱和为止。
Tips:请务必注意 TOO_MANY_REQUESTS(429)响应码(Java客户机的EsRejectedExecutionException),这是Elasticsearch提示它无法跟上当前索引率的方式。
3. 增加refresh interval的值
默认的refresh_interval值为1,这使搜索每秒钟创建一个新的segment。增加这个值(比如30s)将允许更大的segment刷新并减少未来的合并压力。
4. 关闭refresh interval和 副分片
如果需要一次加载大量数据,应该通过设置索引来禁用refresh。refresh_interval设置为-1,并设置索引的number_of_replicas为0。这将暂时使索引处于危险之中,因为任何shard丢失都将导致数据丢失,但是与此同时索引速度将更快,因为文档将只被索引一次。一旦初始加载完成,就可以设置索引的refresh_interval,number_of_replicas回到原始值。
5. 关闭操作系统swapping
内存交换到磁盘对性能是致命的。
6. 给足内存至文件系统缓存
文件系统缓存将用于缓冲I/O操作。您应该确保在文件系统缓存至少使用机器一半的内存。
7. 使用自动生成的标识id
当索引具有显式id的文档时,Elasticsearch需要检查具有相同id的文档是否已经存在于相同的shard中,这是一个代价高昂的操作,并且随着索引的增长,代价会更高。通过使用自动生成的id,ES可以跳过这个检查,这使得索引更快。
8. 使用更快的硬件
9. 调整indexing_buffer_size
如果节点只执行繁重的索引,请确保indices.memory.index_buffer_size足够大,可以在每个shard上提供最多512 MB的索引缓冲区进行繁重索引的任务。
默认值是10%,通常情况下这已经算很多了。例如,如果您给JVM 10GB的内存,它将给索引缓冲区1GB,这足以hold住两个正在大量索引的shard。