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

1、行業背景與垂直搜索

咱們先了解一下機票的行業背景,下圖是由中航信統計的數據,藍色的曲線表明平均每千米的票價,紅色曲線指的是客運量。從2011年到2016年,不管是國內、港澳臺仍是國際,總體趨勢都是機票價格便宜了,坐飛機的人也愈來愈多了。特別是國際機票,這五年裏機票價格降低30%,客運量增加了140%。前端

乘客愈來愈多,購買機票的渠道有哪些呢?如今主要有三個:網絡平臺、代售點和航司官網。像攜程、去哪兒、飛豬、同程等,是主流的網絡購票平臺;像旅行社這類代售點,是旅行團的主要購票渠道;同時大部分航空公司的官網也能夠購票,並且有相對較低的價格。整體來講,網絡平臺是最大的銷售渠道,佔比76%。爲何網絡平臺佔有這麼大的份額呢,主要緣由是機票垂直搜索引擎是主要的用戶流量入口,用戶通常是先比價而後再去預訂,一個好的機票搜索引擎查詢的產品豐富、價格便宜,並且響應速度快,運價也準,這些特性在技術方面實現好並不容易。算法

2、主要問題與解決方案

機票查詢要快、準、低。快是指查詢快,可以提供一個良好的用戶體驗;準是指運價準,能夠保證出票的成功率;低是指票價低,可以吸引更多的用戶。可是,若是票價要有優點,就要有大量產品,產品數據多了查詢就慢,若是查詢要快,就必需要緩存,可是數據緩存了,運價就可能不許。這三者是矛盾的,相似於CAP原則,具體示意圖以下:數據庫

對於以上問題,怎麼解決呢?通用的三個技術方案有:1、用DB+Redis平衡響應速度、數據實時性和查詢成本;2、用削峯填谷的MQ來處理高併發;3、將業務服務化、模塊解耦。這些只是通用的技術點,並無什麼難度,咱們這裏重點介紹與最終結果密切相關的四個模塊:靜態數據、緩存策略、實時查詢、政策匹配。後端

  1. 靜態數據:能靜態處理的數據儘可能靜態化,存儲到本地,能夠是數據庫或緩存,以方便快速地查詢,如航班信息、運價數據和政策數據等;
  1. 緩存策略:從中航信拿到運價數據以後,進行熱冷門數據分類,數據永不過時但持續更新,自主控制數據的更新頻率;
  1. 實時查詢:多渠道多供應實時獲取遠端數據,多數據源查詢速度會變慢,遠端服務不可控,解決方案是三段超時,即前端用戶超時、中端運營超時、後端供應超時;
  1. 政策匹配:大量的產品數據和大量的業務規則,不可能都提供給用戶,須要經過必定的算法進行匹配過濾、排序等。
3、靜態數據與任務打底

機票查詢的靜態數據主要有:城市、機型、航司、運價數據等,這裏重點介紹較爲複雜的運價數據,運價數據的獲取雖然間隔時間較長,但數據量大且更新頻次不一樣。運價數據是由中航信統一提供的,有兩種途徑:黑屏查詢和IBE接口,將獲取到的數據保存到數據庫和緩存中,用戶查詢的時候直接從緩存中獲取,同時也會按照必定的緩存策略來更新。緩存

最初咱們設計了兩套方案來打底運價數據,兩個方案各有優劣。方案1是先預加載全部的運價數據,而後所有保存到數據庫和緩存,而後在航班查詢時經過緩存策略進行相應地更新;方案2是把運價數據根據航線查詢頻率分爲熱門和冷門數據,而後天天凌晨對熱門數據預加載,並在航班查詢的時候對冷門數據進行更新。能夠看出,方案1能保證數據的完整性和實時性,但預加載用時太長;方案2能控制預加載用時,但熱門數據的實時性會從早到晚逐漸下降。兩個方案中都須要實時更新,在考慮數據實時性的同時,還要考慮獲取數據的費用,平衡好二者纔是一個實用的方案。性能優化

綜合對比以後,咱們採用了方案1,具體實現以下圖所示:首先是經過Job對運價數據的初始化,而後以任務消息的方式發送給MQ,MQ裏的消息會被後臺服務自動消費,執行消息隊列裏的任務,把運價數據保存到數據庫和緩存。數據預加載以後,用戶在前臺查詢時,若是緩存裏面沒有數據,或者查到的緩存數據是過時的,系統會自動發一條任務消息給MQ,或者人工配置指定的航線定時更新,Job也會自動發送任務消息給MQ,前臺和後臺的消息被服務消費以實現數據的更新。用戶的不斷請求和後臺指定的任務,保證數據的持續更新,時間越久數據的準確性越高,用戶查詢的命中率也會愈來愈高。網絡

4、緩存策略與數據一致

上面說到運價數據同時存儲在數據庫和緩存,爲何有了緩存還要數據庫呢?存儲到數據庫是爲了方便數據的多維查詢和管理,包括對緩存的進一步干預。數據庫查詢的功能強大,但速度慢,緩存的性能好,但從緩存裏獲取的數據,會有不許確的問題。怎麼才能作到查詢快並且數據準呢?咱們的解決方法是緩存永不失效、數據分類、自主控制更新頻率,以實現運價數據的又快又準。多線程

咱們根據航線查詢的頻率,將能夠分紅熱門數據、冷門數據和沒有數據,航班多、查詢多的是熱門數據,航班少、查詢少的是冷門數據,查詢不到就是沒有數據。在預加載或更新運價數據時,將緩存設置爲一個較長時間或永不過時,而後在前臺訪問時,不一樣數據類型採用不一樣的更新策略,具體以下:併發

  • 熱門航線查詢,在緩存中獲取數據,數據中有一個本身的緩存時間字段,而後根據這個時間來分別處理:
  • 1小時以內更新的:新鮮度較高,能夠直接用;
  • 1-6小時以內更新的:預警n次,第n+1次命中時則異步更新運價;
  • 6小時以外更新的:新鮮度過低,異步更新運價;
  • 冷門航線查詢,與熱門航線同樣,只是不預加載且緩存時間稍長:
  • 12個小時以內更新的:新鮮度較高,能夠直接用;
  • 12-48個小時以內更新的:預警n次,第n+1次命中時則異步更新運價;
  • 48個小時以外更新的:新鮮度過低,異步更新運價;
  • 緩存沒有數據時,直接獲取最新運價,同時更新數據庫和緩存。

以上不管是預警後更新仍是直接更新,都是先把緩存中數據返回給用戶,同時異步更新數據庫和緩存。雖然有存在數據查詢不許確的機率,但被用戶再次查詢時就準確了。查詢到的數據即使不許確,在後繼的航班預訂時也會二次的驗艙驗價,運價數據和庫存數據會再次更新。用戶不斷地查詢,數據不斷地更新,查詢命中率就會愈來愈高,而且用的人越多狀況會越好,會逐步趨近於n個9。框架

5、實時查詢與三段超時

能靜態化的數據咱們要儘可能靜態化,但遠端數據的實時查詢仍是必不可少。實時查詢如何作到又快又好呢,特別是多數據源、多供應商的實時查詢場景。咱們的國際機票查詢就是這樣,前臺頁面點擊查詢時實時調用供應商接口,早期咱們僅調用一個供應接口,產品比較單一,數據不夠豐富,後面咱們引入了多供應商,產品變豐富了,也有了低價,但同時帶來了不少新問題,好比供應端接口須要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秒,這裏的用戶體驗要綜合考慮機率問題。
6、政策匹配與算法優化

弄來這麼多產品,不可能都提供給客人,須要根據運營規則來匹配。機票政策就是機票產品的運營控制策略,如上圖所示,包括政策類型、客戶類型、航程類型、乘客類型、航司、航班、艙位、城市、日期、返點 、定額、Office號等多種屬性。爲何有這麼多屬性呢?由於機票產品的運營規則很複雜,而這種規則的複雜性,直接致使在航班查詢的時候,機票政策的匹配也很複雜的。對於這種大數據、複雜業務規則的數據處理,須要有一套專門的政策匹配算法,具體以下:

第一步是直接從數據庫查政策,在前端查詢的時候,根據查詢的條件,如出發到達城市、日期等,從數據庫中大範圍的獲取政策數據,並把這些數據放到內存中。第二步在內存中對每一個產品進行政策匹配即過濾,先將每個屬性轉化爲業務規則如限制城市、排除供應商、航司指定供應商等,一個屬性一個類、採用統一的接口,而後增長到政策過濾器中。產品與政策的匹配過程,就像水流過過濾網同樣,把最優政策應用到產品上如調整價格。這個過程有些複雜,爲此咱們編寫了一套本身的政策過濾器PolicyFilter框架。第三步是按照政策返點高低進行排序。第四步是將最優政策返回給前臺。如下是部分核心代碼的演示:

  

7、小結

機票垂直搜索性能優化不只僅適合於機票行業,也適合於其它垂直行業,在垂直搜索引擎方面有必定的通用性,只要它存在:遠端數據獲取、靜態數據、緩存更新、規則匹配、多數據源等問題,都是相似解決方案。垂直搜索主要有四把刷子。第一把刷子是靜態數據與任務打底。第二把刷子是緩存與更新,保持數據的新鮮度,不只要快,還要準。第三把刷子是實時查詢與三段超時,多供應商多數據源,供應商要20秒,客戶只能接受3秒,怎麼辦?解決辦法是三段超時。第四刷子是政策匹配,好不容易弄來這麼多產品,不可能都直接顯示給客人,須要根據運營規則進行匹配。以上,每個具體的技術可能並不複雜,但把它們綜合起來,解決具體的實際問題,爲公司爲行業帶來價值,並非件容易的事。技術的核心價值在於技術的應用,技術價值要藉助技術應用和產品才能發揮出來,這比單純的技術學習要有意思得多,但願以上能應用到你具體的工做中。

相關文章
相關標籤/搜索