九、ElasticSearch的集群优化
1.生产环境部署
1)遵照官方建议设置所有系统参数。
在ES的配置文件中elasticsearch.yml中,尽量只写必备的参数,其他可通过api进行动态设置,随着ES版本的不断升级,很多网上流传的参数,现在已经不再适用,所以不要胡乱复制。
建议设置的基本参数有:
①cluster.name
②node.name
③node.master/node.data/node.ingest
④network.host。建议显示指定为服务器的内网ip,切勿直接指定0.0.0.0,很容易直接从外部被修改ES数据。
⑤discovery.zen.ping.unicast.hosts 设置集群其他节点地址,一般设置选举节点即可。
⑥discovery.zen.minimum_master_nodes。一般设置为2,有3个即可。
⑦path.data/path.log
⑧除上述参数外,再根据需要增加其他的静态配置参数,如:refresh优化参数,indices.memory.index_buffer_size。
动态设定的参数有transient(短暂的)和persistent(持续的)两种,前者在集群重启后会丢失,后者在集群重启后依然生效。二者都覆盖了yml中的配置,举例:
#使用transient和persistent动态设置ES集群参数
PUT /_cluster/Settings
{
"persistent":{ #永久
"discovery.zen.minimum_master_nodes:2
},
"transient":{ #临时
"indices.store.throttle.max_bytes_per_sec":"50mb"
}
}
2)关于JVM内存设定
每个节点尽量不要超多31GB。
预留一半内存给操作系统,用来做文件缓存。ES的具体内存大小根据node要存储的数据量来估算,为了保证性能:
搜索类项目中:内存:数据量 ===> 1:16;
日志类项目中:内存:数据量 ===> 1:48/96。
假设现有数据1TB,3个node,1个副本,那么:
每个node存储(1+1)*1024 / 3 = 666GB,即700GB左右,做20%预留空间,每个node约存850GB数据。
此时:
如果是搜索类项目,每个node内存约为850/16=53GB,已经超过31GB最大限制;
而:31*16 = 496,意味着每个node最大只能存496GB的数据,则:2024/496=4.08...即至少需要5个节点。
如果是日志类项目,每个node最大能存:31*48=1488GB,则:2024/1488=1.36...,则三个节点已经够了。
2.写性能优化
在写上面的优化,主要是增大写的吞吐量——EPS(Event Per Second)
优化方案:
①Client:多线程写,批量写bulk;
②ES:在高质量数据建模的前提下,主要在refresh、translig和flush之间做文章。
1)降低refresh写入内存的频率:
A、增大refresh_interval,降低实时性,增大每次refresh处理的文件数,默认1s。可以设为-1s,禁止自动refresh。
B、增大index buffer大小,参数为:indices.memory.index_buffer_size。
此为静态参数,需设定在elasticsea.yml中,默认10%
2)降低translog写入磁盘频率,同时会降低容灾能力:
A、index.translog.durability:设为async;
index.translog.sync_interval。设置需要的大小如:120s => 每120s才写一次磁盘。
B、index.translog.flush_threshold_size。默认512m。
即当translog大小超过此值,会触发一次flush,可以调大避免flush过早触发。
3)在flush方面,从6.x开始,ES固定每30min执行一次,所以优化点不多,一般都是ES自动完成。
4)其他:
A、将副本数设置为0,在文档全部写完之后再加副本;
B、合理设计shard数,保证shard均匀地分布在所有node上,充分利用node资源:
index.routing.allocation.total_shards_per_node:限定每个索引在每个node上可分配的主副分片数,
如:有5个node,某索引有10个主分片,1个副本(10个副分片),则:20/5=45,但是实际要设置为5,预防某个node下线后分片迁移失败。
写性能优化,主要还是index级别的设置优化。
一般在refresh、translog、flush三个方面进行优化;
3.读性能优化
主要受以下几方面影响:
①数据模型是否符合业务模型?
②数据规模是否过大?
③索引配置是否优化?
④查询运距是否优化?
1)高质量的数据建模
A、将需通过cripte脚本动态计算的值,提前计算好作为字段存入文档中;
B、尽量使数据模型贴近业务模型
2)根据不同数据规模设定不同的SLA(服务等级协议),万级数据和千万级数据和亿万级数据性能上肯定有差异;
3)索引配置优化
A、根据数据规模设置合理的分片数,可通过测试得到最适合的分片数;
B、分片数并不是越多越好
4)查询语句优化
A、尽量使用Filter上下文,减少算分场景(Filter有缓存机制,能极大地提升查询性能);
B、尽量不用cript进行字段计算或算分排序等;
C、结合profile、explain API分析慢查询语句的症结所在,再去优化数据模型。
4.其他优化点
1)如何设定shard数?
ES的性能基本是线性扩展的,因此,只需测出一个shard的性能指标,然后根据实际的性能需求就可算出所需的shard数。
测试一个shard的流程如下:
①搭建与生产环境相同配置的单节点集群;
②设定一个单分片0副本的索引;
③写入实际生产数据进行测试,获取(写性能指标);
④针对数据进行查询操作,获取(读性能指标)。
2)压力测试工具,可以采用ES自带的esrally,从经验上讲:
如果是搜索引擎场景,单shard大小不超过15GB;
如果是日志分析场景,单shard大小不超过50GB。
估算索引的总数据大小,除以上述单shard大小,也可得到经验上的分片数。
5.ES集群监控
使用官方免费插件X-pack。
1)安装与启动:
#X-pack的安装
cd ~/elasticsearch-6.1.1
bin/elasticsearch-plugin install x-pack
cd ~/kibana-6.1.1
bin/kibana-plugin indtall x-pack
之后重启ES集群即可。
2)详细界面自行研究即可,也很简单,在kibana的界面可以看到新增了工具,使用Monitoring进行集群监控: