当前位置 : 首页 » 文章分类 :  开发  »  Elasticsearch-优化

Elasticsearch-优化

Elasticsearch 优化相关文档

Optimizations
https://www.elastic.co/guide/en/elasticsearch/reference/current/how-to.html


检索性能调优

Elasticsearch Guide [7.17] » How to » Tune for search speed
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html

增加系统缓存

Elasticsearch 重度依赖操作系统的文件系统缓存,为了加快检索速度,要保证至少一半可用内存用于系统缓存,以保证 ES 可将热点索引放到物理内存中。
这也是为什么官方建议堆内存不要超过可用内存的一半。

使用更快的硬件

1、保证文件系统缓存足够
2、使用 SSD 磁盘

优化文档模型

避免 nested 嵌套字段,避免 join 关系字段。
nested 字段有几倍的性能损失,join 关系字段会带来几百倍的性能损失。

使用copy_to合并字段

将多个字段的内容 copy_to 到一个字段中,方便搜索

提前计算中间结果

比如经常需要对 price 字段进行聚合查询,聚合为 0-200,200-500,500+,可以在插入文档时就计算好这个聚合分类

使用keyword代替数字类型

ES 对 integer, long 等数字类型做了优化更适合 range 查询,但 keyword 类型适合 term 级别查询。
并不是所有的数字类型数据都要存储为数字类型(integer, long等),例如数字类型的 ISBN 号、产品ID等,很少会用做范围 range 查询,更多的是 term 查询,所以更适合保存为 keyword 类型。

避免脚本搜索

强制合并只读索引

将只读索引强制合并为单个 Segment 可加快查询。对于 log 等基于时间写入的索引尤其适用,只保留当天的日志可写,将之前的日志合并为一个索引。

预热全局序号

全局序号用于加速聚合查询,是 fielddata 缓存结构的一部分,位于 JVM 堆内存中,在查询时触发。
对于常用的聚合字段,告诉 ES 提前预热该字段的全局序号缓存,可加快聚合查询速度。

预热文件系统缓存

机器重启后操作系统文件缓存会丢失,随着查询请求才会逐渐将索引中的热区域加载到系统缓存中。
对于常用的索引,配置到 "index.store.preload": ["index1", "index2"],以便启动时自动预热数据

冷->热->缓存

冷数据:查询条件term的索引文件还未加载系统缓存,读磁盘
热数据:查询条件term的索引文件已加载到系统缓存,使用同条件查询一次后触发,读内存
缓存后:用完全相同的查询条件再次查询,结果是完全缓存在内存的

索引数据排序

Elasticsearch 从 6.0 版本开始引入了一个新的特征,叫 Index Sorting(索引排序)。用户可以将索引数据按照指定的顺序存储在硬盘上,这样在搜索排序取前 N 条时,不需要访问所有的匹配中的记录再进行排序,只需要访问前 N 条记录即可。


文档插入(索引)性能调优

Elasticsearch Guide [7.17] » How to » Tune for indexing speed
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html

使用批量操作API

_bulk 批量操作,批量插入、更新、删除文档

多线程插入

修改或关闭刷新间隔(refresh_interval)

index.refresh_interval
https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-refresh-interval-setting

默认值 1 秒,可设为 -1 来禁用 refresh。
未显式设置时,分片在 index.search.idle.after 秒未收到 search 请求后会停止后台的定时 refresh 任务,直到再次收到 search 请求。这么做的目的是为了加快批量索引的速度。
refresh_interval 可以在既存索引上进行动态更新。

1、当正在建立一个大的新索引时,可以将刷新间隔临时调整为较大的值,创建完再调整为默认值。
注意:refresh_interval 需要一个 持续时间 值, 例如 1s (1 秒) 或 2m (2 分钟)。 一个绝对值 1 表示的是 1 毫秒。

PUT /index/_settings
{ "refresh_interval": "30s" } 30s自动刷新。
 
PUT /index/_settings
{ "refresh_interval": "1s" }  每秒自动刷新。

2、当正在建立一个大的新索引时,可以先关闭自动刷新,待开始使用该索引时,再把它们调回来:

PUT /index/_settings
{ "refresh_interval": -1 }    关闭自动刷新。
 
PUT /index/_settings
{ "refresh_interval": "1s" }  每秒自动刷新。

禁用副本

在做批量索引时,可以考虑把副本数 index.number_of_replicas 设置成0,因为document从主分片(primary shard)复制到从分片(replica shard)时,从分片也要执行相同的分析、索引和合并过程,这样的开销比较大,你可以在构建索引之后再开启副本,这样只需要把数据从主分片拷贝到从分片

curl -XPUT 'localhost:9200/my_index/_settings' -d ' {
    "index" : {
        "number_of_replicas" : 0
    }
}'

禁用操作系统swap

增加操作系统文件cache

使用自动生成的id

如果指定 id 创建文档,es 需要先检查此 id 是否已存在,较为耗时。

使用SSD磁盘

增加索引buffer size

读写分离


上一篇 Elasticsearch-Mapping 映射

下一篇 MySQL-SQL-DCL 数据控制语言

阅读
评论
1.3k
阅读预计5分钟
创建日期 2025-04-15
修改日期 2025-04-15
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论