阿里巴巴複雜搜尋系統的可靠性最佳化之路

閒魚技術發表於2019-03-14

背景

搜尋引擎是電商平臺成交鏈路的核心環節,搜尋引擎的高可用直接影響成交效率。閒魚搜尋引擎作為閒魚關鍵系統,複雜度和系統體量都非常高,再加上閒魚所有導購場景都依靠搜尋賦能,搜尋服務的穩定可靠成為了閒魚大部分業務場景可用能力的衡量標準;如何保障搜尋服務的穩定和高可用成為了極大的挑戰。

閒魚搜尋作為閒魚核心系統,有以下幾個突出的特點: * 資料體量大:對接閒魚數十億的商品,引擎有效商品數億; * 索引龐大:閒魚非結構化商品需要與演算法團隊合作,預測抽取有價值的結構化資訊,建立索引;已建立數百的索引欄位,整個引擎索引資料量為T級別; * 增量訊息多:日常增量訊息QPS 數十萬,峰值QPS可以達到 數百萬; * 查詢複雜:很多特殊業務場景,查詢條件要求苛刻而複雜;比如召回GROUP分組統計,聚合/打散/去重,關鍵詞複合運算查詢等; * 實時性性要求高:閒魚中都是二手商品,賣家商品的庫存都是1;商品上下架頻繁,對引擎資料的同步更新實時性要求非常高; * 智慧化擴充套件:由於閒魚商品非結構化特性,為保障召回資料的效果以及相關性;需要引擎具備智慧外掛擴充套件的能力,能與演算法開發人員協同;

鑑於閒魚商品搜尋引擎以上主要特點,本文詳細介紹閒魚搜尋在系統高可用上做的各種努力,希望能給讀者一些啟發。

閒魚搜尋整體架構

正式引出搜尋穩定性保障方案之前,我們需要對閒魚搜尋技術有一個簡單大致的瞭解;

我們比較過很多外部開源的搜尋引擎,都不能完美支援背景中所列的需求點;閒魚使用的是阿里巴巴最新研發的搜尋引擎平臺Ha3,Ha3是一款非常高效,智慧強大的搜尋引擎,它完全滿足閒魚搜尋的要求;
Elasticsearch是基於Lucene的準實時搜尋引擎,也是比較常用的開源搜尋引擎,但是其在演算法擴充套件支撐/絕對實時的能力上與Ha3相差甚遠;在同等硬體條件下,基於1200萬資料做單機效能對比測試發現,Ha3比ElasticSearch開源系統的QPS高4倍,查詢延遲低4倍;Elasticsearch在大規模資料量場景下的效能和穩定性與HA3相比尚有很大的差距。

01

閒魚搜尋體系執行流程

下圖是閒魚搜尋體系系統結構圖,主要分線上和離線兩個流程;


阿里巴巴複雜搜尋系統的可靠性最佳化之路

索引構建流程

索引構建即我們所謂的離線流程,其執行者BuildService①,負責將不同儲存型別的純文字商品資料構建成搜尋引擎格式的索引檔案。原始的商品資料有兩類,一類是存放在儲存上的全量商品資料,這個定期(一般以天為週期)透過DUMP②產出,另一類為實時變更的資料,在商品資訊變更後,由業務系統即時同步給訊息系統Swift③。最終分發給線上服務的Searcher④更新索引。

搜尋查詢流程

搜尋查詢即我們所謂的線上流程;閒魚搜尋服務應用A發起搜尋請求,透過SP⑤進行服務能力編排;首先SP發起QP⑥演算法服務呼叫,進行使用者意圖預測,並獲取排序輔助資訊;然後結合QP返回的結果加上業務系統的查詢引數,向Ha3搜尋引擎發起查詢請求;Ha3搜尋引擎QueryService⑦中Qrs⑧接收到查詢請求後,分發給QueryService中的Searcher進行倒排索引召回、統計、條件過濾、文件打分及排序、摘要生成;最後Qrs將Searcher返回的結果進行整合後返回給SP,SP經過去重再返回給業務系統;

02

閒魚搜尋體系團隊構成

閒魚搜尋的運維體系,是一個相當複雜的構成;其中涉及很多團隊的鼎力協作;

首先必須有Ha3搜尋引擎團隊在底層提供核心的搜尋引擎能力支援;主要負責Ha3搜尋引擎核心能力的建設維護;提供並維護引擎運維操作平臺和實時引擎搜尋服務。
然後是演算法團隊,在Ha3搜尋引擎上進行定製,最佳化使用者搜尋體驗;對閒魚非結構化的商品透過演算法模型進行理解,預測抽取出結構化資訊,供搜尋引擎商品索引使用;監控維護QP叢集服務;開發並使用Ha3引擎排序外掛,進行召回資料分桶實驗,驗證調優。
最後是我們業務工程團隊,串聯整個搜尋流程,監控維護整個搜尋鏈路的可用性;主要維護搜尋對接的資料,Ha3搜尋引擎接入管理,進行SP搜尋服務編排,制定合理的查詢計劃;以及閒魚搜尋統一線上查詢服務的研發維護工作。
本文亦是從業務工程團隊的工作角度出發,闡述如何對複雜搜尋業務系統進行穩定性的保障;

穩定性治理


01

部署架構最佳化


獨立閘道器部署

Ha3引擎透過SP提供基於HTTP協議的搜尋服務API,對類似閒魚這樣複雜的搜尋場景,每個閒魚上層的業務如果都透過拼接SP HTTP介面引數的形式來使用搜尋服務,所有上游業務都需要關心SP的拼接語法,會使開發成本劇增,而且如果由於特殊原因SP進行了語法調整或者不相容升級,那麼所有上層業務都需要修正邏輯,這樣的設計不合理;為了讓業務系統與搜尋系統完全解耦,並且提高搜尋服務的易用性,閒魚搜尋透過統一的業務搜尋閘道器來提供簡單一致的分散式服務,供閒魚各上層搜尋業務使用,並與SP對接,遮蔽掉SP對上游業務系統的穿透;
最開始閒魚搜尋服務與其他很多不相關的業務場景共建在一個比較龐大的底層應用中;這種部署方式對穩定性要求很高的業務模組來說有非常大的安全隱患;
1.各業務模組會相互影響;存在一定程度的程式碼耦合,同時還涉及機器資源的競爭,風險比較高;
2.應用太過龐大,嚴重影響開發協作的效率和程式碼質量;
於是將閒魚搜尋服務部署到獨立的容器分組,新增應用A供閒魚搜尋服務專用,作為各業務使用搜尋服務的獨立閘道器,同時對接下游的SP搜尋服務;保證服務是隔離和穩定的。
前後部署圖如下所示;
阿里巴巴複雜搜尋系統的可靠性最佳化之路

多機房容災部署

在最初,閒魚商品搜尋服務對接的Ha3搜尋引擎只部署在一個機房;當此機房出現比較嚴重的問題時,對上游業務影響非常大,甚至會引發故障;鑑於此,對閒魚商品搜尋引擎的線上離線叢集進行雙機房部署容災;在詳細展開之前,我們先大致理解下Ha3引擎DUMP流程的原理;
阿里巴巴複雜搜尋系統的可靠性最佳化之路
如上圖所示,Ha3引擎DUMP流程大致流程可以簡單分為以下幾步: * 準備源資料:評估業務需求,將需要接入引擎的資料準備好;一般業務資料大部分都是DB資料表,也有少數的ODPS⑨離線資料表;演算法團隊提供的資料絕大部分都是ODPS離線資料表; * DUMP拉取資料:透過Ha3引擎團隊提供的運維平臺,可以將這些表的某些資料欄位接入到建立好的搜尋引擎中,後續DUMP執行的時候,Ha3離線引擎會拉取這些接入的表欄位資料,形成一份引擎自用的映象資料表,在這一步中,我們可以使用引擎團隊提供的UDF工具,對資料進行清洗/過濾等處理; * 資料Merge:引擎將所有的映象表資料,透過我們指定的主鍵進行Join;最終形成一份資料大寬表;供引擎建立索引使用;這一步資料Join後,還可以對最終的資料透過UDF進行進一步的清洗/過濾處理,驗證透過的資料才會進入到大寬表; * 建立更新索引:Ha3離線引擎透過buildService,使用大寬表的資料,與事先我們在Ha3引擎運維平臺指定好的索引Schame對齊,重新構建索引;

以上流程可以透過Ha3引擎運維平臺手動觸發執行,執行完上述流程後,會生成一份新的索引;新的索引叢集服務可用後,線上實時模組會將查詢服務切換到新的索引叢集上,完成一次索引的更新;這個完整流程我們將其稱之為"全量";
全量完成後,當系統有新的商品資訊變動,且相應的資料表有啟用實時更新(我們稱之為增量功能,DB表是透過binlog/ODPS表是透過Swift訊息通知的方式實現),則離線DUMP引擎會感知到此次變動,進而將相應的映象資料表中商品資料更新,並會按上述離線DUMP流程中的步驟,將這個改動資訊一直向引擎上層投遞,直至成功更新引擎索引中的相應資料,或者中途被系統規則丟棄為止;這個實時資料更新的流程我們稱之為"增量";增量更新還有一條通道:演算法同學可以使用特殊的方式,透過Swift增量訊息的方式直接將需要更新的資料不透過DUMP流程,直接更新到Ha3引擎索引中。
閒魚商品量飛速增長,目前已經達到數十億;接入了數百的索引欄位,由於閒魚商品非結構化的原因,索引欄位中只有一小部分供業務使用;另外大部分都是演算法接入的索引,比如大量抽出來的標籤資料,向量化資料等,這些向量化資料非常大;最終的情形表現為閒魚商品搜尋引擎的DUMP處理邏輯比較複雜,而且索引資料總量異常龐大,增量訊息量也處在非常高的水位,再加上閒魚商品單庫存的現狀;因此對資料更新的實時性要求非常高,這些都給穩定性帶來了極大的制約。
索引資料是搜尋引擎的內容核心,如果進入引擎的索引資料有問題,或者新變更的資料沒有更新到引擎索引中,將直接影響搜尋服務的質量;
搜尋引擎單機房部署期間,時常會因為一些不穩定的因素,導致DUMP全量失敗,或者增量延遲,甚至停止;一旦引擎DUMP出現問題,需要恢復基本都很困難,很多場景下甚至需要重新跑全量才能解決問題;但是閒魚商品索引資料體量較大,做一次全量往往要大半天,沒有辦法快速止血,對業務造成了較大的影響;於是對搜尋引擎進行雙機房部署容災(M/N機房),互為備份;
兩個離線DUMP機房採用相同的引擎配置和相同的資料來源,產出相同的索引資料,分別供兩個線上機房使用,兩個機房的線上流量比例也可以按需實時調整;當M機房出現不可逆問題時,自動或手動將流量全部切換到N機房,實現線上快速止血,然後再按部就班排查解決M機房的問題。

下圖為最終的搜尋機房部署情況;
阿里巴巴複雜搜尋系統的可靠性最佳化之路
進行引擎雙機房部署雖然增大了機器資源成本,但是除了上述業務容災優點外,還有以下好處; * 引擎需求的釋出,之前缺乏有效的灰度流程;當搜尋引擎有重大變更/升級,出現高風險的釋出時,可以先在單機房小流量beta測試,資料對比驗證透過後,再發布到另一個機房; * 平常單機房能支撐全部搜尋查詢業務的流量,當遇到大促或大型活動時,將兩個機房同時掛載提供服務,這樣搜尋服務能力和容量直接能翻倍;避免了單機房頻繁擴縮容的困擾; * 效能評估時,可以單獨對未承載流量的機房進行壓測,即使由於壓測導致當機也不會對線上業務造成影響;

02

流量隔離

上文獨立閘道器部署一節中講到,閒魚搜尋透過統一的業務搜尋閘道器來提供簡單一致的分散式服務,供閒魚各上層搜尋業務使用;使用統一的微服務,就必然帶來上游不同業務優先順序和可靠性保障的問題。
閒魚搜尋服務支撐了種類繁多的上游業務,為了統一對各業務場景的流量/服務質量進行度量和管理,在上游業務接入閒魚搜尋服務時,需要申請使用相應的業務來源,這個業務來源標示會伴隨著整個搜尋查詢的生命週期;在日誌採集時直接使用,從而可以針對業務維度進行監控告警,實時感知業務執行的健康情況(簡單監控檢視如下圖),也可以對具體業務進行流量管控,降級限流等;
阿里巴巴複雜搜尋系統的可靠性最佳化之路
搜尋業務來源生命週期圖

03

分級監控體系

對高穩定性系統,當出現問題,或者即將產生問題時,能即時感知,顯得尤為重要;方便實時進行跟蹤處理,防止繼續擴大;目前使用的主要手段是建立健全完善的多維度監控告警體系;


引擎基礎服務監控

使用監控可以快速發現問題,如果監控的粒度夠細還能進行問題的快速定位;不過有時也會存在誤報或者漏報的情況,因此真實的監控一定要結合每個業務自身系統的特性,梳理出關鍵鏈路,針對關鍵鏈路進行多維度360度無死角監控,並且進行合理的預警規則設定,監控預警才會比較有效;

閒魚搜尋引擎線上離線流程/各上游重要應用系統的核心鏈路上,建立了完備的日誌資料採集模組,對關鍵指標進行了精準的監控預警設定;做到任何問題都能及時被感知到。下圖是搜尋服務相應核心日誌以及監控告警情況。
阿里巴巴複雜搜尋系統的可靠性最佳化之路

模擬使用者行為的線上業務監控

上文提到,閒魚搜尋引擎索引體量比較大,需要很多團隊共同協作,搜尋流程複雜度比較高;而且有演算法同學的加入,對閒魚非結構化的商品做了很多AI識別,加上閒魚都是單庫存商品,對引擎實時性要求非常高;前面已經做了一些容災的保障方案;但是對實時性的感知上還需要更進一步,才能及時知道資料的準確情況,是否存在更新延遲,以及延遲時間大概是多久等一系列健康度資訊;
解法是從業務層面進行實時性的監控告警;提取出閒魚商品量比較大更新也比較頻繁的類目K,在閒魚的後臺業務系統中,透過jkeins間隔一定時間(時間步長可以實時調整),使用類目K作為關鍵詞和品類,根據商品更新時間索引降序招回,模擬使用者輪詢的方式傳送搜尋查詢請求,召回滿足要求的第一頁商品;然後根據引擎召回資料的商品更新時間與當前系統時間進行差值比對,大於閾值時長(可以實時調整)說明存在較嚴重的資料更新延遲,則進行告警資訊傳送;   

04

壓測

全鏈路壓測

對搜尋服務以及各上游業務系統進行全鏈路壓測改造;並使用線上真實的使用者請求構造大批次的壓測資料,在保證不影響線上業務正常進行的前提下,驗證鏈路在超大流量模型下系統的容量和資源分配是否合理,找到鏈路中的效能瓶頸點,驗證網路裝置和叢集容量。

引擎單鏈路壓測

Ha3搜尋引擎線上流程,支援透過回放線上高峰時段查詢流量的方式,進行引擎線上服務效能壓測。
Ha3搜尋引擎離線流程,支援透過回放一段時間Swift增量訊息的方式,進行引擎DUMP增量效能壓測。   

05

灰度釋出

閒魚商品的非結構化特性,離不開演算法賦能;在我們的研發週期中,與兩個演算法團隊,相當多的演算法同學保持著深度合作;給閒魚搜尋帶來了跨越式的發展,但是在團隊協作和研發效率上也給我們帶來了極大的挑戰。

演算法團隊、引擎團隊、加上業務工程團隊,非常大的搜尋專案開發小組,每週都有非常多的新演算法模型,新的引擎改造,新的業務模組需要上線。
大量的新增邏輯改動直接上線,會帶來很多問題;首先是程式碼層面,雖然預發環境有做充分測試,但也難保沒有邊緣邏輯存在測試遺漏的情況;即使預發測試都完全覆蓋,但線上和預發終究環境不同,線上大流量環境及有可能會暴露一些隱藏的程式碼問題;第二方面,假使程式碼沒有任何質量問題,但所有功能全部繫結上線,所有邏輯都混雜在一起,如何評定某個模組上線後的效果成為極大的困擾,特別是演算法模型的最佳化,和業務上新模式的嘗試,都需要根據詳細的效果反饋資料指標來指導進行下一步的最佳化方向;
因此急需一套灰度實驗保障體系,不僅可以用來協調和隔離整個搜尋業務中各個模組,做到對各模組進行單獨的效果評估;並且還能提高大家的協作效率,讓各模組能進行快速試錯,快速迭代;
阿里巴巴複雜搜尋系統的可靠性最佳化之路

為了解決以上非常重要的問題,業務工程團隊開發了一套實驗管理系統,用來進行搜尋實驗灰度排程管理,系統功能如上圖所示;其具有以下特點。 * 實驗靈活方便,一個實驗可以包含多個實驗元件,一個實驗元件可供多個實驗使用;一個實驗元件又可以包含多個實驗分桶; * 各頁面模組的實驗都可以在系統中實時調控,包括實驗的開/關;以及實驗之間的關係處理; * 搜尋實驗埋點全鏈路打通,統計各種實驗資料包表; * 統計資料接入了閒魚門戶和通天塔,可檢視各個指標不同分桶的實驗曲線; * 提升實驗迭代速度,提升演算法/業務效率,快速試錯,加速搜尋成交轉化的增長;

06

應急預案

根據評估分析或經驗,對搜尋服務中潛在的或可能發生的突發事件的關鍵點,事先制定好應急處置方案;當滿足一定的條件時進行多維度多層級的自動降級限流,或者配置手動預案進行人工干預;

任何時候發現線上問題,首先需要快速止血,避免問題的擴大;具有自動預案會自動發現問題,自動熔斷,我們需要密切關注系統的執行情況,防止反彈;若出現反彈,並且對業務有較大影響時,快速人工介入執行降級預案;完成止血後再詳細排查具體原因,當短時間無法確定問題根源時,如在問題出現時有過變更或釋出,則第一時間回滾變更或釋出。

阿里巴巴複雜搜尋系統的可靠性最佳化之路
對系統中各級的依賴服務,熔斷降級已經系統負載保護,我們使用的是阿里巴巴自主研發的資源呼叫控制元件Sentinel[4],目前已經開源;或者也可以使用Hytrix降級限流工具;

07

問題排查

將閒魚搜尋鏈路接入阿里搜尋問題排查平臺,搜尋實時查詢請求的各個步驟輸入的引數資訊/產出的資料資訊都會在此工具平臺詳細展示,方便各種問題的排查跟進,以及資料資訊對比;

可以對各查詢條件下各個分桶的實驗召回資料進行視覺化顯示,方便各個實驗間的效果對比;以及每個召回商品的各類細節資訊檢視,包括業務資料和演算法標籤資料,還包含每個商品對應的各引擎外掛算分情況,都能詳細閱覽;
還可以根據商品Id,賣家Id,賣家Nick進行商品索引資訊的披露;可以排查相應商品在引擎索引中的詳細資料,如果資料和預想的有出入,具體是離線DUMP哪一步的處理邏輯導致的狀態異常,都能一鍵查詢。
接入此問題排查平臺後,能非常直觀的掌握引擎的執行狀況,搜尋召回的鏈路狀態;對快速發現問題根源,即時修復問題都有非常重大的作用!

總結與展望

本文主要介紹閒魚如何保障複雜場景下搜尋引擎服務的穩定性,主要從架構部署,隔離性,容量評估,風險感知&管控等方面進行闡述,介紹瞭如何穩定支撐20+線上搜尋業務場景,做到了快速發現恢復線上問題,高效提前預知規避風險案例50+,極大程度提升了搜尋服務的使用者體驗,保障了閒魚搜尋全年無故障;

經過上述治理方案後,閒魚搜尋系統穩定性得到了極大的保障,同時我們也會繼續深耕,在搜尋能力的高可用、更易用上更進一步,讓上游業務更加順滑;
希望給各位讀者帶來一些思考和啟發。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900359/viewspace-2638374/,如需轉載,請註明出處,否則將追究法律責任。

相關文章