我们在很多场景下会用到ES帮助我们解决搜索问题,但是很多人了解只是停留在表面,如何深入的使用ES,并做针对性的性能优化呢?
批量提交
当大量的写任务时,可以采用批量提交的方案,但是需要考虑每次提交数据量的最优性能,这样可以根据网络情况,集群情况,数据大小控制批量写入的数量。
- 可以一次批量写入5M~15M开始,直到性能没有提升时结束。
- 逐渐增加并发数,使用监控工具观察CPU,IO,网络,内存等情况。
- 如果抛出EsRejectedExecutionException错误,说明集群已经到达处理瓶颈了,可以适当增加集群节点。
优化存储设备
现代服务器上,磁盘往往是系统的最大瓶颈。 并且ES本身是磁盘使用密集型的服务,所以在磁盘能力提升后,集群整体性能会大幅度提高。
- 条件允许,强烈建议SSD,SSD相对机械磁盘具有超高的读写速度和稳定性。
- 采用RAID0,可以提升写入速度。
- 配置ES在多块磁盘同时进行读写。
使用合理的段合并
Lucene以段形式存储数据,当新数据创建索引时,会自动创建一个新段,所以在一个索引文件中包含多个段。数据越多后,索引段越多,需要消耗的文件句柄及cpu就越多。
Lucene后台服务会定期计算庞大的段合并工作量,所以:
- 当段合并速度落后索引写入速度时,为避免堆积,es会把写索引线程数量降低到一个,并打印告警信息。
- 为防止因为段合并影响搜索性能,es默认对段合并进行限制,默认20m/s。
减少refresh次数
Lucene为提高写性能会采用延迟写入方式,只是将数据写入内存中,当延迟大于1s时,会触发一次refresh,refresh会把内存中数据以段形式刷新到操作系统文件缓存系统中。
数据以段形式刷新到操作系统的文件系统后才可以进行搜索,所以如果搜索实时性要求不高,可以增加延迟,可以减少段数量,降低合并压力。
减少flush次数
Translog数量达到512m会触发一次flush。主要为了把文件缓存系统中段数据持久化到磁盘,这个过程比较耗时,可以设置index.translog.flush_threshold_size参数修改缓存数据量,减少刷新次数,比如可以增加一倍。
减少副本数量
es的副本可以保证集群可用性,提高搜索并发能力,但是降低写入性能。 因为文档写入内容需要同步副本。
如果大批量导入可以关闭index.number_of_replicas:0,写入成功后在开启副本。