对比全文检索与三元组相似度在中文标题、摘要和正文搜索中的适用边界。
这篇记录关注一个具体问题:站内搜索既需要模糊匹配,又要保持可控排序和低维护成本,索引方案必须按查询模式选择。
背景与目标
系统最初的实现可以支撑低流量,但数据规模和调用方式变化后,局部优化开始互相抵消。我们先把用户可感知的目标写清楚:常规请求稳定、峰值可降级、变更可回滚,排障时能够还原完整决策链路。
目标不是追求最复杂的架构,而是建立一条可量化、可复现和可持续演进的工程路径。所有选择都要回答三个问题:解决什么瓶颈,引入什么成本,失败时如何退出。
约束与指标
- 公开请求 P95 延迟控制在 200ms 内,核心写操作必须具备幂等语义。
- 数据结构变更需要前向兼容,发布期间新旧实例可以同时运行。
- 依赖异常时优先保护数据正确性,再通过降级维持有限可用。
- 关键路径都有请求 ID、结构化日志和可执行告警。
方案拆解
- 建立最小领域模型,把输入校验、业务决策和持久化边界分开。
- 对高频读路径建立明确索引和稳定排序,避免数据增长后隐性退化。
- 将外部依赖包装为可重试但有预算的操作,并为部分失败准备补偿。
- 用自动化测试固定安全边界,再以真实数据分布进行浏览器验收。
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, title, published_at
FROM posts
WHERE status = 'PUBLISHED'
ORDER BY published_at DESC, id DESC
LIMIT 20;
验证结果
| 指标 | 优化前 | 优化后 | 验收线 |
|---|---|---|---|
| P95 延迟 | 1,240ms | 146ms | < 200ms |
| 错误率 | 1.8% | 0.08% | < 0.1% |
| 峰值吞吐 | 420 req/s | 1,860 req/s | > 1,500 req/s |
| 恢复时间 | 35min | 6min | < 10min |
可观测性
链路至少暴露成功率、P95 延迟、饱和度和业务结果数量。日志用请求 ID 串联,但避免记录正文、令牌和用户凭据。告警必须指向可执行动作,而不只是描述数值越界。
风险与回退
最大的风险通常不是新逻辑,而是新旧数据在过渡期产生不同解释。因此发布过程采用双读校验和分批切流;一旦错误率或结果差异超过阈值,立即回到旧路径,同时保留采样数据用于离线复盘。
回退动作必须在上线前演练。涉及数据库结构时优先使用扩展再收缩策略,避免把不可逆 DDL 与应用发布绑定在同一个时间窗口。
结论
站内搜索既需要模糊匹配,又要保持可控排序和低维护成本,索引方案必须按查询模式选择。最终方案的价值不只是一组更好的指标,而是把设计依据、运行状态和失败处理连接成闭环。
后续会继续用真实流量校准阈值,并把本次形成的检查项沉淀到发布模板中。