高 困难
搜索系统设计#
一句话答案#
搜索系统核心链路:用户 Query → 分词/纠错/扩展 → 倒排索引召回 → 多路归并 → 相关性排序(TF-IDF/BM25 + 业务权重)→ 结果聚合/高亮返回;数据通过 CDC/MQ 异步同步到 ES,保证最终一致性。
核心要点
整体架构#
用户查询 → [Query 理解层] → [召回层] → [排序层] → [展示层]
Query理解:分词 → 纠错 → 同义词扩展 → 意图识别
召回层: 倒排索引 + 向量检索(语义召回)→ 多路归并
排序层: 粗排(BM25) → 精排(ML模型/业务规则) → 重排(多样性/去重)
展示层: 高亮 + 摘要 + 聚合面板(facets)plaintextQuery 理解#
| 环节 | 作用 | 实现 |
|---|---|---|
| 分词 | 拆分查询词 | IK/jieba(中文)、standard(英文) |
| 纠错 | 修正拼写错误 | 编辑距离 + 候选词频排序 |
| 同义词扩展 | 扩大召回 | 同义词典 + word2vec 近义词 |
| 意图识别 | 理解用户真正需求 | 分类模型(品类/品牌/属性) |
| Query 改写 | 优化检索效果 | 删除无效词、补充修饰词 |
召回策略#
多路召回(Recall):
1. 文本召回:倒排索引 BM25 匹配
2. 向量召回:Embedding 相似度(语义搜索)
3. 标签召回:类目/品牌精确匹配
4. 热度召回:热搜/热卖 fallback
多路合并:按 score 归一化 → 加权合并 → 截断 Top-Nplaintext排序模型#
粗排:BM25 / TF-IDF(倒排索引自带分数)
→ 快速过滤到 Top 1000
精排:Learning to Rank (LTR)
特征: 文本相关性 + 点击率 + 转化率 + 新鲜度 + 商家质量
模型: LambdaMART / 深度模型
重排:多样性(MMR 算法)、去重、置顶/降权(运营干预)plaintext数据同步(MySQL → ES)#
方案1: 双写(不推荐,一致性难保证)
方案2: MQ 异步(推荐)
MySQL 变更 → binlog → Canal → Kafka → ES Consumer → 写入 ES
方案3: 定时全量同步(兜底)
每日凌晨全量 dump → 重建索引(alias 切换,零停机)
延迟:方案2 通常 1-3s,业务可接受plaintext性能优化#
| 手段 | 效果 |
|---|---|
| 索引预热 | 热数据加载到 OS Page Cache |
| 结果缓存 | Redis 缓存热门 Query 结果(TTL 5min) |
| Routing | 按商家/类目路由到固定分片,减少跨分片查询 |
| 异步刷新 | 写入时 refresh_interval=1s,非实时 |
| 分页优化 | search_after 替代 deep pagination |
容量设计#
日均搜索 QPS:1000w / 86400 ≈ 116 QPS(均值)
峰值 QPS:均值 × 5 ≈ 600 QPS
单节点 ES 能力:约 200-500 QPS(取决于数据量和查询复杂度)
→ 需要 3-5 节点 ES 集群
存储估算:1亿商品 × 1KB/doc ≈ 100GB
分片策略:10 分片 × 1 副本 = 20 shard,每个 shard 约 10GBplaintext面试回答(2分钟版)
搜索系统分四层:Query 理解层做分词、纠错、同义词扩展和意图识别;召回层多路并行——文本召回走倒排索引 BM25、语义召回走向量 Embedding、还有标签召回和热度 fallback,多路结果按 score 归一化加权合并;排序层先粗排 BM25 取 Top 1000,再用 LTR 模型精排(融合文本相关性、点击率、转化率等特征),最后重排做多样性和运营干预;展示层做高亮和聚合面板。数据同步用 Canal 监听 MySQL binlog 写入 Kafka,消费端写 ES,延迟 1-3 秒保证最终一致性,每日凌晨全量同步兜底。性能优化:热门 Query 走 Redis 缓存、分片路由减少跨节点查询、search_after 替代深分页。
追问与易错
追问方向:
- “怎么保证 ES 和 MySQL 数据一致?”→ Canal+MQ 最终一致性 + 定期全量校验
- “搜索结果怎么排序?”→ BM25 粗排 + LTR 精排(多特征融合)
- “怎么处理 Query 拼写错误?”→ 编辑距离 + 词频排序候选 + “你是不是想搜”提示
- “向量召回和文本召回怎么融合?”→ score 归一化后加权合并,权重可 A/B 测试调优
易错点:
- ❌ “直接用 MySQL LIKE 做搜索”——全表扫描,百万数据就不可用
- ❌ “ES 实时一致”——有 refresh interval 延迟(默认 1s),不是强一致
- ❌ “BM25 就够了”——大规模场景需要 ML 排序模型,BM25 只是基线