《Elasticsearch从开始到优化:性能优化》

Elasticsearch默认配置提供了良好的开箱即用的体验。但在不同的场景下,也有许多优化方法来提高Elasticsearch的性能。

通用建议

不要返回大的查询结果集

如果需要,使用 scroll 接口。

避免大文档

Elasticsearch和Lucene都有文档大小限制。大的文档会造成更多的网络、内存、磁盘的消耗,影响索引和搜索速度。

避免稀疏

Elasticsearch依赖Lucene来进行索引和存储数据,Lucene背后的数据结构在密集数据时工作的最好。尽量同一个索引下文档结构相同,避免稀疏,相关建议:

1.同一个索引里避免放入不相关的文档

2.标准化文档结构

3.同一个索引避免不同类型

4.对稀疏字段禁用 normsdoc_values
用于过滤不需要需要打分的字段,禁用 norms。不被用于排序和聚合的字段,禁用 doc_values

索引速度优化

使用bulk请求

bulk请求性能远高于单文档索引请求。并不是每次bulk越多文档越好,可对节点进行测试,找出每次最佳bulk文档数。

使用多进程/线程向Elasticsearch发送数据

单线程bulk请求不太可能达到集群最大索引能力。所以使用多进程/线程,可以测试找出最优进程/线程数量。

增加刷新间隔

Elasticsearch 默认刷新间隔index.refresh_interval是1s,意味着每秒都会强制Elasticsearch创建segment,以便索引的文档能够被搜索到。增加刷新间隔降低创建segment频率,使写入磁盘的segment更大,并且减小未来segmeng合并的压力。

禁止刷新和复制

当需要大量加载数据时,禁止刷新和复制,可以数倍提供索引速度。设置刷新间隔index.refresh_interval为-1,副本数index.number_of_replicas为0,便可禁止刷新和复制。禁止复制时,副本数为0,可能导致数据丢失。数据加载完成后,便可将两个参数调整为原来的值。

禁止swapping

swapping(内存交换)会导致JVM heap被交换到磁盘上,导致很差的性能和节点稳定性。应该不惜一切代价禁止swapping。

确保有空闲内存用于文件系统缓存

文件系统缓存用于缓冲IO操作,确保至少一半内存用于文件系统缓存。

使用自动生成的id

索引一个文档时显示指定id,Elasticsearch会检查分片内是否有相同的id, 索引越大,这个代价就越高。

使用更快的硬件

使用更快的磁盘,使用本地存储。

索引缓冲区大小

确保重索引操作的shard的缓冲区indices.memory.index_buffer_size足够大。

搜索速度优化

确保有空闲内存用于文件系统缓

Elasticsearch严重依赖文件系统缓存来保证快速搜索。

使用更快的硬件

如果搜索瓶颈在I/O,那就分配更大的文件系统缓存,使用更快的存储。如果搜索瓶颈在CPU,那就使用更快的cpu。

文档建模

使用合理的文档模型,避免join操作,嵌套使查询慢数倍,父子关系使查询慢百倍。

预热文件系统缓存

通过配置index.store.preload 告诉操作系统哪些文件需要被加载到内存中。谨慎使用,避免出现文件太大,文件系统缓存不够加载的情况,会导致搜索变慢。

查询语法优化

使用过滤上下文filter context,常用的过滤器会被Elasticsearch缓存,提高性能。

使用routing

Elasticsearch默认使用文档的id进行routing,将文档映射到某个shard上。索引时可以根据文档的某个字段进行routing,搜索时指定routing便可到相应的shard上搜索,提高搜索速度,同时大大降低集群资源的使用。

分索引

索引越来越大,shard也越来越大,查询速度越来越慢。Elasticsearch不提供shard split的功能,可以创建新索引,保证单个索引不会太大。

.
.
.

改变自己,改变世界,支持我吧!