768 字
约 2 分钟
7
S13-J01 · 索引调优:mapping、refresh、段合并

适用读者:写入慢、或"写了搜不到"的人。
前置:S13-B03。
实测环境:ES 8.15.3(2026-11-05)。
覆盖旧文:1549(92) + 空壳 698 补写(E-S13-015)= 92 点。
覆盖扩展:E-S13-005(refresh/translog)、E-S13-006(段合并)。
上一篇:S13-B03 · 查询 DSL 与客户端
下一篇:S13-J02 · 集群与脑裂。


1. 一句话结论

写入慢和"搜不到"是同一个机制的两面:ES 用"不可变段 + 每秒 refresh + translog"换取写入吞吐——可见性、持久性、性能三者是权衡。


2. 写入链路与三个开关(E-S13-005)

写请求 → memory buffer → refresh(生成可搜 segment,默认 1s)→ translog(持久性)→ flush(落盘)
开关 默认 改它的后果
refresh_interval 1s 调大 → 写入更快、可见延迟变大
refresh=true(单次写) 无 立即可见、写入变慢
translog.durability request(每次 fsync) 改 async → 更快但可能丢

实测(B01 复现):refresh_interval: -1 时写入 3 条后 _count 是 0,_refresh 后变成 3。

判据:"业务要求写完立即可搜吗?" 要求 → 写入带 refresh=true(只用于小流量关键数据);不要求 → 保持默认 1 秒。


3. 为什么批量导入要关 refresh 和副本

设置 导入期 导入后
refresh_interval -1 恢复 1s
number_of_replicas 0 恢复原值
批量大小 每批 5–15 MB —

原理:副本写入要跨节点同步,导入期关掉能显著提速(ES 官方批量导入建议)。


4. 段合并(E-S13-006)

事实 说明
段不可变 删除/更新只是"标记 + 新段"
段越多查越慢 每个段都要查
_forcemerge 合并成大段(只对只读索引做)

实测:

_cat/segments/articles → _0  3 docs  5.3kb(单段,合并后无变化)

"为什么不要对写索引 forcemerge":会产生大量 IO 且合并期间仍可写入 → 反复合并。只对"历史只读索引"合并(如按月索引)。


5. 五个误区

误区 真相
"refresh 等于落盘" refresh 只让数据可搜,flush 才落盘
"副本越多写越快" 副本增加写放大
"forcemerge 越勤越好" 只对只读索引做
"bulk 越大越好" 太大会 OOM/超时
"改 mapping 就能调优" 类型/分词器不可改(B02)

6. 自检

  1. 写入链路的三个阶段?
  2. refresh 与 flush 各做什么?
  3. 批量导入为什么要关 refresh/副本?
  4. _forcemerge 的正确使用场景?
  5. translog.durability 的取舍?

7. 下一篇

S13-J02 · 集群、分片、副本与脑裂

调优讲完,下一篇讲"分片怎么定、脑裂怎么防"。


本篇属于系列《S13 · 搜索与文档存储》。旧文来源:A-1549(空壳 698 补写);扩展点 E-S13-005/006/015。段与集群信息为 ES 8.15.3 实测。

S13-J01 · 索引调优:mapping、refresh、段合并
https://www.clxhxhhr.top/posts/5363/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。