背景
因为业务需求需要在生产中多次使用到ES,在长期运用中也经历到一些问题并解决,所以希望通过文章记录下经验并分享
索引数据优化
- 使用bulk批量写索引方式减少http请求次数
- 索引数据可以分为增量和全量模式增加容灾能力,增量近实时更新,全量每日更新
- refresh_interval当索引数据很大的时候可以设置成-1,因为当缓存区满时ES自动会refresh,减少refresh时的损耗
- 禁止动态mapping,只对有需要的字段做索引映射,明确好每个字段的类型
- 避免使用nested类型索引,因为nested索引数据是单独存放的一个文件,当nested文件很大的时候会拖累整个查询性能
- 通过对数据分类同时并行写入数据
- 数字类型和keyword类型要依情况判断,在ES5.x之后的数字类型的索引结构不再是倒排索引,而是Block k-d tree的索引结构,此时数值类型的索引做范围查找的性能较高,Term查询的性能就会变慢,具体原理可以参考公司大佬kennywu的一篇文章(number?keyword?傻傻分不清楚)
搜索优化
- 使用Term查询的性能最佳
- 查询只返回主键id,不返回具体数据,不要把ES当做数据库使用,并且可以避免解析索引Json数据,提高响应
- 避免使用Script查询和Script排序,当召回量很大的时候性能会极差,因为脚本一般都需要经过实时计算。
- 对于distance的查询可以优先用ES自带的distance计算,因为我们项目中前端页面展示的距离是自己计算的,所以我们为了保持一致必须使用script实时计算,但我们发现查询性能很差,此时我们选择加一个官方距离限制之后再用script的折中方案优化
- 如果必须要使用script,可以先考虑如何通过其他查询条件限制小召回量,另外优先使用painless语法,并且script脚本逻辑看是否可以优化
- 善用filter查询,因为filter过滤查询是有缓存的
- 注意minimum_should_match可能带来的误差,因为默认是按照概率计算的
数据一致性
ES运行一般是分布式集群模式,那么就会涉及到CAP理论,ES使用的AP,当索引分片在做复制的时候是无法保证数据一致性的,所以如果业务需要强一致性需求,我们需要从业务上考虑如何优化。
网友评论