一条商品数据写入 ES 后为什么不能立刻搜到?写入和搜索链路分别发生了什么?
我的判断
写入成功后不能立刻搜索,通常是因为文档已进 translog 和内存缓冲,但还没 refresh 成新的可搜索 segment。
协调节点根据 routing 找到主分片,主分片校验并写入内存 buffer 和 translog,再复制到副本,满足确认条件后返回。此时按 _id 的实时 GET 可以从内部状态拿到新文档,但普通 search 依赖已打开的 segment reader。
refresh 会把内存中的新 segment 发布给搜索,默认周期通常约一秒,所以 ES 是近实时,不是每次写完都立即可搜。flush 则和 translog、持久化及 segment 提交相关,不能把 refresh 和 flush 混为一谈。
如果业务只在少量关键写后必须搜索到,可以使用 refresh=wait_for 等待下一次 refresh;不会每条写都 refresh=true,那会制造大量小 segment、增加 merge 和查询成本。批量导入时反而会临时放大 refresh interval,完成后再恢复。
设计接口时,写后立即展示可直接使用写入返回的数据或按 ID GET,不必强迫搜索链路变成强实时。