天天看點

機票垂直搜尋引擎的性能優化

機票垂直搜尋引擎的性能優化 原文: 機票垂直搜尋引擎的性能優化

一、行業背景與垂直搜尋

我們先了解一下機票的行業背景,下圖是由中航信統計的資料,藍色的曲線代表平均每公裡的票價,紅色曲線指的是客運量。從2011年到2016年,無論是國内、港澳台還是國際,整體趨勢都是機票價格便宜了,坐飛機的人也越來越多了。特别是國際機票,這五年裡機票價格下降30%,客運量增長了140%。

機票垂直搜尋引擎的性能優化

乘客越來越多,購買機票的管道有哪些呢?現在主要有三個:網絡平台、代售點和航司官網。像攜程、去哪兒、飛豬、同程等,是主流的網絡購票平台;像旅行社這類代售點,是旅行團的主要購票管道;同時大部分航空公司的官網也可以購票,而且有相對較低的價格。總體來說,網絡平台是最大的銷售管道,占比76%。為什麼網絡平台占有這麼大的份額呢,主要原因是機票垂直搜尋引擎是主要的使用者流量入口,使用者一般是先比價然後再去預訂,一個好的機票搜尋引擎查詢的産品豐富、價格便宜,而且響應速度快,運價也準,這些特性在技術方面實作好并不容易。

二、主要問題與解決方案

機票查詢要快、準、低。快是指查詢快,能夠提供一個良好的使用者體驗;準是指運價準,可以保證出票的成功率;低是指票價低,能夠吸引更多的使用者。但是,如果票價要有優勢,就要有大量産品,産品資料多了查詢就慢,如果查詢要快,就必須要緩存,但是資料緩存了,運價就可能不準。這三者是沖突的,類似于CAP原則,具體示意圖如下:

機票垂直搜尋引擎的性能優化

對于以上問題,怎麼解決呢?通用的三個技術方案有:一、用DB+Redis平衡響應速度、資料實時性和查詢成本;二、用削峰填谷的MQ來處理高并發;三、将業務服務化、子產品解耦。這些隻是通用的技術點,并沒有什麼難度,我們這裡重點介紹與最終結果密切相關的四個子產品:靜态資料、緩存政策、實時查詢、政策比對。

  1. 靜态資料:能靜态處理的資料盡量靜态化,存儲到本地,可以是資料庫或緩存,以友善快速地查詢,如航班資訊、運價資料和政策資料等;
  1. 緩存政策:從中航信拿到運價資料之後,進行熱冷門資料分類,資料永不過期但持續更新,自主要制資料的更新頻率;
  1. 實時查詢:多管道多供應實時擷取遠端資料,多資料源查詢速度會變慢,遠端服務不可控,解決方案是三段逾時,即前端使用者逾時、中端營運逾時、後端供應逾時;
  1. 政策比對:大量的産品資料和大量的業務規則,不可能都提供給使用者,需要通過一定的算法進行比對過濾、排序等。

三、靜态資料與任務打底

機票查詢的靜态資料主要有:城市、機型、航司、運價資料等,這裡重點介紹較為複雜的運價資料,運價資料的擷取雖然間隔時間較長,但資料量大且更新頻次不同。運價資料是由中航信統一提供的,有兩種途徑:黑屏查詢和IBE接口,将擷取到的資料儲存到資料庫和緩存中,使用者查詢的時候直接從緩存中擷取,同時也會按照一定的緩存政策來更新。

最初我們設計了兩套方案來打底運價資料,兩個方案各有優劣。方案1是先預加載所有的運價資料,然後全部儲存到資料庫和緩存,然後在航班查詢時通過緩存政策進行相應地更新;方案2是把運價資料根據航線查詢頻率分為熱門和冷門資料,然後每天淩晨對熱門資料預加載,并在航班查詢的時候對冷門資料進行更新。可以看出,方案1能保證資料的完整性和實時性,但預加載用時太長;方案2能控制預加載用時,但熱門資料的實時性會從早到晚逐漸降低。兩個方案中都需要實時更新,在考慮資料實時性的同時,還要考慮擷取資料的費用,平衡好兩者才是一個實用的方案。

綜合對比之後,我們采用了方案1,具體實作如下圖所示:首先是通過Job對運價資料的初始化,然後以任務消息的方式發送給MQ,MQ裡的消息會被背景服務自動消費,執行消息隊列裡的任務,把運價資料儲存到資料庫和緩存。資料預加載之後,使用者在前台查詢時,如果緩存裡面沒有資料,或者查到的緩存資料是過期的,系統會自動發一條任務消息給MQ,或者人工配置指定的航線定時更新,Job也會自動發送任務消息給MQ,前台和背景的消息被服務消費以實作資料的更新。使用者的不斷請求和背景指定的任務,保證資料的持續更新,時間越久資料的準确性越高,使用者查詢的命中率也會越來越高。

機票垂直搜尋引擎的性能優化

四、緩存政策與資料一緻

上面說到運價資料同時存儲在資料庫和緩存,為什麼有了緩存還要資料庫呢?存儲到資料庫是為了友善資料的多元查詢和管理,包括對緩存的進一步幹預。資料庫查詢的功能強大,但速度慢,緩存的性能好,但從緩存裡擷取的資料,會有不準确的問題。怎麼才能做到查詢快而且資料準呢?我們的解決方法是緩存永不失效、資料分類、自主要制更新頻率,以實作運價資料的又快又準。

我們根據航線查詢的頻率,将可以分成熱門資料、冷門資料和沒有資料,航班多、查詢多的是熱門資料,航班少、查詢少的是冷門資料,查詢不到就是沒有資料。在預加載或更新運價資料時,将緩存設定為一個較長時間或永不過期,然後在前台通路時,不同資料類型采用不同的更新政策,具體如下:

  • 熱門航線查詢,在緩存中擷取資料,資料中有一個自己的緩存時間字段,然後根據這個時間來分别處理:
  • 1小時之内更新的:新鮮度較高,可以直接用;
  • 1-6小時之内更新的:預警n次,第n+1次命中時則異步更新運價;
  • 6小時之外更新的:新鮮度太低,異步更新運價;
  • 冷門航線查詢,與熱門航線一樣,隻是不預加載且緩存時間稍長:
  • 12個小時之内更新的:新鮮度較高,可以直接用;
  • 12-48個小時之内更新的:預警n次,第n+1次命中時則異步更新運價;
  • 48個小時之外更新的:新鮮度太低,異步更新運價;
  • 緩存沒有資料時,直接擷取最新運價,同時更新資料庫和緩存。
機票垂直搜尋引擎的性能優化

以上無論是預警後更新還是直接更新,都是先把緩存中資料傳回給使用者,同時異步更新資料庫和緩存。雖然有存在資料查詢不準确的機率,但被使用者再次查詢時就準确了。查詢到的資料即便不準确,在後繼的航班預訂時也會二次的驗艙驗價,運價資料和庫存資料會再次更新。使用者不斷地查詢,資料不斷地更新,查詢命中率就會越來越高,并且用的人越多情況會越好,會逐漸趨近于n個9。

五、實時查詢與三段逾時

能靜态化的資料我們要盡量靜态化,但遠端資料的實時查詢還是必不可少。實時查詢如何做到又快又好呢,特别是多資料源、多供應商的實時查詢場景。我們的國際機票查詢就是這樣,前台頁面點選查詢時實時調用供應商接口,早期我們僅調用一個供應接口,産品比較單一,資料不夠豐富,後面我們引入了多供應商,産品變豐富了,也有了低價,但同時帶來了很多新問題,比如供應端接口需要20~30秒,但前端客戶隻能接受8秒以内,怎麼辦?提高供應資料門檻?但這不是核心競争。還有查詢速度變慢、外部資料源不可控、資料格式多樣等問題。

機票垂直搜尋引擎的性能優化

對于以上問題,我們的解決辦法是三段逾時,所謂三段逾時,即供應端、營運端和用戶端。前端滿足客人、中間滿足營運控制政策、後端滿足供應商,三方都要滿意,這樣才能産品更豐富、價格更低、營運政策更靈活、使用者響應更及時。三段逾時的時間可以根據具體場景進行配置,具體如下:

  • 供應端逾時:供應端是後端,是指提供資料源的一方,供應端存在的問題就是外部不可控。供應端處于資料來源的最底端,解決辦法是盡量加大供應端的逾時時間限制。我們對請求供應接口的最大HTTP逾時時間設定為45秒,這個值可以滿足絕大部分情況。
  • 營運端逾時:營運端是中間端,把供應商的資料拿過來之後,做包裝轉換、去重、政策比對等業務處理。我們先統計每一個供應接口的請求時間,确認供應接口資料的品質和優先級,比如說:A供應資料的品質相比B和C供應資料的品質要高,那麼A的請求級别可以設定得高一些。我們優先考慮拿到A供應的資料,如果A的資料在8秒就傳回,而B和C的超過這個時間,那麼我們此時在前台就隻把A的資料傳回給客戶。對于B和C的資料,由于在HTTP請求時我們采用異步并設定了較大的供應端逾時,是以它會在A傳回之後,繼續異步請求并将傳回的資料儲存到緩存中,以供使用者下次或其他使用者使用。當我們拿到了多供應商的産品資料後,這時會有一定重複的資料,需要規範化處理,将不同資料格式轉換成統一标準,然後去重并選取最優,最後根據營運政策進行政策比對等。
  • 用戶端逾時:用戶端是前端,需要處理最終展示和不同終端使用者的不同需求。用戶端采用多線程異步讀取,這樣不會影響主線程的速度,同時并發請求,提升響應速度和使用者體驗。這裡指的主線程請求時間,可以了解為在前台終端裝置需要等待的時間,比如APP要求8秒鐘傳回,那就設定8秒時間;如果PC端B2B白屏網頁查詢,客戶可以等待時間為25秒,那麼就是設定25秒。用戶端的逾時時間要大于或等于所有的營運端逾時時間,例如用戶端逾時是25秒,那麼營運端線程A的逾時可以最大為25秒,但如果線程A的絕大部分航線擷取時間是18秒,那麼線程B和C的逾時最好不要超過18秒,這裡的使用者體驗要綜合考慮機率問題。

六、政策比對與算法優化

機票垂直搜尋引擎的性能優化

弄來這麼多産品,不可能都提供給客人,需要根據營運規則來比對。機票政策就是機票産品的營運控制政策,如上圖所示,包括政策類型、客戶類型、航程類型、乘客類型、航司、航班、艙位、城市、日期、返點 、定額、Office号等多種屬性。為什麼有這麼多屬性呢?因為機票産品的營運規則很複雜,而這種規則的複雜性,直接導緻在航班查詢的時候,機票政策的比對也很複雜的。對于這種大資料、複雜業務規則的資料處理,需要有一套專門的政策比對算法,具體如下:

第一步是直接從資料庫查政策,在前端查詢的時候,根據查詢的條件,如出發到達城市、日期等,從資料庫中大範圍的擷取政策資料,并把這些資料放到記憶體中。第二步在記憶體中對每個産品進行政策比對即過濾,先将每一個屬性轉化為業務規則如限制城市、排除供應商、航司指定供應商等,一個屬性一個類、采用統一的接口,然後增加到政策過濾器中。産品與政策的比對過程,就像水流過過濾網一樣,把最優政策應用到産品上如調整價格。這個過程有些複雜,為此我們編寫了一套自己的政策過濾器PolicyFilter架構。第三步是按照政策返點高低進行排序。第四步是将最優政策傳回給前台。以下是部分核心代碼的示範:

機票垂直搜尋引擎的性能優化
機票垂直搜尋引擎的性能優化

七、小結

機票垂直搜尋性能優化不僅僅适合于機票行業,也适合于其它垂直行業,在垂直搜尋引擎方面有一定的通用性,隻要它存在:遠端資料擷取、靜态資料、緩存更新、規則比對、多資料源等問題,都是類似解決方案。垂直搜尋主要有四把刷子。第一把刷子是靜态資料與任務打底。第二把刷子是緩存與更新,保持資料的新鮮度,不僅要快,還要準。第三把刷子是實時查詢與三段逾時,多供應商多資料源,供應商要20秒,客戶隻能接受3秒,怎麼辦?解決辦法是三段逾時。第四刷子是政策比對,好不容易弄來這麼多産品,不可能都直接顯示給客人,需要根據營運規則進行比對。以上,每一個具體的技術可能并不複雜,但把它們綜合起來,解決具體的實際問題,為公司為行業帶來價值,并不是件容易的事。技術的核心價值在于技術的應用,技術價值要借助技術應用和産品才能發揮出來,這比單純的技術學習要有意思得多,希望以上能應用到你具體的工作中。

posted on 2019-02-13 15:00 NET未來之路 閱讀( ...) 評論( ...) 編輯 收藏

轉載于:https://www.cnblogs.com/lonelyxmas/p/10369891.html