別再搞混檢索和搜索!一文講透技術(shù)演進與架構(gòu)邏輯
或許 99% 的開發(fā)者不會深度參與全網(wǎng)搜索引擎的搭建,但幾乎每個人都在業(yè)務(wù)中實現(xiàn)過 “檢索” 功能 —— 小到查詢后臺的一條訂單記錄,大到篩選電商平臺的千萬級商品數(shù)據(jù)。“檢索” 與 “搜索” 僅一字之差,背后卻藏著從簡單查詢到復(fù)雜系統(tǒng)的技術(shù)躍遷。本文將從業(yè)務(wù)需求出發(fā),拆解搜索與檢索的核心技術(shù)、架構(gòu)設(shè)計,以及不同階段的解決方案,讓復(fù)雜邏輯變得清晰可感。
一、從 “做個谷歌” 說起:全網(wǎng)搜索引擎的核心架構(gòu)
曾有人提出需求:“想做一個全網(wǎng)搜索引擎,和谷歌類似就行,兩個月能上線嗎?” 看似簡單的訴求,背后卻是一套涉及數(shù)據(jù)抓取、索引構(gòu)建、結(jié)果排序的復(fù)雜系統(tǒng)。要理解其難度,首先得拆解全網(wǎng)搜索引擎的宏觀架構(gòu)與核心流程。
1. 三大核心子系統(tǒng):支撐 “從網(wǎng)頁到結(jié)果” 的全鏈路
全網(wǎng)搜索引擎的核心能力由三個子系統(tǒng)協(xié)同實現(xiàn)(對應(yīng)架構(gòu)中粉色模塊),缺一不可:
- Spider 爬蟲系統(tǒng)相當(dāng)于搜索引擎的 “觸角”,負責(zé)主動遍歷互聯(lián)網(wǎng)上的網(wǎng)頁。它需要智能判斷 URL 優(yōu)先級(如資訊類網(wǎng)頁更新快,優(yōu)先抓取),應(yīng)對不同網(wǎng)站的反爬策略(如驗證碼、IP 限制),還要處理網(wǎng)頁編碼異常、死鏈等問題,是數(shù)據(jù) “入口” 的關(guān)鍵。
- Search&Index 索引系統(tǒng) 分為 “建索引” 和 “查索引” 兩大功能,是搜索引擎的 “中樞”。
Build_index將 Spider 抓取的網(wǎng)頁內(nèi)容加工處理 —— 先做分詞(如 “人工智能發(fā)展趨勢” 拆分為 “人工智能”“發(fā)展”“趨勢”),再構(gòu)建正排索引和倒排索引,把雜亂的網(wǎng)頁轉(zhuǎn)化為可快速查詢的結(jié)構(gòu)化數(shù)據(jù);
Search_index接收用戶的搜索詞,通過索引快速定位匹配的網(wǎng)頁,完成 “初步篩選”。
- Rank 打分排序系統(tǒng)決定用戶最終看到的結(jié)果順序。它會結(jié)合網(wǎng)頁相關(guān)性(如搜索詞在標(biāo)題中出現(xiàn)比在正文出現(xiàn)權(quán)重高)、網(wǎng)頁權(quán)威性(如政府官網(wǎng)比個人博客權(quán)重高)、用戶行為(如點擊量、停留時間)等上百個維度計算得分,是 “搜索體驗優(yōu)劣” 的核心,也是谷歌、百度等引擎體驗差異的關(guān)鍵。
2. 兩大核心數(shù)據(jù):連接 “抓取” 與 “檢索” 的橋梁
系統(tǒng)的運轉(zhuǎn)依賴兩類核心數(shù)據(jù):
- Web 網(wǎng)頁庫存儲 Spider 抓取的原始網(wǎng)頁數(shù)據(jù),相當(dāng)于 “數(shù)據(jù)倉庫”。由于要容納千億級網(wǎng)頁,它必須是分布式存儲系統(tǒng)(如 HDFS),且需支持高容錯(避免單節(jié)點故障丟失數(shù)據(jù))和動態(tài)擴容(隨網(wǎng)頁量增長增加節(jié)點)。
- Index 索引數(shù)據(jù)即Build_index生成的正排索引和倒排索引,是 “快速查詢的鑰匙”。它的設(shè)計直接決定檢索速度 —— 好的索引結(jié)構(gòu)能讓 “從搜索詞到網(wǎng)頁” 的查詢耗時控制在毫秒級。
3. 核心邏輯:“寫入” 與 “檢索” 分離
全網(wǎng)搜索引擎的業(yè)務(wù)特性,決定了它必須是 “寫入” 和 “檢索” 分離的系統(tǒng):
全網(wǎng)搜索引擎的業(yè)務(wù)特性,決定了它必須是 “寫入” 和 “檢索” 分離的系統(tǒng):
- 寫入流程(數(shù)據(jù)進入系統(tǒng)):由 Spider 和 Search&Index 協(xié)同完成。
Spider 根據(jù) URL 隊列,批量抓取互聯(lián)網(wǎng)網(wǎng)頁;
將網(wǎng)頁內(nèi)容(含 HTML、圖片鏈接等)存儲到 Web 網(wǎng)頁庫;
Build_index從網(wǎng)頁庫讀取數(shù)據(jù),清洗無效內(nèi)容(如廣告代碼)后分詞;
生成正排索引和倒排索引,存入 Index 索引數(shù)據(jù)中。這個過程是 “離線 + 異步” 的 —— 網(wǎng)頁抓取后不會立刻進入索引,需經(jīng)過處理和構(gòu)建,保證索引的完整性和高效性。
- 檢索流程(用戶獲取結(jié)果):由 Search&Index 和 Rank 協(xié)同完成。
用戶輸入搜索詞(如 “2024 新能源汽車銷量”),Search_index先對搜索詞分詞;
通過倒排索引查詢匹配的網(wǎng)頁(初篩結(jié)果);
Rank 對初篩結(jié)果按得分排序,過濾低質(zhì)量網(wǎng)頁(如惡意跳轉(zhuǎn)頁);
返回排序后的 Top 結(jié)果(如首頁 10 條)。這個過程是 “實時 + 同步” 的 —— 用戶等待時間需控制在 1-3 秒內(nèi),否則會直接放棄搜索。
二、檢索的基石:正排索引與倒排索引
無論是全網(wǎng)搜索還是業(yè)務(wù)中的簡單檢索,核心都依賴 “正排索引” 和 “倒排索引” 這兩種數(shù)據(jù)結(jié)構(gòu)。理解它們,就掌握了 “快速查詢” 的關(guān)鍵。
1. 正排索引:從 “key” 找 “內(nèi)容”
正排索引的邏輯很簡單:通過唯一標(biāo)識(key)快速查詢對應(yīng)的實體內(nèi)容,類似我們用手機號查聯(lián)系人信息。
- 舉例 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=數(shù)碼,也是正排索引查詢。
在搜索場景中,網(wǎng)頁內(nèi)容會先分詞,此時正排索引可理解為Map<url_id, List<分詞項>>—— 比如url_id=2001對應(yīng)分詞["人工智能", "發(fā)展", "趨勢"],能通過url_id快速定位網(wǎng)頁的分詞結(jié)果,時間復(fù)雜度接近 O (1)。
2. 倒排索引:從 “內(nèi)容” 找 “key”
倒排索引與正排索引相反:通過 “內(nèi)容片段(如分詞項)” 快速查詢對應(yīng)的唯一標(biāo)識(key),是搜索的核心。它的結(jié)構(gòu)可理解為Map<分詞項, List<url_id>>—— 比如分詞 “人工智能” 對應(yīng)[2001, 2003, 2005],表示url_id=2001“2003”“2005” 的網(wǎng)頁都包含 “人工智能” 這個詞。
舉個具體例子理解:
假設(shè)有 3 個網(wǎng)頁,正排索引(分詞后)如下:
- url_id=2001 → 內(nèi)容 “人工智能發(fā)展趨勢” → 分詞["人工智能", "發(fā)展", "趨勢"]
- url_id=2002 → 內(nèi)容 “人工智能應(yīng)用場景” → 分詞["人工智能", "應(yīng)用", "場景"]
- url_id=2003 → 內(nèi)容 “應(yīng)用場景分析” → 分詞["應(yīng)用", "場景", "分析"]
對應(yīng)的倒排索引就是:
- “人工智能” → [2001, 2002]
- “發(fā)展” → [2001]
- “趨勢” → [2001]
- “應(yīng)用” → [2002, 2003]
- “場景” → [2002, 2003]
- “分析” → [2003]
當(dāng)用戶搜索 “人工智能應(yīng)用” 時,系統(tǒng)先分詞為["人工智能", "應(yīng)用"],再通過倒排索引找到兩個分詞對應(yīng)的url_id列表,最后求交集[2002]—— 這就是 “初篩結(jié)果” 的由來。
3. 關(guān)鍵優(yōu)化:有序集合求交集的 5 種方法
檢索的核心步驟 “求分詞結(jié)果的交集”,其效率直接影響搜索速度。由于倒排索引的List<url_id>會提前排序(便于優(yōu)化),我們可以通過不同方法提升交集效率:

以跳表為例:若url_id列表是[101,102,103,104,201,202,301,302],可建立一級索引[101,201,301]。查詢 “201” 時,無需遍歷前 4 個元素,直接通過索引跳到 201,效率大幅提升 —— 這也是谷歌、百度等主流搜索引擎的核心優(yōu)化手段。
三、業(yè)務(wù)檢索的 4 個階段:從簡單到復(fù)雜的演進
并非所有檢索需求都需要 “全網(wǎng)搜索” 級別的架構(gòu)。隨著數(shù)據(jù)量、并發(fā)量的增長,業(yè)務(wù)檢索會經(jīng)歷 4 個階段,每個階段對應(yīng)不同的技術(shù)方案。
1. 原始階段:用 SQL 的 LIKE 實現(xiàn)(創(chuàng)業(yè)初期)
核心邏輯:直接用數(shù)據(jù)庫的LIKE語句匹配內(nèi)容,無需額外開發(fā)。比如查詢標(biāo)題包含 “無線耳機” 的商品:
SELECT goods_id FROM t_goods WHERE name LIKE '%無線耳機%'優(yōu)點:零開發(fā)成本,10 分鐘就能上線;
缺點:全表掃描,數(shù)據(jù)量超 10 萬就會卡頓(如查詢耗時從 0.1 秒增至 5 秒以上);不支持分詞(如搜 “無線耳機降噪” 無法匹配 “降噪無線耳機”)。適用場景:創(chuàng)業(yè)初期,數(shù)據(jù)量 < 10 萬,并發(fā)量 < 100 的業(yè)務(wù)驗證場景(如小電商試運營)。
2. 初級階段:數(shù)據(jù)庫全文索引(數(shù)據(jù)量百萬級)
核心邏輯:利用數(shù)據(jù)庫的全文索引特性,替代LIKE,支持分詞和快速查詢。
比如 MySQL 中創(chuàng)建商品標(biāo)題的全文索引:
ALTER TABLE t_goods ADD FULLTEXT INDEX idx_goods_name (name);
-- 查詢時用MATCH AGAINST實現(xiàn)分詞檢索
SELECT goods_id FROM t_goods WHERE MATCH(name) AGAINST ('無線耳機降噪');優(yōu)點:支持分詞,效率比LIKE高 50-100 倍(百萬數(shù)據(jù)查詢耗時從 10 秒降至 0.1 秒);無需引入外部系統(tǒng),運維成本低;
缺點:僅支持 MyISAM 引擎(InnoDB 需 MySQL 5.6+);檢索與 CURD 耦合(如大促期間下單量高,會導(dǎo)致檢索卡頓);數(shù)據(jù)量超百萬后性能驟降,難以水平擴展。
適用場景:數(shù)據(jù)量 10 萬 - 100 萬,并發(fā)量 100-500 的成長型業(yè)務(wù)(如區(qū)域型電商)。
3. 中級階段:開源外置索引(數(shù)據(jù)量千萬 - 10 億級)
核心邏輯:將 “檢索” 與 “存儲” 分離 —— 原始數(shù)據(jù)存在數(shù)據(jù)庫(負責(zé) CURD),檢索用外置索引系統(tǒng)(負責(zé)分詞、查詢),通過 “雙寫”“定時同步” 保證數(shù)據(jù)一致性。主流方案是ElasticSearch(ES),它基于 Lucene 內(nèi)核,封裝了高可用、負載均衡能力,提供 RESTful 接口,開箱即用。ES 的優(yōu)勢:
- 支持 10 億級數(shù)據(jù)存儲,并發(fā)量可達 5000+(壓測場景下,單集群支持每秒 5000 次查詢);
- 天然支持集群,水平擴展簡單(新增節(jié)點即可擴容,無需修改代碼);
- 豐富的插件生態(tài)(如ik_smart中文分詞插件、geo_point地理位置插件),滿足個性化需求(如 “附近的咖啡店” 檢索)。
- 實際案例:某生鮮平臺用 ES 支撐 “商品檢索”(5 億級數(shù)據(jù))和 “訂單日志查詢”(3 億級數(shù)據(jù)),日常并發(fā) 2000+,大促期間通過擴容節(jié)點輕松應(yīng)對 5000 + 并發(fā)。
- 適用場景:數(shù)據(jù)量 100 萬 - 10 億,并發(fā)量 500-5000 的成熟業(yè)務(wù)(如全國性電商、物流平臺)。
4. 高級階段:自研搜索引擎(數(shù)據(jù)量 100 億 +,并發(fā) 10 萬 +)
當(dāng)數(shù)據(jù)量突破 100 億、并發(fā)達到每秒 10 萬次,且業(yè)務(wù)有強定制化需求(如特殊打分規(guī)則、極致實時性)時,開源系統(tǒng)的 “通用性” 會成為瓶頸 —— 此時需要自研搜索引擎。
自研核心思路:無限擴展(加機器即擴容)以 “電商商品檢索” 的自研引擎 E-search 為例,架構(gòu)分為三層:
- Proxy 接入層(無狀態(tài))接收用戶搜索請求(如 “2024 新款無線耳機”),根據(jù)負載均衡策略轉(zhuǎn)發(fā)到 Merger 層。無狀態(tài)設(shè)計讓 “加機器就提升并發(fā)能力”,輕松應(yīng)對 10 萬 + QPS。
- Merger 邏輯層(無狀態(tài))接收 Proxy 的請求,分發(fā)到多個 Searcher 節(jié)點查詢,合并各節(jié)點結(jié)果后執(zhí)行 Rank 打分(如 “新品權(quán)重 + 銷量權(quán)重 + 好評率權(quán)重”)。業(yè)務(wù)規(guī)則在此靈活配置,同樣支持水平擴容。
- Searcher 檢索層(數(shù)據(jù)與服務(wù)綁定)將索引數(shù)據(jù)水平切分(如按商品類目分成 8 組),每組冗余 3 份(保證高可用,避免單節(jié)點故障)。服務(wù)啟動時加載索引到內(nèi)存,查詢直接操作內(nèi)存,響應(yīng)時間控制在 100 毫秒內(nèi)。需要擴容時,增加切分組數(shù)或冗余節(jié)點即可。
適用場景:超大規(guī)模業(yè)務(wù)(數(shù)據(jù) 100 億 +,并發(fā) 10 萬 +),或有強定制化需求的大廠業(yè)務(wù)(如阿里、京東的商品搜索)。
四、高級話題:如何實現(xiàn) “1 秒前的訂單可檢索”?
需求三提出:“必須檢索出 5 分鐘前的新聞、1 秒前的訂單,不復(fù)雜吧?” 看似簡單的 “實時性”,在超大規(guī)模數(shù)據(jù)場景下,需要特殊的架構(gòu)設(shè)計 —— 核心是 “索引分級” 與 “Dump&Merge”。
1. 核心矛盾:實時更新與索引效率的沖突
倒排索引為了保證檢索效率,必須 “緊密存儲”(無碎片)。若每新增一條訂單就修改索引,會產(chǎn)生大量碎片(如索引文件中出現(xiàn)空洞),導(dǎo)致檢索速度從 100 毫秒降至 1 秒以上。因此,“實時修改索引” 不可行 —— 需用 “分級索引” 解決。
2. 索引分級:用 “多庫協(xié)同” 實現(xiàn)實時性
將索引分為三級,不同級別對應(yīng)不同時間范圍的數(shù)據(jù):
- 全量庫存儲 500 億 + 歷史訂單數(shù)據(jù),索引緊密無碎片,檢索速度最快(50 毫秒內(nèi));
- 日增量庫存儲 1 天內(nèi)新增 / 修改的訂單(約 2000 萬條),同樣緊密存儲,檢索速度 100 毫秒內(nèi);
- 分鐘增量庫存儲 5 分鐘內(nèi)新增 / 修改的訂單(約 50 萬條),數(shù)據(jù)量小,查詢速度 30 毫秒內(nèi)。
更新邏輯:新增 / 修改訂單時,只寫入 “分鐘增量庫”(避免影響全量庫);
查詢邏輯:同時查詢?nèi)繋臁⑷赵隽繋臁⒎昼娫隽繋欤喜⒔Y(jié)果后去重 —— 既保證全量數(shù)據(jù)的檢索效率,又能獲取 1 秒前的最新訂單。
3. Dump&Merge:異步合并,保持索引整潔
分級索引會導(dǎo)致 “數(shù)據(jù)分散”,需通過兩個工具異步合并,保證各級索引數(shù)據(jù)量可控:
- Dumper(導(dǎo)出)每 5 分鐘將 “分鐘增量庫” 的數(shù)據(jù)導(dǎo)出為離線文件(如 JSON 格式),清空分鐘庫;
- Merger(合并)每 24 小時將 “日增量庫” 的數(shù)據(jù)合并到 “全量庫”,同時清空日庫。
優(yōu)勢:分鐘庫數(shù)據(jù)量始終控制在 50 萬條內(nèi),保證實時性;全量庫通過定時合并保持緊密存儲,保證檢索效率。若業(yè)務(wù)規(guī)模更大,還可增加 “秒級庫”“月庫”,進一步細化分級。
總結(jié):
- 全網(wǎng)搜索引擎的核心架構(gòu)由三大子系統(tǒng)組成,分別是負責(zé)抓取網(wǎng)頁數(shù)據(jù)的 spider 爬蟲系統(tǒng)、處理索引構(gòu)建與查詢的 search&index 系統(tǒng),以及實現(xiàn)結(jié)果排序的 rank 打分系統(tǒng)。
- 站內(nèi)搜索引擎與全網(wǎng)搜索引擎的核心差異在于數(shù)據(jù)獲取方式:站內(nèi)搜索無需 spider 子系統(tǒng),可直接從內(nèi)部業(yè)務(wù)系統(tǒng)(如內(nèi)容發(fā)布系統(tǒng))獲取數(shù)據(jù),而全網(wǎng)搜索需依賴 spider 主動抓取互聯(lián)網(wǎng)網(wǎng)頁。
- 從系統(tǒng)屬性來看,spider 爬蟲系統(tǒng)和 search&index 索引系統(tǒng)更偏向工程實現(xiàn),通過合理的架構(gòu)設(shè)計(如分布式部署、任務(wù)調(diào)度)即可滿足基礎(chǔ)功能需求;但 rank 打分系統(tǒng)需結(jié)合業(yè)務(wù)場景、用戶偏好持續(xù)優(yōu)化模型與權(quán)重,是一個需要長期迭代積累的過程。
- 正排索引(forward index)是一種高效的數(shù)據(jù)結(jié)構(gòu),核心作用是通過網(wǎng)頁唯一標(biāo)識 url_id,快速定位并獲取該網(wǎng)頁分詞后的內(nèi)容集合 list<item>,實現(xiàn) “標(biāo)識到內(nèi)容” 的快速映射。
- 倒排索引(inverted index)則與正排索引方向相反,它以分詞 item 為 key,可快速查詢到包含該分詞的所有網(wǎng)頁唯一標(biāo)識集合 list<url_id>,是實現(xiàn) “內(nèi)容到標(biāo)識” 檢索的核心。
- 用戶檢索的完整流程可拆解為三步:首先對輸入的搜索詞進行分詞處理,得到多個 item;接著通過倒排索引分別查詢每個 item 對應(yīng)的網(wǎng)頁 url_id 集合;最后對多個集合求交集,篩選出同時包含所有搜索詞的網(wǎng)頁,完成初篩。
- 針對有序集合求交集,常見的實現(xiàn)方法及特性如下:
二重 for 循環(huán)法:邏輯簡單但效率極低,時間復(fù)雜度為 O (n2),僅適用于極小數(shù)據(jù)量場景;
拉鏈法:通過雙指針遍歷有序集合,元素最多被比較一次,時間復(fù)雜度優(yōu)化至 O (n),是中小規(guī)模數(shù)據(jù)的常用方案;
水平分桶 + 多線程并行:將集合按區(qū)間拆分到不同 “桶” 中,通過多線程并行計算各桶交集,再合并結(jié)果,可利用多核資源提升大規(guī)模數(shù)據(jù)處理效率;
bitmap 法:用 bit 位表示集合元素存在狀態(tài),通過 “位與” 操作快速求交集,運算并行度高,時間復(fù)雜度為 O (n),但對內(nèi)存有一定要求;
跳表法:在有序集合上構(gòu)建多層索引,減少無效遍歷次數(shù),將時間復(fù)雜度降至接近 O (log n),是超大規(guī)模數(shù)據(jù)場景(如搜索引擎)的核心方案。
































