搜尋引擎新架構:與SQL不得不說的故事
阿里巴巴搜尋引擎HA3架構
1.HA3架構分為線上和離線兩部分
- 線上是一個傳統的2層服務架構,分別叫做QRS和search。QRS負責接受使用者請求,做一些簡單處理之後把請求發給下面的search節點,search節點負責載入索引並完成檢索,最終由QRS彙集各個search節點的結果並返回給使用者。
- 離線部分分為兩個環節,一個環節是資料的預處理,其核心的工作是把業務和演算法維度的資料加工成對索引友好的大寬表,另一個環節是索引的構建,它的主要挑戰是既要支援大規模的索引更新,也要保障索引是實時性。
2.HA3的特點主要有三個:
- 第一個是高效能的服務架構;
- 第二個是豐富的索引能力;
- 第三個是金字塔形的演算法工作框架
這些特點是HA3在阿里巴巴集團內風靡非常有利的武器,但隨著這幾年業務的發展,這一架構逐漸成了我們再往前進一步的攔路虎。
搜尋引擎HA3核心挑戰
具體體現在2個方面,一個是深度學習的滲透,另一個是資料維度的膨脹。
1. 深度學習
它的使用範圍,從早期的精排,逐步擴散到了粗排、檢索,比如向量索引的召回。深度學習的引入本身也會帶來2個問題:一個是深度模型的本身的網路結構通常比較複雜,對執行流程和模型大小都有非常高的要求,傳統的pipeline工作模式是非常難以有效支援的;另外一個問題是模型和特徵資料的實時更新也對索引的能力提出了很大的挑戰,在線上百億級別的更新是一個常態。
2. 資料維度的膨脹
以電商領域為例,原來考慮的維度主要是買家、賣家這兩個維度,現在得考慮位置、配送、門店、履約等等,同樣是配送,有3公里5公里送的,有同城的,還有跨城的,像這樣的例子還有很多。而搜尋引擎離線的工作流程會把各個維度的資料join成一張大寬表,這會導致資料更新的規模成笛卡爾積的形式展開,在新場景下,無論是更新的量級還是時效性上都很難滿足。
搜尋傳統解決方案
就是根據業務資料維度的特點,把引擎分拆成過多個不同的例項,然後在業務層通過查詢不同的引擎例項來得到結果。比如說餓了麼的搜尋引擎就有門店、商品等維度的資料,為了解決門店狀態的實時變化對索引的衝擊,可以部署兩個搜尋引擎例項,一個用來搜尋合適的門店,另外一個用來搜尋合適的商品,由業務方先查門店引擎再查商品引擎來完成。但這個方案有一個明顯的缺點,那就是符合使用者意圖的門店非常多的時候,門店的資料需要從門店引擎序列化到業務方再發送給商品引擎,這裡序列化的開銷非常大,往往需要對返回的門店數目做一定截斷,而截斷的門店中很可能有更匹配使用者意圖的,這樣對業務效果也會有比較大的影響。特別熱門的商區,不管是對使用者還是賣家,都是非常大的損失。
HA3 SQL新的解決方案
以資料庫SQL的執行方式來重塑搜尋,核心要點有3條。
1.將原來頻寬表的模式擴充套件成支援多表,每個表的索引載入、更新、切換做到相互獨立,把原來需要離線join的操作變成線上查詢時join。
2.徹底拋棄原有的pipeline的工作模式,以DAG圖化的方式來執行,並將搜尋的功能抽象成一個個獨立的運算元,與深度學習的執行引擎進行統一。
3.以SQL的方式來表達圖化的查詢流程,這樣不光使用者使用起來簡單,也可以複用SQL生態的一些基礎功能。舉個例子,電商個性化搜尋技術裡面,把商品、個性化推薦、深度模型等資訊分別放到不同的表中,配合上靈活的索引格式,比如倒排索引、正排索引、KV索引等等,加上執行引擎本身可以支援並行、非同步、編譯優化等技術,不管是記憶體還是CPU都能得到有效利用,很輕鬆地就能解決業務上的各種問題。
搜尋引擎HA3新的架構
主要分為三層:
- 最底下一層是searchRuntime的Framework,其核心職責主要有索引管理和服務排程,其中索引部分主要是載入的策略和查詢介面,如計算儲存分離的支援、實時索引構建的支援等等;服務排程主要處理的是程序的failover和服務的更新,即通常意義的面向終態的二層排程,主要的特點是以統一的方式做程序的重啟、程式的更新、灰度的釋出等等。
- 中間這一層是DAG引擎層,其核心內容有兩個,一個是執行引擎本身,另一個就是運算元。這裡的執行引擎主要有三部分的能力,包括單機內圖的執行,分散式的通訊和深度學習,通過運算元間的互聯,我們能夠很方便的把搜尋的查詢流程和深度學習進行對接,實現深度學習在搜尋的各個階段的滲透,如向量檢索、粗排和精排。運算元部分的抽象是這輪架構抽象最重要的一環,把原來面向過程式的開發變成了獨立功能的開發,一方面要求運算元本身的功能要儘可能內聚,另一方面運算元級別的管理也更有利於功能的複用和釋出。
- 最上面一層是SQL查詢層,核心的工作有兩部分,一個是SQL解析,另外一個是查詢優化。由於DAG的流程可以任意定製,如何讓使用者更方便地構建圖、更方便的進行運算元間的協作會是很關鍵的問題,簡單、通用是個必須考慮的,這也是我們首選SQL的原因;另外一個原因是業界SQL的執行器,通常包含邏輯優化和物理優化兩個環節,這個對一個複雜的DAG的執行提供了非常好的抽象,我們也利用了這個機制來進行了很多細緻的優化,包括圖的變換、運算元合併、編譯優化等等。
實踐案例
1. 餓了麼
外賣搜尋場景的例子,假設使用者在搜尋框裡面輸入了一個關鍵詞"牛肉麵",搜尋引擎後臺的流程大體如下:通過使用者的位置資訊找到現在還在營業的、並且能賣牛肉麵的門店,每個門店給出最匹配的商品,最後返回最符合使用者需求的門店與商品。在這裡,門店營業情況如何、配送能力是否足夠、對應的商品有沒有賣完,這些資料都需要實時更新的,而在大規模的資料裡面快速找到匹配的資訊,也涉及到豐富的索引技術,比如空間索引、倒排索引、向量索引等等,最後門店和商品的排序也要依賴深度模型的參與,使用者的偏好、優惠資訊、距離都是很重要的因素。原有的搜尋流程是基於elasticsearch通過分別查詢門店和商品維度的表來實現的,但會有查詢結果截斷和深度學習接入困難的問題,而在HA3上這些問題都非常容易解決,遷移到新架構後,不光業務的長尾問題消失了,而且效能還提升1倍,給後續演算法的迭代留下了非常大的空間,這裡效能的提升主要來自於索引結構和查詢優化上的一些工作。
2.淘寶本地生活的服務
其核心的訴求也是希望在淘寶的搜尋裡面引入本地服務的概念,如天貓超市和盒馬的小時達的業務,通過將門店和商品維度的資料單獨分拆,不光更新能力提升了兩個數量級,還複用了餓了麼搜尋的很多功能。
3.釘釘的釘盤搜尋
業務上需要在傳統的搜尋上支援釘盤檔案的許可權控制,由於檔案和許可權這兩個維度資料的規模都非常大,而且更新比較頻繁,通過HA3SQL線上的實時本地join,非常低延遲的解決了這個問題。
4.內部監控系統
原來是基於開源技術druid構建的,但業務規模上來逐步不能滿足需求了,經常出現異常需要手動處理的情況,我們在HA3的基礎上擴充套件了時序資料索引,藉助SQL並行執行的能力,latency有了明顯下降,穩定性也得到了質的提升。
本文為阿里雲原創內容,未經允許不得轉載。