这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战
写优化
副本数量0
集群首次灌入数据, 副本数设置为0, 写入完毕再调整回去, 副本分片只需要拷贝,节省了索引过程
PUT /my_index/_settings
{
"number_of_replicas": 0
}
自动生成doc ID
如果外部指定ID,ES会尝试读取原来doc的版本号,判断是否需要更新,这会设计读取磁盘操作,自动生成doc ID 可以避免这个环节
合理设置mappings
- 将不需要建立索引的字段index属性设置为not_analyzed或no, 对字段不分词或者不索引,可以减少很多运算操作,降低CPU占用,尤其是binary类型在默认情况下占用CPU很高
- 减少字段内容长度,如果原始数据的大段内容无需全部建立索引,尽量减少不必要的内容
- 使用不同的分析器, 不同分析器在索引过程中运算复杂度有很大差异。
调整_source字段
_ source字段用于存储doc原始数据,对于部分不需要存储的字段,通过includes excludes过滤, 或者将_ source禁用,一般用于索引和数据分离,可以降低I/O压力。
对analyzed的字段禁用norms
Norms用于在搜索时禁用doc的评分, 不需要评分就禁用
调整索引的刷新时间
参数缺省是1秒,强制每秒创建一个segment, 从而保证写入数据近实时可见,可被搜索到,调整到20,降低了刷新的次数,资源会释放给index操作使用。
批处理
尽量使用bulk处理
Document路由处理
默认的routing是id, 可以在发送请求的时候手动指定一个routing value, 比如user_id。 但是线程数降低了, 单批处理耗时增加, 延长数据不见的时间
读优化
数据分组
开始只建立一个index,数据量增大,扩容增加index的shard数。shards增大时,要搜索的shards个数也显著上升, 基于数据分组的思路,可以基于client进行数据分组,每个client值依赖自己的index数据shards进行搜索。
Filter替代Query
Filter没有打分环节,理论上更快, 如果搜索不需要打分,直接使用Filter,如果部分需要打分, 使用bool查询。
ID 定义为keyword
keyword会被优化,方便terms查询,数字类型改成keyword也被优化成range类型搜索,搜索性能提升大约30%
限制输入
防止用户无约束的查询语句拖累ES集群的查询性能,对keywords进行限制