Appearance
性能与最佳实践
写入流程简述
- 文档写入后先进入内存缓冲区,再定期 refresh 生成新的可搜索段(segment),因此搜索是近实时(默认约 1 秒内可见)。
- 缓冲区内容会 flush 到磁盘,形成持久化段;多个小段会在后台 merge 成大段,减少文件数、回收删除空间。
理解这一点有助于合理设置 refresh_interval 和 Bulk 策略。
批量写入建议
- 尽量用 Bulk API:单条频繁写入会产生大量网络与 refresh 开销,Bulk 可显著提升吞吐。
- 批次大小:单次 Bulk 不宜过大(如 5MB~15MB body 或几千条文档为参考),避免超时或内存压力;可根据文档大小和集群能力调优。
- 并发:多线程/多进程发 Bulk 时注意总 QPS 和集群负载,可配合限速(如
requests_per_second)使用。
刷新间隔(Refresh Interval)
默认约 1 秒 refresh 一次。若写入量很大且对近实时要求不高,可适当增大 refresh_interval,减少 refresh 频率,提升写入性能:
http
PUT /my_index/_settings
{
"index": {
"refresh_interval": "30s"
}
}写入高峰过后可改回 1s。必要时也可在单次请求里用 refresh=false(默认)或 refresh=wait_for 控制行为。
查询优化与最佳实践
用 filter 代替 query(不需要算分时)
只做筛选、不需要相关度排序时,把条件放在 bool.filter 里,而不是 must。filter 可被缓存,且不参与算分,性能更好。
避免深度分页
from + size 过大会拉取大量数据到协调节点,成本高且默认有上限(如 10000)。
- 业务上限制最大页码或改用 search_after、scroll 做游标式分页。
- 若只需 Top N,尽量控制 size。
只返回需要的字段
用 _source 过滤或排除字段,减少网络与序列化开销:
http
"_source": ["title", "author", "year"]或 "_source": { "excludes": ["content"] }。
索引设计建议
- text 与 keyword:需要全文检索用 text,需要精确匹配/排序/聚合用 keyword;常见做法是同一字段用 fields 同时保留 text 与 keyword。
- 分片数:主分片创建后不可改,需提前估算数据量和增长;单分片几十 GB 以内较常见,避免过多小分片。
- 按时间滚动:日志等时序数据建议按天/周建索引 + 别名查询,便于删除旧数据、做 ILM 和 Reindex。
生产环境注意
- 内存与 JVM:堆内存建议不超过物理内存的 50%,且不超过约 31GB(压缩指针阈值);详见官方 堆大小 建议。
- 磁盘:使用 SSD 可明显提升 I/O;监控磁盘空间,避免写满导致节点离开集群。
- 安全:生产建议开启 认证(如 X-Pack)、HTTPS、网络隔离,并定期备份(快照)。