Elasticsearch 的优化技巧 系列文章索引
这系列的文章主要的目的在於当我们开始使用 Elastic Stack 时,我们如何优化 Elasticsearch 的使用方式,包含 Indexing, Searching, Disk Usage, Shard Optimization 等四个主题。
这篇文章主要提供 Indexing 的效能优化的各种技巧与建议:
refresh_interval
以下会分别针对这些优化项目进行说明。
大量资料要 Indexing 时,使用 bulk 减少 round-trip overhead,至於 bulk request 要多大才是合适的?这个在不同的 Elasticsearch Cluster 硬体规格、不同的 Indexing 文件大小,所以还是要依照使用情境进行 Benchmark ,找到最合适的批次处理大小,另外官方有建议,bulk request 的资料量太大的话,大量的 bulk 请求同时进入 Elasticsearch 时,可能会吃光 Elasticsearch 的记忆体,所以一般不建议一个 bulk request 处理数十 MB 以上的资料。
使用 multi tread/worker 来处理 indexing 绝对比单一 thraed 能提高处理的效率,不过就像 bulk request 的调效一样,这个会是依照硬体配置有不同的最佳化配置方式,所以同样的会建议进行 Benchmark 来保确当下情境下合适的 thread 数量,并注意若是 Elasticsearch 丢出 TOO_MANY_REQUESTS (429)
的错误时,就已达到上线,应该要调整配置。
refresh_interval
在 Elasticsearch 的 Indexing 生命周期中,当不断的有资料 indexing 进入 Elasticsearch 时,一开始是写在 memory buffer 中的,而这时还无法被搜寻到 (如下图):
当 Elasticsearch 透过 refresh
的机制,将 In-memory buffer 的整理成 segment file,这时的状态就是能被搜寻到的 (下图中灰色的那块,因为还没进行 fsync
所以还没被 commit)。
Elasticsearch 预设的 refresh_interval
是 1s
,也就是一秒会进行一次处理,若是大量的资料在进行 indexing 时,可以将这个值调大,或甚至先暂时关闭,以提升 indexing 的效率。
这个配置的调整,有时能将 indexing 的效能提升一倍,不过一样是依照情境会有不一样的效果,但基本上都能有一定的成效。
这个设定的配置在 index.refresh_interval
,可参考 官方文件 - Index Module。
当我们在 indexing 资料进入 Elasticsearch 时,Elasticsearch 的 Routing 机制预设会让资料平均分配在各个 Shard 身上,以下图为例,可以想像左边是我们的 Coordinator node,当我们有两批资料要 bulk indexing 进入 ES,而在没有特别指定 Routing 的机制,所以每个资料被分配到不同的 shard 身上,这个例子我们有 4 个 Shards,所以每一批的处理,都会要分配到 4 个 Shards,这时 bulk 的处理就会要 4 个 Threads 来处理各个 Shard 的工作,2 批 bulk request 也就是总共有 8 个 Threads。
如果我们指定第一批的资料只会 Routing 到 Shard 1, 2,而第二批的资料只会 Routing 到 3, 4,这样 bullk 在处理时,就只会用到 2 个 Threads来进行这样的操作。(如下图)
可以看到这种例子时,Threads 数量就减少一半了,这部份的配置方式,请参考 官方文件 - Routing。
建议如果是一次性的 Indexing 一批资料进入 Elasticsearch,先将 index.number_of_replicas
设成 0
,在我们 Indexing 资料时, 让 Elasticseach 把资源用在处理 Indexing ,而不要在这个阶段就去进行 Replica 的处理,等到资料都 indexing 完成之後,再把这个配置改回我们原先的预期配置,再让 Elasticseach 进行 replication 的处理。
为了避免 JVM heap 被 swap 到 disk,而降低 Elasticsearch 的处理效率,这边建议关闭 swapping,这部份请直接参考 官方文件 - Disable swapping。
Elasticsearch 使用时,由於使用 Lucene 进行许多 Segment files 的处理,会需要用到大量 filesystem 的 memory buffer,因此官方的配置建议上,会建议 JVM Heap size v.s OS filesystem 各配置 50% 的记忆体大小,因此请确保 Filesystem 拥有足够的记忆体来处理 indexing 的 request。
Elasticsearch 在进行 Indexing 的处理时,会检查文件的 id 是否已存在於目前的 shard 当中,如果是使用 Elasticsearch auto-generated ids 时,由於这个 Id 的组成有包含的时间,所以 Elasticsearch 可以确保他产生时不会与现存的资料有重覆的情况,因此可以省略这个 id checking 的机制,这样会让 indexing 的速度有所提升。
Indexing 的处理是属於 I/O bound,在官方的建议配置上,会建议基本上要使用 SSD 等级的硬碟来当成 Elasticsearch 的储存硬体规格,而且使用 SSD 的配置,会让整体的 C/P 值会较高。
若是因资料量太大而有成本的考量,应该进一步再使用 Index Lifecycle Management 将 Indexing 完成的资料、或是较旧的资料,转移到较便宜的磁碟硬体状置上。
如果有大量的 indexing 的处理时,适时的调高 indices.memory.index_buffer_size
,这个值预设是 10%
的 JVM head size,这个 index buffer 是所有 active shard 共用的,所以若是有大量 indexing 处理时,也就会互相占用这个空间,所以确保 indexing 时影响的 shard 数量,并且配置足够的 index buffer size。
这个配置官方的建议是一个 shard 在 512MB 之内,若是超过的话效能一般不会有太明显的改善。
如果是持续不断的大量 indexing 资料进入 Elasticsearch 中,可以考虑使用 multi-cluster 的架构,将 indexing 的处理指向一个 Elasticsearch Cluster - A,而透过 cross-cluster replication 将资料 replica 到另一个 Elasticsearch Cluster - B,所有的 search 就指向 Elasticsearch Cluster - B,让 searching 的各种请求处理,不会占用到 indexing 的处理资源,确保 indexing 有独立不受影响的资源配置。
Elasticsearch 因为避免 process crash 时资料的遗失,会预设在每 5秒钟
、或是 memory size 达到 512mb
…等条件达到时执行 fsync,而这个处理的 Disk I/O 成本较高,因此在大量 indexing 资料时,而且这时期又允许接受系统 crash 时资料遗失的风险,可以将 index.translog.interval
和 index.translog.flush_threshold_size
的配置调高,以提升 indexing 的效率。
查看最新 Elasticsearch 或是 Elastic Stack 教育训练资讯: https://training.onedoggo.com
欢迎追踪我的 FB 粉丝页: 乔叔 - Elastic Stack 技术交流
不论是技术分享的文章、公开线上分享、或是实体课程资讯,都会在粉丝页通知大家哦!
此系列文章已整理成书
乔叔带你上手 Elastic Stack:Elasticsearch 的最佳实践与最佳化技巧
书中包含许多的修正、补充,也依照 Elastic 新版本的异动做出不少修改。
有兴趣的读者欢迎支持! 天珑书局连结
<<: 见习村27 - First non-repeating character
>>: Python - pandas (v) dataframe资料框
刚好有一道面试题目,不能使用 input type=date 或任何现有套件,要做出类似Datepi...
由於上一篇已经介绍过了 SPI 的 Timing Diagram,那麽今天就直接进入 I2C Mas...
URL : https://app.hackthebox.eu/machines/144 IP :...
一个模型到底学到了什麽东西一直都是一个研究课题,也是大家在意的,包括表徵学习、小样本学习、资料的偏差...
学习目标 本篇内容为阅读官方文件 Get data from a server 的笔记内容。 接续 ...