顿搜
14. ES生成环境使用与参数调优——ElasticSearch基础专栏
一、数据结构优化
基于Elasticsearch的使用场景,文档数据的结构尽量和使用场景相结合,去掉没用的和不合理的数据
1.1 尽量减少不需要的字段
如果Elasticsearch用于业务搜索服务,那么一些不需要用于搜索的字段最好不要存储到索引库中,这样既节省空间,同时在相同的数据量下也能提高搜索性能
同样,控制字段的数量和字段的类型也是Elasticsearch性能优化的重中之重。
1.2 尽量使用静态映射
尽量避免使用动态映射,这样有可能会导致集群崩溃。
此外,动态映射有可能会带来不可控制的数据类型,进而导致在查询端出现相关异常,影响业务。
二、查询优化
Elasticsearch用于业务搜索的近实时查询时,查询效率的优化显得尤为重要。
2.1 Cache的设置及使用
Elasticsearch在查询的时候,使用filter查询会用到querycache,如果业务场景中的过滤查询比较多,建议将querycache设置得大一些,以提高查询速度
indices.queries.cache.size: 10%以上设置是默认的,可以设置成百分比,也可以设置成具体的值,如256MB
2.2 合理使用深度翻页
在使用Elasticsearch的过程中,应尽量避免深度翻页的出现。
正常翻页查询都是从from开始size条数据,需要在每个分片中查询文档评分在前面的from+size条数据,然后协同节点收集每个分配的前from+size条数据,协同节点一共会收到N*(from+size)条数据,然后进行排序,再将其中from到from+size条数据返回。如果from或者size很大的话,会导致参加排序的数量过大,最终会导致CPU资源消耗增大。
对于这种深度翻页的业务,推荐使用Elasticsearch中的滚动查询来解决
三、索引优化设置
索引优化主要是在Elasticsearch的数据插入层面优化
3.1 合理批量提交
当有大量数据需要提交时,建议采用批量提交(Bulk操作)的方式。
此外,使用Bulk请求时,每个请求的数据量不宜过大,因为太大会导致内存使用过多,尽量控制在几十MB之内。
3.2 增加刷新时间间隔
如果系统对数据延迟要求不高的话,可以通过延长刷新时间间隔来有效地减少段合并的压力,提高索引的性能
index.refresh_interval设置为30秒,减少刷新次数
在进行数据导入时,可以将“刷新”临时关闭,即把index.refresh_interval设置为设-1,数据导入成功后再打开为正常模式。
3.3 _id字段的使用
在创建索引或者写入文档数据时,应该尽可能避免使用自定义的_id,建议使用Elasticsearch的默认ID生成策略,这样对于Elasticsearch内部进行数据负载有很大作用。
3.4 _all和_source字段的使用
_all和_source字段的使用应该注意场景和需要,_all字段包含所有的索引字段,方便做全文搜索,如果无此需求,可以禁用;
_source存储了原始的文档内容,如果没有获取原始文档数据的需求,可通过设置includes、excludes属性来定义放入_source的字段。
四、硬件配置优化
升级硬件设备的配置一直都是提高服务能力最快速有效的手段之一。在系统层面能够影响应用性能的因素一般有3个:CPU、内存和IO
4.1 磁盘的选择
尽量使用固态硬盘(Solid State Drive,SSD)
4.2 禁止swap
推荐做法是禁用swap,一旦允许内存与磁盘交换,就会引起致命的性能问题。
可以通过在config/elasticsearch.yml配置文件中修改bootstrap.memory_lock: true来保持JVM锁定内存,以保证Elasticsearch的性能。
4.3 内存配置
排序和聚合都很耗内存,所以有足够的堆空间来应付它们是很重要的。
即使堆空间比较小,也能为操作系统文件缓存提供额外的内存。
因为Lucene使用的许多数据结构都是基于磁盘的格式,Elasticsearch利用操作系统缓存对性能的提升能产生很大的效果。
如果机器内存等于64GB,可以给Elasticsearch分配32GB,留下32GB给Lucene。
当服务内存是32GB和16GB时,最少也需要给Elasticsearch分配8GB。