Google 如何在 0.3 秒内显示搜索结果(它们在作弊,你也该这么做)
Source: Dev.to
实时搜索的幻觉
当你点击 搜索 时,你并不是在实时检索整个互联网,而是在检索 Google 预先计算好的互联网索引,这完全是两回事。
想象一个拥有一百万本书的图书馆,有人让你找出所有提到 “jollof rice” 的书。逐页扫描需要数天甚至数周。相反,你可以在事先花上几个月时间创建一个 索引——一本巨大的书,列出图书馆里出现的每个词以及这些词出现的具体书籍和页码。
当有人查询 “jollof rice” 时,你只需打开索引的 “jollof” 部分,看到包含该词的书籍和页码列表,同样查找 “rice”,找出两个列表的交集,然后在几秒钟内把答案交给对方。所有艰苦的工作都在有人提问之前完成。
这正是 Google 所做的,只是规模达到了行星级别。
实际搜索时发生了什么
让我们拆解这三百毫秒内的步骤:
- 前端服务器 (GFE) – 你的查询首先到达 Google 在全球分布的前端服务器,靠近你的地点(例如,你在拉各斯时会命中西非的 GFE)。
- 拼写纠正 – Google 检查是否有拼写错误并在必要时自动纠正。此过程运行在 Google 的内部基础设施 Borg(Kubernetes 的前身)上。
- 索引分片 – 已纠正的查询被发送到 Google 的索引分片。索引被拆分成成千上万的分片,分布在全球各数据中心。每个分片保存倒排索引的一部分以及实际文档数据。
- Top‑k 抓取 – 每个相关分片快速抓取约 1,000 条可能匹配查询的文档。索引已经排序并针对这种查找做了优化。
- 排序 – 所有这些结果被送到 Google 的排序系统,系统使用两百多种信号(位置、搜索历史、新鲜度、反向链接、移动友好性、页面速度等)在毫秒级完成排序。
- 格式化 – 前十条结果被格式化后返回给你的浏览器。整个过程不到半秒。
关键洞见: Google 并不是实时搜索数十亿页面,而是从持续在后台更新的预计算索引中查找结果。
倒排索引:Google 的秘密武器
倒排索引 存储词语以及包含这些词语的文档列表,而不是存储完整文档。
普通存储
Document 1 contains “I love jollof rice”
倒排索引
- “jollof” 出现在:Document 1, Document 2
- “rice” 出现在:Document 1
- “Lagos” 出现在:Document 2
当有人搜索 “jollof Lagos” 时,系统立刻知道 Document 2 是唯一同时包含这两个词的文档——无需扫描文档。
Google 的倒排索引覆盖数千亿网页、数万兆词汇。由于它是预先计算并在成千上万台服务器上分片的,查找速度极快。
增量索引:Google 如何保持最新
网页不断变化——新页面出现,旧页面更新,站点下线。如果每次都从头重建整个索引,那根本不可能。
Google 使用 增量索引:
- 爬虫持续浏览网页,寻找新内容或已更改的内容。
- 检测到变化后,仅更新索引中相关的部分。
- 热门新闻站点每几分钟爬取一次;小型站点可能每几天或几周爬取一次。
索引永远不可能做到绝对实时,但已经足够新,以至于用户几乎感觉不到延迟。突发新闻可以在几分钟内出现在搜索结果中;一篇小博客文章可能需要数小时甚至数天才被收录。
为什么 99 % 的应用都慢
大多数应用慢的原因是它们在每次请求时都进行全表扫描或复杂计算。Google 的做法恰恰相反:预计算 所有可能的结果。
示例:外卖应用
慢速做法
- 用户打开应用。
- 应用获取用户位置。
- 应用向数据库查询:“查找所有餐厅,计算距离,筛选 5 km 内的,按评分排序”。
- 数据库扫描数千行,执行距离计算,返回结果,需要几秒钟。
Google 风格做法
- 每隔几分钟,预先计算每个主要社区附近的餐厅列表。
- 将这些列表存入高速内存(如 Redis)。
- 用户打开应用时,直接查找对应社区的预计算列表。
- 结果在几百毫秒内呈现。
昂贵的工作(距离计算、过滤、排序)被移到后台任务,而不是请求时进行。
预计算重要的真实案例
- YouTube 推荐 – 算法在后台持续运行,实时更新数亿用户的推荐列表。打开应用时看到的列表是几分钟或几小时前预计算好的。
- Instagram 动态 – 动态在后台根据关注对象和互动历史组装。下拉刷新仅仅是获取已经构建好的动态。
- 电商搜索(Amazon) – 商品关键词、类别、属性的倒排索引实现瞬时查找,避免全目录扫描。
- 银行仪表盘 – 账户余额和交易历史在仪表盘视图中被聚合并缓存;主事务数据库负责写入,新写入实时显示在报告视图中则通过预计算实现。
权衡:新鲜度 vs. 速度
预计算带来的唯一主要权衡是数据可能略有陈旧。如果 Google 的索引在十分钟前更新,而某网站在五分钟前才改动,那么搜索结果暂时不会反映这次改动。
对大多数场景而言,这完全可以接受。用户更在乎响应速度,而不是完美的实时准确性。相对于预计算索引带来的显著性能提升,这点延迟几乎可以忽略不计。