Google搜索為什么不能無(wú)限分頁(yè)?
優(yōu)采云 發(fā)布時(shí)間: 2022-06-18 10:58Google搜索為什么不能無(wú)限分頁(yè)?
這是一個(gè)很有意思卻很少有人注意的問(wèn)題。
當我用Google搜索MySQL這個(gè)關(guān)鍵詞的時(shí)候,Google只提供了13頁(yè)的搜索結果,我通過(guò)修改url的分頁(yè)參數試圖搜索第14頁(yè)數據,結果出現了以下的錯誤提示:
Google不能無(wú)限分頁(yè)
百度搜索同樣不提供無(wú)限分頁(yè),對于MySQL關(guān)鍵詞,百度搜索提供了76頁(yè)的搜索結果。
百度不能無(wú)限分頁(yè)為什么不支持無(wú)限分頁(yè)
強如Google搜索,為什么不支持無(wú)限分頁(yè)?無(wú)非有兩種可能:
「做不到」是不可能的,唯一的理由就是「沒(méi)必要」。
首先,當第1頁(yè)的搜索結果沒(méi)有我們需要的內容的時(shí)候,我們通常會(huì )立即更換關(guān)鍵詞,而不是翻第2頁(yè),更不用說(shuō)翻到10頁(yè)往后了。這是沒(méi)必要的第一個(gè)理由——用戶(hù)需求不強烈。
其次,無(wú)限分頁(yè)的功能對于搜索引擎而言是非常消耗性能的。你可能感覺(jué)很奇怪,翻到第2頁(yè)和翻到第1000頁(yè)不都是搜索嘛,能有什么區別?
實(shí)際上,搜索引擎高可用和高伸縮性的設計帶來(lái)的一個(gè)副作用就是無(wú)法高效實(shí)現無(wú)限分頁(yè)功能,無(wú)法高效意味著(zhù)能實(shí)現,但是代價(jià)比較大,這是所有搜索引擎都會(huì )面臨的一個(gè)問(wèn)題,專(zhuān)業(yè)上叫做「深度分頁(yè)」。這也是沒(méi)必要的第二個(gè)理由——實(shí)現成本高。
我自然不知道Google的搜索具體是怎么做的,因此接下來(lái)我用ES(Elasticsearch)為例來(lái)解釋一下為什么深度分頁(yè)對搜索引擎來(lái)說(shuō)是一個(gè)頭疼的問(wèn)題。
為什么拿ES舉例子
Elasticsearch(下文簡(jiǎn)稱(chēng)ES)實(shí)現的功能和Google以及百度搜索提供的功能是相同的,而且在實(shí)現高可用和高伸縮性的方法上也大同小異,深度分頁(yè)的問(wèn)題都是由這些大同小異的優(yōu)化方法導致的。
什么是ES
ES是一個(gè)全文搜索引擎。
全文搜索引擎又是個(gè)什么鬼?
試想一個(gè)場(chǎng)景,你偶然聽(tīng)到了一首旋律特別優(yōu)美的歌曲,回家之后依然感覺(jué)余音繞梁,可是無(wú)奈你只記得一句歌詞中的幾個(gè)字:「傘的邊緣」。這時(shí)候搜索引擎就發(fā)揮作用了。
使用搜索引擎你可以獲取到帶有「傘的邊緣」關(guān)鍵詞的所有結果,這些結果有一個(gè)術(shù)語(yǔ),叫做文檔。并且搜索結果是按照文檔與關(guān)鍵詞的相關(guān)性進(jìn)行排序之后返回的。我們得到了全文搜索引擎的定義:
全文搜索引擎是根據文檔內容查找相關(guān)文檔,并按照相關(guān)性順序返回搜索結果的一種工具
網(wǎng)上沖浪太久,我們會(huì )漸漸地把計算機的能力誤以為是自己本身具備的能力,比如我們可能誤以為我們大腦本身就很擅長(cháng)這種搜索。恰恰相反,全文檢索的功能是我們非常不擅長(cháng)的。
舉個(gè)例子,如果我對你說(shuō):靜夜思。你可能脫口而出:床前明月光,疑是地上霜。舉頭望明月,低頭思故鄉。但是如果我讓你說(shuō)出帶有「月」的古詩(shī),想必你會(huì )費上一番功夫。
包括我們平時(shí)看的書(shū)也是一樣,目錄本身就是一種符合我們人腦檢索特點(diǎn)的一種搜索結構,讓我們可以通過(guò)文檔ID或者文檔標題這種總領(lǐng)性的標識來(lái)找到某一篇文檔,這種結構叫做正排索引。
目錄就是正排索引
而全文搜索引擎恰好相反,是通過(guò)文檔中的內容來(lái)找尋文檔,詩(shī)詞大會(huì )中的飛花令就是人腦版的全文搜索引擎。
飛花令就是全文搜索
全文搜索引擎依賴(lài)的數據結構就是大名鼎鼎的倒排索引(「倒排」這個(gè)詞就說(shuō)明這種數據結構和我們正常的思維方式恰好相反),它是單詞和文檔之間包含關(guān)系的一種具體實(shí)現形式。
單詞文檔矩陣
打??!不能繼續展開(kāi)了話(huà)題了,趕緊一句話(huà)介紹完ES吧!
ES是一款使用倒排索引數據結構、能夠根據文檔內容查找相關(guān)文檔,并按照相關(guān)性順序返回搜索結果的全文搜索引擎
高可用的秘密——副本(Replication)
高可用是企業(yè)級服務(wù)必須考慮的一個(gè)指標,高可用必然涉及到集群和分布式,好在ES天然支持集群模式,可以非常簡(jiǎn)單地搭建一個(gè)分布式系統。
ES服務(wù)高可用要求其中一個(gè)節點(diǎn)如果掛掉了,不能影響正常的搜索服務(wù)。這就意味著(zhù)掛掉的節點(diǎn)上存儲的數據,必須在其他節點(diǎn)上留有完整的備份。這就是副本的概念。
副本
如上圖所示,Node1作為主節點(diǎn),Node2和Node3作為副本節點(diǎn)保存了和主節點(diǎn)完全相同的數據,這樣任何一個(gè)節點(diǎn)掛掉都不會(huì )影響業(yè)務(wù)的搜索。滿(mǎn)足服務(wù)的高可用要求。
但是有一個(gè)致命的問(wèn)題,無(wú)法實(shí)現系統擴容!即使添加另外的節點(diǎn),對整個(gè)系統的容量擴充也起不到任何幫助。因為每一個(gè)節點(diǎn)都完整保存了所有的文檔數據。
因此,ES引入了分片(Shard)的概念。
PB級數量的基石——分片(Shard)
ES將每個(gè)索引(ES中一系列文檔的集合,相當于MySQL中的表)分成若干個(gè)分片,分片將盡可能平均地分配到不同的節點(diǎn)上。比如現在一個(gè)集群中有3臺節點(diǎn),索引被分成了5個(gè)分片,分配方式大致(因為具體如何平均分配取決于ES)如下圖所示。
分片
這樣一來(lái),集群的橫向擴容就非常簡(jiǎn)單了,現在我們向集群中再添加2個(gè)節點(diǎn),則ES會(huì )自動(dòng)將分片均衡到各個(gè)節點(diǎn)之上:
橫向擴展高可用 + 彈性擴容
副本和分片功能通力協(xié)作造就了ES如今高可用和支持PB級數據量的兩大優(yōu)勢。
現在我們以3個(gè)節點(diǎn)為例,展示一下分片數量為5,副本數量為1的情況下,ES在不同節點(diǎn)上的分片排布情況:
主分片和副分片的分布
有一點(diǎn)需要注意,上圖示例中主分片和對應的副本分片不會(huì )出現在同一個(gè)節點(diǎn)上,至于為什么,大家可以自己思考一下。
文檔的分布式存儲
ES是怎么確定某個(gè)文檔應該存儲到哪一個(gè)分片上呢?
通過(guò)上面的映射算法,ES將文檔數據均勻地分散在各個(gè)分片中,其中routing默認是文檔id。
此外,副本分片的內容依賴(lài)主分片進(jìn)行同步,副本分片存在意義就是負載均衡、頂上隨時(shí)可能掛掉的主分片位置,成為新的主分片。
現在基礎知識講完了,終于可以進(jìn)行搜索了。
ES的搜索機制
一圖勝千言:
客戶(hù)端進(jìn)行關(guān)鍵詞搜索時(shí),ES會(huì )使用負載均衡策略選擇一個(gè)節點(diǎn)作為協(xié)調節點(diǎn)(Coordinating Node)接受請求,這里假設選擇的是Node3節點(diǎn);
Node3節點(diǎn)會(huì )在10個(gè)主副分片中隨機選擇5個(gè)分片(所有分片必須能包含所有內容,且不能重復),發(fā)送search request;被選中的5個(gè)分片分別執行查詢(xún)并進(jìn)行排序之后返回結果給Node3節點(diǎn);Node3節點(diǎn)整合5個(gè)分片返回的結果,再次排序之后取到對應分頁(yè)的結果集返回給客戶(hù)端。
注:實(shí)際上ES的搜索分為Query階段和Fetch階段兩個(gè)步驟,在Query階段各個(gè)分片返回文檔Id和排序值,Fetch階段根據文檔Id去對應分片獲取文檔詳情,上面的圖片和文字說(shuō)明對此進(jìn)行了簡(jiǎn)化,請悉知。
現在考慮客戶(hù)端獲取990~1000的文檔時(shí),ES在分片存儲的情況下如何給出正確的搜索結果。
獲取990~1000的文檔時(shí),ES在每個(gè)分片下都需要獲取1000個(gè)文檔,然后由Coordinating Node聚合所有分片的結果,然后進(jìn)行相關(guān)性排序,最后選出相關(guān)性順序在990~1000的10條文檔。
深度分頁(yè)
頁(yè)數越深,每個(gè)節點(diǎn)處理的文檔也就越多,占用的內存也就越多,耗時(shí)也就越長(cháng),這也就是為什么搜索引擎廠(chǎng)商通常不提供深度分頁(yè)的原因了,他們沒(méi)必要在客戶(hù)需求不強烈的功能上浪費性能。
完。