Elasticsearch是非常灵活且功能丰富的搜索引擎,提供了开箱即用的美好体验 。但是,在实战业务场景中,经常会出现远远低于预期的索引和查询速度 。
下面是针对Elasticsearch索引性能进行调优的建议 。
一、使用批量请求(bulk requests)批量请求将产生比单文档索引请求好得多的性能 。
为了知道批量请求的最佳大小,尝试在具有单个分片的单个节点上运行基准测试 。首先尝试索引100个文档,然后是200,然后是400,等等 。当索引速度开始稳定时,就达到了数据批量请求的最佳大小 。
一般而言,宁可批量索引文档少一些,而不是在太多文档的方向上犯错 。请注意,如果批量请求文档太大,可能会使Elasticsearch集群受到内存压力,因此建议避免每个请求超出几十兆字节,即使较大的请求看起来效果更好 。
二、使用多个工作者(workers)或线程向Elasticsearch发送数据发送批量请求的单个线程不太可能将Elasticsearch集群的索引容量最大化 。为了使用集群的所有资源,可以从多个线程或进程发送数据 。除了更好地利用集群的资源,这应该有助于降低每个fsync的成本 。
请注意TOO_MANY_REQUESTS(429)响应代码(JAVA客户端的EsRejectedExecutionException),这是Elasticsearch提示无法跟上当前索引速率的方式 。发生这种情况时,应该再次尝试暂停索引,理想情况下使用随机策略调整索引并发量 。
与调整批量请求(bulk request)大小类似,只有测试才能确定最佳的worker数量 。这可以通过逐渐增加工作者数量来测试,直到集群上的I/O或CPU饱和 。
三、调大refresh interval参数为了让索引文档对查询可见,需要执行refresh操作,该操作是有成本的 。当正在进行索引时,不断地执行refresh操作,将影响索引速度 。
默认的index.refresh_interval是1s,这迫使Elasticsearch每秒创建一个新的分段 。增加这个参数值(比如说30s)将提升索引速度 。
PUT INDEX-NAME/_settings
{
"refresh_interval" : "30s"
}
四、初始化数据加载临时禁用refresh和replicas如果需要一次加载大量数据,则应该将index.refresh_interval设置为-1,并将index.number_of_replicas设置为0,来禁用刷新(refresh) 。这会暂时使索引处于危险之中,因为任何分片的丢失都将导致数据丢失,但是同时索引将会更快,因为文档只被索引一次 。初始加载完成后,可以将index.refresh_interval和index.number_of_replicas设置回其原始值 。
五、禁用swApping交换内存通过禁止swap交换内存,确保操作系统不会交换出Java进程 。
具体禁用swapping的操作,可以参考下面链接:
https://www.elastic.co/guide/en/elasticsearch/reference/7.0/setup-configuration-memory.html
六、提供内存给filesystem cache文件系统缓存(filesystem cache)将用于缓冲I/O操作 。确保运行Elasticsearch的节点获得至少一半的主机内存,提供给filesystem cache 。
七、使用自动生成的id(auto-generated ids)索引具有显式id的文档时,Elasticsearch需要检查具有相同id的文档是否已经存在于相同的分片中,这是费时的操作,并且随着索引增长而变得更加费时 。通过使用自动生成的ID,Elasticsearch可以跳过这个检查,这使索引更快 。
PUT test-index
{
"settings":{
"number_of_shards": 3,
"number_of_replicas": 1
}
}
POST test-index/_doc
{
"sku": "002",
"title": "bbb"
}
GET test-index/_search
文章插图
八、使用更快的硬件一般而言,索引是I/O密集的,需要准备如下硬件:
(1)为filesystem cache分配更多的内存;
(2)使用SSD硬盘;
(3)使用local storage(不要使用NFS、SMB 等remote filesystem)
九、索引缓存区(Indexing buffer size)如果节点只做大量的索引,确保index.memory.index_buffer_size足够大,每个分片最多可以提供512 MB的索引缓冲区 。超过这一设置,索引性能通常也不会提升 。
Elasticsearch采用该设置(Java堆的百分比,或者绝对字节大小),并将其作为所有活动分片(active shards)的共享缓冲区 。非常活跃的分片自然比执行轻量级索引的分片,更多地使用这个缓冲区 。
默认设置为 10%,通常是足够的 。如我们给JVM 10GM内存,索引缓冲区将为1GB,这足以两个索引很重的分片 。
【Elasticsearch调优索引速度-最佳实践】
推荐阅读
- SQL 中判断条件的先后顺序,会引起索引失效吗?
- 搜索引擎蜘蛛的作用是什么?
- MySQL索引背后的数据结构及算法原理
- 通用搜索引擎背后的技术点
- MySQL索引怎么用?究竟能有多快?看完这篇你就懂了
- MySQL,合理的使用索引结构和查询
- MySQL进阶篇 | 合理的使用索引结构和查询
- ElasticSearch 索引设置总结
- 「系统架构」Elasticsearch是如何保证数据的一致性和实时性的
- 还不知道MySQL怎么给字符串加索引?