别再说你不会 ElasticSearch 调优了,都给你整理好了

作者:Ghost Stories原文:http://wangnan.tech/post/elasticsearch-how-to/

别再说你不会 ElasticSearch 调优了,都给你整理好了

文章插图
 
ES 发布时带有的默认值,可为 ES 的开箱即用带来很好的体验 。全文搜索、高亮、聚合、索引文档 等功能无需用户修改即可使用,当你更清楚的知道你想如何使用 ES 后,你可以作很多的优化以提高你的用例的性能,下面的内容告诉你 你应该/不应该 修改哪些配置 。
第一部分:调优索引速度
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html
使用批量请求批量请求将产生比单文档索引请求好得多的性能 。
为了知道批量请求的最佳大小,您应该在具有单个分片的单个节点上运行基准测试 。首先尝试索引100个文件,然后是200,然后是400,等等 。当索引速度开始稳定时,您知道您达到了数据批量请求的最佳大小 。在配合的情况下,最好在太少而不是太多文件的方向上犯错 。请注意,如果群集请求太大,可能会使群集受到内存压力,因此建议避免超出每个请求几十兆字节,即使较大的请求看起来效果更好 。
发送端使用多worker/多线程向es发送数据,发送批量请求的单个线程不太可能将Elasticsearch群集的索引容量最大化 。为了使用集群的所有资源,您应该从多个线程或进程发送数据 。除了更好地利用集群的资源,这应该有助于降低每个fsync的成本 。
请确保注意TOO_MANY_REQUESTS(429)响应代码(JAVA客户端的EsRejectedExecutionException),这是Elasticsearch告诉您无法跟上当前索引速率的方式 。发生这种情况时,应该再次尝试暂停索引,理想情况下使用随机指数回退 。
与批量调整大小请求类似,只有测试才能确定最佳的worker数量 。这可以通过逐渐增加工作者数量来测试,直到集群上的I / O或CPU饱和 。
调大 refresh interval 。默认的index.refresh_interval是1s,这迫使Elasticsearch每秒创建一个新的分段 。增加这个价值(比如说30s)将允许更大的部分flush并减少未来的合并压力 。
加载大量数据时禁用refresh和replicas 。如果您需要一次加载大量数据,则应该将index.refresh_interval设置为-1并将index.number_of_replicas设置为0来禁用刷新 。这会暂时使您的索引处于危险之中,因为任何分片的丢失都将导致数据 丢失,但是同时索引将会更快,因为文档只被索引一次 。初始加载完成后,您可以将index.refresh_interval和index.number_of_replicas设置回其原始值 。
设置参数,禁止OS将es进程swap出去
您应该确保操作系统不会swApping out the java进程,通过禁止swap
https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html
为filesystem cache分配一半的物理内存
文件系统缓存将用于缓冲I / O操作 。您应该确保将运行Elasticsearch的计算机的内存至少减少到文件系统缓存的一半 。
使用自动生成的id(auto-generated ids)
索引具有显式id的文档时,Elasticsearch需要检查具有相同id的文档是否已经存在于相同的分片中,这是昂贵的操作,并且随着索引增长而变得更加昂贵 。通过使用自动生成的ID,Elasticsearch可以跳过这个检查,这使索引更快 。
买更好的硬件
搜索一般是I/O 密集的,此时,你需要
a.为filesystem cache分配更多的内存
b.使用SSD硬盘
c.使用local storage(不要使用NFS、SMB 等remote filesystem)
d.亚马逊的 弹性块存储(Elastic Block Storage)也是极好的,当然,和local storage比起来,它还是要慢点,如果你的搜索是 CPU-密集的,买好的CPU吧
加大 indexing buffer size
如果你的节点只做大量的索引,确保index.memory.index_buffer_size足够大,每个分区最多可以提供512 MB的索引缓冲区,而且索引的性能通常不会提高 。Elasticsearch采用该设置(java堆的一个百分比或绝对字节大小),并将其用作所有活动分片的共享缓冲区 。非常活跃的碎片自然会使用这个缓冲区,而不是执行轻量级索引的碎片 。
默认值是10%,通常很多:例如,如果你给JVM 10GB的内存,它会给索引缓冲区1GB,这足以承载两个索引很重的分片 。
禁用_field_names字段
_field_names 字段引入了一些索引时间开销,所以如果您不需要运行存在查询,您可能需要禁用它 。
_field_names:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-field-names-field.html
剩下的,再去看看 “调优 磁盘使用”吧
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html 中有许多磁盘使用策略也提高了索引速度 。


推荐阅读