大数跨境
0
0

别再搞混检索和搜索!一文讲透技术演进与架构逻辑(普通人也能懂)

别再搞混检索和搜索!一文讲透技术演进与架构逻辑(普通人也能懂) 二进制跳动
2025-10-09
2
导读:别再搞混检索和搜索!一文讲透技术演进与架构逻辑(普通人也能懂)
或许 99% 的开发者不会深度参与全网搜索引擎的搭建,但几乎每个人都在业务中实现过 “检索” 功能 —— 小到查询后台的一条订单记录,大到筛选电商平台的千万级商品数据。“检索” 与 “搜索” 仅一字之差,背后却藏着从简单查询到复杂系统的技术跃迁。本文将从业务需求出发,拆解搜索与检索的核心技术、架构设计,以及不同阶段的解决方案,让复杂逻辑变得清晰可感。

一、从 “做个谷歌” 说起:全网搜索引擎的核心架构

曾有人提出需求:“想做一个全网搜索引擎,和谷歌类似就行,两个月能上线吗?” 看似简单的诉求,背后却是一套涉及数据抓取、索引构建、结果排序的复杂系统。要理解其难度,首先得拆解全网搜索引擎的宏观架构与核心流程。

1. 三大核心子系统:支撑 “从网页到结果” 的全链路

全网搜索引擎的核心能力由三个子系统协同实现(对应架构中粉色模块),缺一不可:


  • Spider 爬虫系统
    相当于搜索引擎的 “触角”,负责主动遍历互联网上的网页。它需要智能判断 URL 优先级(如资讯类网页更新快,优先抓取),应对不同网站的反爬策略(如验证码、IP 限制),还要处理网页编码异常、死链等问题,是数据 “入口” 的关键。
  • Search&Index 索引系统
       分为 “建索引” 和 “查索引” 两大功能,是搜索引擎的 “中枢”。
    • Build_index
      将 Spider 抓取的网页内容加工处理 —— 先做分词(如 “人工智能发展趋势” 拆分为 “人工智能”“发展”“趋势”),再构建正排索引和倒排索引,把杂乱的网页转化为可快速查询的结构化数据;
    • Search_index
      接收用户的搜索词,通过索引快速定位匹配的网页,完成 “初步筛选”。
  • Rank 打分排序系统
    决定用户最终看到的结果顺序。它会结合网页相关性(如搜索词在标题中出现比在正文出现权重高)、网页权威性(如政府官网比个人博客权重高)、用户行为(如点击量、停留时间)等上百个维度计算得分,是 “搜索体验优劣” 的核心,也是谷歌、百度等引擎体验差异的关键。

2. 两大核心数据:连接 “抓取” 与 “检索” 的桥梁

系统的运转依赖两类核心数据:

  • Web 网页库
    存储 Spider 抓取的原始网页数据,相当于 “数据仓库”。由于要容纳千亿级网页,它必须是分布式存储系统(如 HDFS),且需支持高容错(避免单节点故障丢失数据)和动态扩容(随网页量增长增加节点)。
  • Index 索引数据
    Build_index生成的正排索引和倒排索引,是 “快速查询的钥匙”。它的设计直接决定检索速度 —— 好的索引结构能让 “从搜索词到网页” 的查询耗时控制在毫秒级。

3. 核心逻辑:“写入” 与 “检索” 分离

全网搜索引擎的业务特性,决定了它必须是 “写入” 和 “检索” 分离的系统:

全网搜索引擎的业务特性,决定了它必须是 “写入” 和 “检索” 分离的系统:

  • 写入流程(数据进入系统):由 Spider 和 Search&Index 协同完成。

    1. Spider 根据 URL 队列,批量抓取互联网网页;
    2. 将网页内容(含 HTML、图片链接等)存储到 Web 网页库;
    3. Build_index
      从网页库读取数据,清洗无效内容(如广告代码)后分词;
    4. 生成正排索引和倒排索引,存入 Index 索引数据中。这个过程是 “离线 + 异步” 的 —— 网页抓取后不会立刻进入索引,需经过处理和构建,保证索引的完整性和高效性。
  • 检索流程(用户获取结果):由 Search&Index 和 Rank 协同完成。

    1. 用户输入搜索词(如 “2024 新能源汽车销量”),Search_index先对搜索词分词;
    2. 通过倒排索引查询匹配的网页(初筛结果);
    3. Rank 对初筛结果按得分排序,过滤低质量网页(如恶意跳转页);
    4. 返回排序后的 Top 结果(如首页 10 条)。这个过程是 “实时 + 同步” 的 —— 用户等待时间需控制在 1-3 秒内,否则会直接放弃搜索。

二、检索的基石:正排索引与倒排索引

无论是全网搜索还是业务中的简单检索,核心都依赖 “正排索引” 和 “倒排索引” 这两种数据结构。理解它们,就掌握了 “快速查询” 的关键。

1. 正排索引:从 “key” 找 “内容”

正排索引的逻辑很简单:通过唯一标识(key)快速查询对应的实体内容,类似我们用手机号查联系人信息。

  • 举例 1:订单表t_order(order_id, user_id, amount, status),通过order_id=10086查询到user_id=123,amount=999,status=已支付,就是正排索引查询;
  • 举例 2:商品库t_goods(goods_id, name, price, category),通过goods_id=567查询到name=无线耳机,price=299,category=数码,也是正排索引查询。

在搜索场景中,网页内容会先分词,此时正排索引可理解为Map<url_id, List<分词项>>—— 比如url_id=2001对应分词["人工智能", "发展", "趋势"],能通过url_id快速定位网页的分词结果,时间复杂度接近 O (1)。

2. 倒排索引:从 “内容” 找 “key”

倒排索引与正排索引相反:通过 “内容片段(如分词项)” 快速查询对应的唯一标识(key),是搜索的核心。它的结构可理解为Map<分词项, List<url_id>>—— 比如分词 “人工智能” 对应[2001, 2003, 2005],表示url_id=2001“2003”“2005” 的网页都包含 “人工智能” 这个词。

举个具体例子理解:

假设有 3 个网页,正排索引(分词后)如下:

  • url_id=2001
     → 内容 “人工智能发展趋势” → 分词["人工智能", "发展", "趋势"]
  • url_id=2002
     → 内容 “人工智能应用场景” → 分词["人工智能", "应用", "场景"]
  • url_id=2003
     → 内容 “应用场景分析” → 分词["应用", "场景", "分析"]

对应的倒排索引就是:

  • “人工智能” → [2001, 2002]
  • “发展” → [2001]
  • “趋势” → [2001]
  • “应用” → [2002, 2003]
  • “场景” → [2002, 2003]
  • “分析” → [2003]

当用户搜索 “人工智能应用” 时,系统先分词为["人工智能", "应用"],再通过倒排索引找到两个分词对应的url_id列表,最后求交集[2002]—— 这就是 “初筛结果” 的由来。

3. 关键优化:有序集合求交集的 5 种方法

检索的核心步骤 “求分词结果的交集”,其效率直接影响搜索速度。由于倒排索引的List<url_id>会提前排序(便于优化),我们可以通过不同方法提升交集效率:

以跳表为例:若url_id列表是[101,102,103,104,201,202,301,302],可建立一级索引[101,201,301]。查询 “201” 时,无需遍历前 4 个元素,直接通过索引跳到 201,效率大幅提升 —— 这也是谷歌、百度等主流搜索引擎的核心优化手段。

三、业务检索的 4 个阶段:从简单到复杂的演进

并非所有检索需求都需要 “全网搜索” 级别的架构。随着数据量、并发量的增长,业务检索会经历 4 个阶段,每个阶段对应不同的技术方案。

1. 原始阶段:用 SQL 的 LIKE 实现(创业初期)

核心逻辑:直接用数据库的LIKE语句匹配内容,无需额外开发。比如查询标题包含 “无线耳机” 的商品:

SELECT goods_id FROM t_goods WHERE name LIKE '%无线耳机%'

优点:零开发成本,10 分钟就能上线;

缺点:全表扫描,数据量超 10 万就会卡顿(如查询耗时从 0.1 秒增至 5 秒以上);不支持分词(如搜 “无线耳机降噪” 无法匹配 “降噪无线耳机”)。

适用场景:创业初期,数据量 < 10 万,并发量 < 100 的业务验证场景(如小电商试运营)。

2. 初级阶段:数据库全文索引(数据量百万级)

核心逻辑:利用数据库的全文索引特性,替代LIKE,支持分词和快速查询。

比如 MySQL 中创建商品标题的全文索引:

ALTER TABLE t_goods ADD FULLTEXT INDEX idx_goods_name (name);-- 查询时用MATCH AGAINST实现分词检索SELECT goods_id FROM t_goods WHERE MATCH(name) AGAINST ('无线耳机降噪');
优点:支持分词,效率比LIKE高 50-100 倍(百万数据查询耗时从 10 秒降至 0.1 秒);无需引入外部系统,运维成本低;
缺点:仅支持 MyISAM 引擎(InnoDB 需 MySQL 5.6+);检索与 CURD 耦合(如大促期间下单量高,会导致检索卡顿);数据量超百万后性能骤降,难以水平扩展。
适用场景:数据量 10 万 - 100 万,并发量 100-500 的成长型业务(如区域型电商)。

3. 中级阶段:开源外置索引(数据量千万 - 10 亿级)

核心逻辑:将 “检索” 与 “存储” 分离 —— 原始数据存在数据库(负责 CURD),检索用外置索引系统(负责分词、查询),通过 “双写”“定时同步” 保证数据一致性。主流方案是ElasticSearch(ES),它基于 Lucene 内核,封装了高可用、负载均衡能力,提供 RESTful 接口,开箱即用。ES 的优势

  • 支持 10 亿级数据存储,并发量可达 5000+(压测场景下,单集群支持每秒 5000 次查询);
  • 天然支持集群,水平扩展简单(新增节点即可扩容,无需修改代码);
  • 丰富的插件生态(如ik_smart中文分词插件、geo_point地理位置插件),满足个性化需求(如 “附近的咖啡店” 检索)。
  • 实际案例:某生鲜平台用 ES 支撑 “商品检索”(5 亿级数据)和 “订单日志查询”(3 亿级数据),日常并发 2000+,大促期间通过扩容节点轻松应对 5000 + 并发。
  • 适用场景:数据量 100 万 - 10 亿,并发量 500-5000 的成熟业务(如全国性电商、物流平台)。

4. 高级阶段:自研搜索引擎(数据量 100 亿 +,并发 10 万 +)

当数据量突破 100 亿、并发达到每秒 10 万次,且业务有强定制化需求(如特殊打分规则、极致实时性)时,开源系统的 “通用性” 会成为瓶颈 —— 此时需要自研搜索引擎。

自研核心思路:无限扩展(加机器即扩容)以 “电商商品检索” 的自研引擎 E-search 为例,架构分为三层:

  • Proxy 接入层(无状态)
    接收用户搜索请求(如 “2024 新款无线耳机”),根据负载均衡策略转发到 Merger 层。无状态设计让 “加机器就提升并发能力”,轻松应对 10 万 + QPS。
  • Merger 逻辑层(无状态)
    接收 Proxy 的请求,分发到多个 Searcher 节点查询,合并各节点结果后执行 Rank 打分(如 “新品权重 + 销量权重 + 好评率权重”)。业务规则在此灵活配置,同样支持水平扩容。
  • Searcher 检索层(数据与服务绑定)
    将索引数据水平切分(如按商品类目分成 8 组),每组冗余 3 份(保证高可用,避免单节点故障)。服务启动时加载索引到内存,查询直接操作内存,响应时间控制在 100 毫秒内。需要扩容时,增加切分组数或冗余节点即可。

适用场景:超大规模业务(数据 100 亿 +,并发 10 万 +),或有强定制化需求的大厂业务(如阿里、京东的商品搜索)。

四、高级话题:如何实现 “1 秒前的订单可检索”?

需求三提出:“必须检索出 5 分钟前的新闻、1 秒前的订单,不复杂吧?” 看似简单的 “实时性”,在超大规模数据场景下,需要特殊的架构设计 —— 核心是 “索引分级” 与 “Dump&Merge”。

1. 核心矛盾:实时更新与索引效率的冲突

倒排索引为了保证检索效率,必须 “紧密存储”(无碎片)。若每新增一条订单就修改索引,会产生大量碎片(如索引文件中出现空洞),导致检索速度从 100 毫秒降至 1 秒以上。因此,“实时修改索引” 不可行 —— 需用 “分级索引” 解决。

2. 索引分级:用 “多库协同” 实现实时性

将索引分为三级,不同级别对应不同时间范围的数据:

  • 全量库
    存储 500 亿 + 历史订单数据,索引紧密无碎片,检索速度最快(50 毫秒内);
  • 日增量库
    存储 1 天内新增 / 修改的订单(约 2000 万条),同样紧密存储,检索速度 100 毫秒内;
  • 分钟增量库
    存储 5 分钟内新增 / 修改的订单(约 50 万条),数据量小,查询速度 30 毫秒内。

更新逻辑:新增 / 修改订单时,只写入 “分钟增量库”(避免影响全量库);

查询逻辑:同时查询全量库、日增量库、分钟增量库,合并结果后去重 —— 既保证全量数据的检索效率,又能获取 1 秒前的最新订单。

3. Dump&Merge:异步合并,保持索引整洁

分级索引会导致 “数据分散”,需通过两个工具异步合并,保证各级索引数据量可控:

  • Dumper(导出)
    每 5 分钟将 “分钟增量库” 的数据导出为离线文件(如 JSON 格式),清空分钟库;
  • Merger(合并)
    每 24 小时将 “日增量库” 的数据合并到 “全量库”,同时清空日库。

优势:分钟库数据量始终控制在 50 万条内,保证实时性;全量库通过定时合并保持紧密存储,保证检索效率。若业务规模更大,还可增加 “秒级库”“月库”,进一步细化分级。

总结:

  1. 全网搜索引擎的核心架构由三大子系统组成,分别是负责抓取网页数据的 spider 爬虫系统、处理索引构建与查询的 search&index 系统,以及实现结果排序的 rank 打分系统。
  2. 站内搜索引擎与全网搜索引擎的核心差异在于数据获取方式:站内搜索无需 spider 子系统,可直接从内部业务系统(如内容发布系统)获取数据,而全网搜索需依赖 spider 主动抓取互联网网页。
  3. 从系统属性来看,spider 爬虫系统和 search&index 索引系统更偏向工程实现,通过合理的架构设计(如分布式部署、任务调度)即可满足基础功能需求;但 rank 打分系统需结合业务场景、用户偏好持续优化模型与权重,是一个需要长期迭代积累的过程。
  4. 正排索引(forward index)是一种高效的数据结构,核心作用是通过网页唯一标识 url_id,快速定位并获取该网页分词后的内容集合 list<item>,实现 “标识到内容” 的快速映射。
  5. 倒排索引(inverted index)则与正排索引方向相反,它以分词 item 为 key,可快速查询到包含该分词的所有网页唯一标识集合 list<url_id>,是实现 “内容到标识” 检索的核心。
  6. 用户检索的完整流程可拆解为三步:首先对输入的搜索词进行分词处理,得到多个 item;接着通过倒排索引分别查询每个 item 对应的网页 url_id 集合;最后对多个集合求交集,筛选出同时包含所有搜索词的网页,完成初筛。

  7. 针对有序集合求交集,常见的实现方法及特性如下:
    • 二重 for 循环法:逻辑简单但效率极低,时间复杂度为 O (n²),仅适用于极小数据量场景;
    • 拉链法:通过双指针遍历有序集合,元素最多被比较一次,时间复杂度优化至 O (n),是中小规模数据的常用方案;
    • 水平分桶 + 多线程并行:将集合按区间拆分到不同 “桶” 中,通过多线程并行计算各桶交集,再合并结果,可利用多核资源提升大规模数据处理效率;
    • bitmap 法:用 bit 位表示集合元素存在状态,通过 “位与” 操作快速求交集,运算并行度高,时间复杂度为 O (n),但对内存有一定要求;
    • 跳表法:在有序集合上构建多层索引,减少无效遍历次数,将时间复杂度降至接近 O (log n),是超大规模数据场景(如搜索引擎)的核心方案。

【声明】内容源于网络
0
0
二进制跳动
15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
内容 739
粉丝 0
二进制跳动 15 年 + 技术老兵 架构师|技术总监|科技创业技术合伙人 曾任职苏宁科技、电讯盈科、联想云 专注架构设计与技术落地
总阅读385
粉丝0
内容739