感觉针对ES的优化可以有这么几块儿
- ES集群的优化
- ES的索引设计
- ES的写入优化
- ES的查询优化
- ES的一些基础知识点
- 对集群做过哪些优化
上面的1,2,3,4之间可能之间会有交叉,比如索引设置delay_allocation 是属于索引设计的优化,同时也是集群稳定性的优化,也算是针对集群的优化。可以先按照自己的思路准备一下。
1.集群优化
这个是偏向于集群的搭建设计,在搭建一个集群的时候。首先我们要考虑是的我们的业务场景,数据量,查询和写入的量级,根据这个来规划集群的节点数量和节点的配置。其次是集群的一些高可用的保证以及安全相关的保证(近几年很多数据泄露事件都是因为ES导致)。
-
在集群的资源的选择上大概有一些基础的原则
- 索引单个分片尽量不大于50G,一般20G左右差不多(因为考虑到索引混部,单个节点的内存容量)
- 单个节点的内存最好是大于等于64G,jvm的值要小于32(防止指针膨胀),给系统留更多的内存用来做文件缓存
- 因为索引的实际读取是文件缓存+磁盘,所以在索引数据远大于内存的时候使用ssd可以提供更好的读写性能
- es官方的一些常规优化,关闭swap,把进程可以持有的句柄数目调大,线程数调大
-
副本数最好大于等于一,来提供更高的可用性,同时也可以使用多集群的方式来提供更高的可用性,前置nginx来做代理
-
安全相关的设置,基于用户名和密码访问,提供更好的安全性,而且尽量不要暴露到外网当中
-
监控,在状态为yellow等能够报警
2.索引设计
-
索引单个分片尽量不大于50G,一般20G左右差不多(因为考虑到索引混部,单个节点的内存容量)
-
索引的副本数>=1,提供一些冗余,如果是高读取,低写入的索引,可以增加副本的数量
-
配置索引的慢查询日志,并且监控
-
Unsigined_delay,在节点失败之后,延迟分配,这样可以降低集群的抖动,因为一般情况下我们都会监控集群的稳定性,在yellow的时候会人工check干预
-
使用alias来使用索引,实际底层可以在不同时刻关联不同的索引
-
手动设置不同的字段的mapping,关闭动态的mapping,防止脏数据插入
-
具体的字段设置,text字段可以使用 ik+(standard+match_phrase)
-
同义词插件,自定义词典
3.写入优化
-
使用ssd,内存更大一些,也可以调整write_buffer
-
调整refresh的时间间隔
-
使用bulk的写入方式,同时可以叠加多线程的写入
-
也可以优化translog,改成异步的,但是这个会对数据的一致性造成影响
4.查询优化
查询优化,我觉得这个要具体情况具体分析,主要可以从两个方面入手。
第一个是集群的整体负载如何,如果集群的整体负载已经比较高了cpu高,load高,那么更可能是集群资源不太够,这个时候可以对集群进行扩容,让内存磁盘比例更高一些,配置更好的磁盘ssd,cpu核数多一些。
第二种情况是,进群整体的负载并不高,这个时候我们通过slowlog来看看是哪些查询比较慢。分析这些query的结构,可以用es的profile调试,来看看查询慢在哪个环节。调整的话一般有两个途径,
- 一个是从通用优化上面去调整。
- 比如增加分片的数量,这样每个分片处理的数据更少,增大内存cpu,
- 还有一种可能就是流量偏大,我们可以增加副本数来提供更好的查询性能
- 从query侧优化,使用查询分析看看esquery主要慢在哪个地方,进而优化
- 优化script,尽量使用doc values进行计算,script,通过多路召回等其他方式来减少对script的使用
- 查询过于复杂,计算条件太多,查询链条太长,合并的倒排表太多
- 精简查询,可以将一些条件提前计算好,多个条件变成一个条件写入到es当中,查询逻辑更加简单,比如用户的状态这个字段
- 尽可能的使用查询缓存filter查询
- disscuss寻找支持
5.ES基础知识
可以偏向于架构和基础层面一些?
- 集群的管理
- 集群master选举
- pacifica架构简述一下
- 一次写入的过程
- 一次查询的过程
6.集群优化的实际经历
- 增加专用的master,增加副本,开启权限校验,使用脚本监控集群状态
- 集群按照业务进行拆分,防止不同业务之间相互干扰
- 开启es的慢查询日志,搜集并且监控
- 关闭集群的预加载处理
- query优化,
- script使用dov values来替代source中获取字段的方式
- 使用多路召回来替换掉script查询,由模型来学习排序