跳到内容

20.2 近实时索引、同步、分片与搜索运维

搜索索引通常是权威数据库的派生视图。它可以短暂陈旧、可以重建,却不能悄悄成为库存、价格或权限的第二个裁判。

近实时来自 Refresh,不是写入失败

Lucene 以不可变 segment 组织索引。新文档先进入内存索引结构与日志路径,refresh 打开新的可搜索 segment;后台 merge 再把小 segment 合并。

Elasticsearch 的 index API 返回成功后,文档不一定立刻能被 search API 命中。默认 refresh 行为依部署与索引活跃状态而异,不能把“永远 1 秒”写死。需要 read-after-write 搜索体验时,可评估 refresh=wait_for,让写请求等待下一次自然 refresh;频繁强制 refresh=true 会制造大量小 segment 并增加 merge 成本。

还要区分:

  • refresh:让最近操作可搜索;
  • flush:推进持久化边界并处理 translog/commit 相关状态;
  • merge:合并不可变 segment,清理已删除文档的物理占用;
  • replica acknowledgement:决定索引写入的副本确认条件。

它们不是同一个“刷盘”动作。

Primary Shard 决定数据切分

文档 ID 或 routing 值映射到 primary shard,副本 shard 保存该 primary 的复制数据。搜索请求由 coordinating node 发往相关 shard copy,再合并各 shard 的 top results。

text
query
  -> shard 0 top-k
  -> shard 1 top-k
  -> shard 2 top-k
  -> coordinator merge/rerank

Primary shard 太少会限制并行与容量,太多则增加 heap、文件句柄、cluster state、scatter/gather 和恢复成本。副本提高故障容忍与潜在读吞吐,不会增加写入数据的分片数。

自定义 routing 可让同一租户/实体查询只访问部分 shard,却也可能制造热点和超大 shard。规划应使用真实文档大小、查询 fan-out、恢复时间和增长曲线,而不是固定“每 shard 多少 GB”的万能数字。

数据库到搜索索引的同步

可靠链路通常是:

text
database transaction
  -> outbox/WAL/CDC
  -> durable event log
  -> idempotent indexer
  -> search index
  -> checkpoint + lag metrics

事件至少携带稳定实体 ID、source version 和删除语义。Indexer 对同一实体乱序事件应拒绝旧版本覆盖新版本;删除不能只从源表缺席推断,应传播 tombstone 或显式删除事件。

周期全量同步容易在扫描期间混入增量,造成缺口或倒退。正确重建需要一致快照位置:先记录/取得快照对应的 WAL/offset,再回填快照,最后从衔接位置消费增量。

Reindex 用新索引和 Alias 切换

修改 analyzer、字段类型或主分片规划时,通常创建新版本索引:

text
products-v3 (current alias target)
products-v4 (backfill + catch up + verify)

流程:

  1. 创建显式 mapping/settings 的 v4;
  2. 从一致快照全量回填;
  3. 追上增量并记录 checkpoint;
  4. 对比数量、抽样文档、过滤和相关性;
  5. 原子切换读写 alias;
  6. 保留可回退窗口,再删除 v3。

双写 v3/v4 仍需处理一边成功一边失败;基于同一 CDC 日志分别投影通常更容易重放和审计。

搜索结果不能直接裁决交易

用户在搜索页看到“有库存”,点击下单时必须回权威交易库重新校验并原子扣减。权限撤销若要求立即生效,也不能只等待索引 refresh。

搜索服务应声明 freshness SLO,例如:

  • 99% 商品更新在 30 秒内可搜;
  • 删除/下架在 10 秒内从公共结果移除;
  • 权限强校验在返回详情或执行操作时由权威服务完成。

不同字段可有不同风险与降级路径。

深分页与结果一致性

from + size 越深,每个 shard 需要保留并返回更多候选,协调节点成本迅速增加。面向滚动列表优先使用 search_after 和稳定 tie-breaker;需要跨多页保持一致视图时结合 point in time(PIT)。

排序字段必须稳定且确定。只按分数时,相同分数文档在 refresh、replica 或 shard 状态变化后可能换序。

词法、向量与混合检索

向量检索擅长语义相似,却不天然保证精确编号、否定词、最新事实或权限过滤。词法检索擅长精确 term 与可解释过滤。混合检索通常:

text
lexical candidates + vector candidates
  -> normalize / RRF / learned reranker
  -> hard business filters

Embedding 模型版本应写入索引元数据;升级模型往往需要重新计算向量和评估。向量召回同样需要离线 judgement、延迟和内存/磁盘成本测试,不能只看几条演示查询。

运维指标

至少监控:

  • indexing rate、reject、bulk error 与 CDC lag;
  • refresh、segment count、merge time/throttle;
  • shard size、allocation、recovery 与 cluster health;
  • search p50/p95/p99、timeout、cancel 和 shard failures;
  • query fan-out、slow log、cache 与 heap/GC;
  • zero-result rate、Recall/nDCG 采样与权限漏出检查;
  • source version 与 index checkpoint 差距;
  • 全量重建和 alias 回退耗时。

集群绿色只说明 shard 分配状态,不证明数据已与权威源同步,也不证明搜索质量正确。

参考

至此,第五卷的专业主线从关系模型一直延伸到缓存与搜索派生视图。下一阶段的全卷校验将检查代码、链接、目录和术语,再进入故事线与文风统一。

Built with VitePress | Software Systems Atlas