集群部署优化建议
选择合理的硬件配置:尽可能使用SSD
Elasticsearch 最大的瓶颈往往是磁盘读写性能,尤其是随机读取性能。使用SSD(PCI-E接口SSD卡/SATA接口SSD盘)通常比机械硬盘(SATA盘/SAS盘)查询速度快5~10倍,写入性能提升不明显。
对于文档检索类查询性能要求较高的场景,建议考虑 SSD 作为存储,同时按照 1:10 的比例配置内存和硬盘。
对于日志分析类查询并发要求较低的场景,可以考虑采用机械硬盘作为存储,同时按照 1:50 的比例配置内存和硬盘。
单节点存储数据建议在2TB以内,不要超过5TB,避免查询速度慢、系统不稳定。
给JVM配置机器一半的内存,但是不建议超过32G
修改 conf/jvm.options 配置,-Xms 和 -Xmx 设置为相同的值,推荐设置为机器内存的一半左右,剩余一半留给操作系统缓存使用。
JVM 内存建议不要低于 2G,否则有可能因为内存不足导致 ES 无法正常启动或内存溢出,JVM 建议不要超过 32G,否则 JVM 会禁用内存对象指针压缩技术,造成内存浪费。
机器内存大于 64G 内存时,推荐配置 -Xms30g -Xmx30g。
JVM 堆内存较大时,内存垃圾回收暂停时间比较长,建议配置 ZGC 或 G1 垃圾回收算法。
规模较大的集群配置专有主节点,避免脑裂问题
Elasticsearch 主节点负责集群元信息管理、index 的增删操作、节点的加入剔除,定期将最新的集群状态广播至各个节点。
在集群规模较大时,建议配置专有主节点只负责集群管理,不存储数据,不承担数据读写压力。
具体配置如下:
# 专有主节点配置(conf/elasticsearch.yml): node.master: true node.data: false node.ingest: false # 数据节点配置(conf/elasticsearch.yml): node.master: false node.data: true node.ingest: true 复制代码
Elasticsearch 默认每个节点既是候选主节点,又是数据节点。最小主节点数量参数 minimum_master_nodes 推荐配置为候选主节点数量一半以上,该配置告诉 Elasticsearch 当没有足够的 master 候选节点的时候,不进行 master 节点选举,等 master 节点足够了才进行选举。
例如对于 3 节点集群,最小主节点数量从默认值 1 改为 2。
# 最小主节点数量配置(conf/elasticsearch.yml): discovery.zen.minimum_master_nodes: 2 复制代码
Linux操作系统调优
关闭交换分区,防止内存置换降低性能。
具体配置如下:
# 将 /etc/fstab 文件中包含swap的行注释掉 sed -i '/swap/s/^/#/' /etc/fstab swapoff -a # 单用户可以打开的最大文件数量,可以设置为官方推荐的65536或更大些 echo "* - nofile 65536" >> /etc/security/limits.conf # 单用户线程数调大 echo "* - nproc 131072" >> /etc/security/limits.conf # 单进程可以使用的最大map内存区域数量 echo "vm.max_map_count = 655360" >> /etc/sysctl.conf # 参数修改立即生效 sysctl -p 复制代码
索引性能调优建议
严格设置存储和索引开关,不要将数据全部存储或者全部索引
Elasticsearch支持持久化和索引,但是Elasticsearch主要场景是全文检索,成本昂贵。建议根据业务只将需要索引的Field进行索引,不仅节省索引成本,而且在操作时速度更快、效率更高!
禁止使用多type索引 ,避免索引稀疏
Elasticsearch支持对同一个索引,划分不同的type进行读写,数据以type级别进行隔离。但是Elasticsearch多type索引共用_id,其version往往容易产生冲突,而且6.x版本开始逐渐转向单type索引的设计,7.x之后将不再支持多type索引。
分片数根据业务数据量和集群规模进行设置
Elasticsearch默认分片数是5, 不同的业务索引分片数应该根据实际情况进行设置,如果索引数据量特别小且未来的增量有限,可以适当减少分片数,因为分片作为Elasticsearch集群的元数据在分片数很多的情况下,集群的同步管理和故障恢复会存在一定的风险。
如果索引数据量特别大,需要根据数据量和集群规模进行设置,一个分片建议在10亿级别,最大数据量建议是40亿。同时分片数也受集群规模影响,集群节点数太少不宜设置过多的分片数,会导致同一个索引的多个分片存在于一个Elasticsearch节点中,出现故障恢复较慢。
您可以在集群节点上保存的分片数量与您可用的堆内存大小成正比,但这在Elasticsearch中没有的固定限制。 一个很好的经验法则是:确保每个节点的分片数量保持在低于每1GB堆内存对应集群的分片在20-25之间。 因此,具有30GB堆内存的节点最多可以有600-750个分片,但是进一步低于此限制,您可以保持更好。 这通常会帮助群体保持处于健康状态。
副本数不大于3
Elasticsearch默认副本数是1,即存在1个primary和1个replica共两份数据,主备形式同步,为了提升数据的安全性,避免数据丢失,可以设置副本数为2,即存在1个primary和两个replica共三份数据。但是没有必要设置过大的副本数,Elasticsearch的复制会对集群性能产生影响,特别是refresh_interval设置比较小的集群。
禁止自动创建索引
Elasticsearch的索引默认可以自动创建,必须禁用掉。
自动创建索引无法避免误操作带来的元数据治理问题,设置action.auto_create_index
为false
。
创建完索引,禁用掉自动类型mapping
Elasticsearch的索引默认可自动类型mapping,必须禁用掉。自动创建mapping会带来类型与实际类型不匹配的问题,设置index.mapper.dynamic
为false
。
字符串mapping设置,优先使用keyword
Elasticsearch的索引默认支持keyword和text,text用于分词场景,keyword不支持分词,不使用分词时,需要明确指定类型为keyword。
mapping设置,慎用嵌套类型
Elasticsearch的索引默认支持mapping嵌套,正常情况下慎用嵌套类型,如果使用嵌套类型,建议深度不要超过2,嵌套类型文档内部更新无法原子更新。
join设计,慎用nested和parent-child
Elasticsearch的索引默认不支持join,建议应用程序自身处理。如果需要在父子两个文档都需要进行过滤,或者需要返回父子两个文档的field,建议使用nested,其他场景建议使用parent-child。
通常情况下,nested比parent-child查询快5-10倍,但parent-child更新文档比较方便。
索引字段数不要太多,字段类型占用内存越少越好
Elasticsearch的索引最多默认支持1000个字段,Elasticsearch的字段数越多,对于集群缓存的消耗越严重,通常建议不要超过50个字段。
建议设计过程中,非索引和聚合字段不要存放到Elasticsearch中,可以使用其他存储引擎,比如mysql、hbase等。
禁用掉_all和_source
Elasticsearch的索引默认开启_all和_source,除了正常的存储和索引之外,还存放着原始写入记录、其他的元数据信息,这些信息可以直接使用正常的存储和索引filed进行替代,禁用掉可以提升集群性能,也可以在进行查询和搜索时进行exclude或者include设置。
设置合理延迟分片平衡时间
Elasticsearch的集群对网络的稳定性有很大的依赖,默认延迟分片平衡时间是1m,即副本在1分钟内恢复到集群,则不会进行重新分片。如果运维过程中,断网时间较长,建议修改该参数,避免来回创建分片、移动分片,为运维和节点异常恢复提供缓冲时间。