操作系统参数设置
遵照官网文档的建议设置所有的系统参数
参见文档,"Setup Elasticsearch -> Important System Configuration"。
例如:关掉swap、增大文件描述符等。
es elasticsearch.yml设置
elasticsearch.yml中尽量只写必备的参数,其他可以通过api动态设置的参数,都通过api来设定。
参见文档"Setup Elasticsearch -> Important Elasticsearch Configuration"
随着es的版本升级,很多网络流传的配置参数已不在支持,因此不要随便复制别人的集群配置参数。
建议设置的参数
动态设定参数有transient和persistent两种设置,前者在集群重启后丢失,后者不会,但两种设定都会覆盖elasticsearch.yml中的配置。
关于JVM的设定
不要超过31GB。
预留一半内存给操作系统,用来做文件缓存。
具体的大小根据该node要存储的数据量来估算,为了保证性能,在内存和数据量之间有一个建议比例。
搜索类项目的比例建议在1:16以内。
日志类项目的比例建议在1:48~1:96之间。
假设总数据量大小为1TB,3个node,一个副本,那么每个node要存储的数据量为2TB/3约等于666G,即700G左右,做20%的预留空间,每个node要存储大约850G的数据。
如果是搜索类项目,每个node内存大小为850G/16=53GB,大于31GB。31GB*16=496GB,即每个node最多存储496GB的数据,所以需要至少5个node。
如果是日志类项目,每个node内存大小为850GB/48=18GB,因此3个节点足够。
写性能优化
写数据过程包括如下3个:
refresh
translog
flush
refresh过程
segment写入磁盘的过程依然很耗时,可以借助文件系统缓存的特性,先将segment在缓存中创建并开放查询来进一步提升实时性,该过程在es中被称为refresh。
在refresh之前文档会先存储在一个buffer中,refresh时将buffer中的所有文档清空并生成segment。
es默认一秒执行一次refresh,因此文档的实时性被提高到1秒,这也是es被称为近实时(near real time)的原因。
translog过程
如果在内存中的segment还没有写入到磁盘前发生了宕机,那么其中的文档就无法恢复了,如何解决这个问题?
es引入了translog机制。写入文档到buffer时,同时写入translog。
translog文件会同步的写入到磁盘,6.x以后的版本默认每个请求都会落盘,可以修改为每5秒写一次,这样就会在发生宕机时最多只丢5秒以内的数据,同时提升了写的性能。相关配置在index.translog.*。
es启动时会检查translog文件,并从中恢复数据。
flush过程
flush负责将内存中segment写入到磁盘,主要作如下工作:
将translog写入到磁盘(伴随操作,异步写入translog时有意义)。
将index buffer清空,其中的一个文档生成新的segment,相当于一个refresh操作(伴随操作)。
更新commit point并写入到磁盘。
执行fsync操作,将内存中的segment写入到磁盘。
删除旧的translog文件。
写性能优化目标:
目标是增大写的吞吐量,EPS(events per second)越高越好。
优化方案。
客户端多线程写,批量写。
es:在高质量的数据模型的前提下,主要在refresh、translog、flush上做文章。
写性能优化-refresh
目标为奖励refresh的频率,降低实时性,以增大每一次refresh处理的文档数,默认是1s,设置为-1直接禁止自动refresh。
增大index buffer的size,参数为indices.memery.index_buffer_size(静态参数,需要设定在elasticsearch.yml中,默认是10%)。
写性能优化-translog
目标是降低translog写磁盘的频率,从而提高写效率,但会降低容灾能力
index.translog.durability这只为async,index.translog.sync_interval设置为需要的大小,比如120秒,那么translog会每120秒写入一次磁盘。
index.translog.flush_threshold_size默认为512mb,即tranlog超过该大小会触发一次flush操作,那么调大该值可以避免flush的频繁发生。
写性能优化-flush
目标位降低flush的次数,在6.x以后可优化的空间不大,多为es自动完成。
合理设计shard数,并保证shard均匀的分配到所有node上,充分利用所有node的资源。
index级别的优化,以日志场景举例,一般会有如下索引设定:
读性能优化
读性能主要受以下几个方面影响:
数据模型是否符合业务模型。
数据规模是否过大。
索引配置是否优化。
查询语句是否优化。
读数据优化-数据模型
高质量的数据模型是优化的基础。
将需要通过script计算的值提前计算好作为字段存到文档中。
尽量使得数据模型贴近业务模型。
读数据优化-数据规模
根据不同的数据规模设定不痛的SLA。上万条数据与上千万数据性能肯定存在差异。
读数据优化-索引配置调优
索引配置主要包括如下:
根据数据规模设置合理的主分片数,可以通过测试得到最合理的分片数。
设置合理的副本数目,不是越多越好。
读数据优化-查询语句调优
查询语句调优主要有如下几种常见手段:
尽量使用fliter上下文,减少算分的场景,由于filter有缓存机制,可以极大的提高查询性能。
尽量不使用script进行字段计算或者算分排序等。
结合profile、explain API分析满查询语句的症结所在,然后在去优化它的数据模型。