機票垂直搜尋引擎之效能優化

技術瑣話發表於2019-02-14

機票垂直搜尋引擎之效能優化

行業背景與垂直搜尋

從2011年到2016年,無論國內,還是國際,整體趨勢都是機票價格便宜了,坐飛機的人也越來越多。特別是國際機票,這五年裡機票價格下降了30%,客運量增長了140%。 

乘客越來越多,購買機票的渠道有哪些呢?現在主要有三個:網路平臺、代售點和航司官網。像攜程、去哪兒、飛豬、同程等,都是主流的網路購票平臺;像旅行社這類代售點,是旅行團的主要購票渠道;同時大部分航空公司的官網也可以購票,而且價格相對較低。總體來說,網路平臺是最大的銷售渠道,佔比為76%。

為什麼網路平臺佔有這麼大的份額呢?主要原因是機票垂直搜尋引擎是主要的使用者流量入口,使用者一般是先比價,然後去預訂,一個好的機票搜尋引擎查詢的產品豐富、價格便宜,而且響應速度快,運價也準,這些特性在技術方面實現好並不容易。 

主要問題與解決方案

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

機票垂直搜尋引擎之效能優化

對於以上問題,怎麼解決呢?通用的三個技術方案有:用DB+Redis平衡響應速度、資料實時性和查詢成本;用削峰填谷的MQ來處理高併發;將業務服務化、模組解耦。這些只是通用的技術點,並沒有什麼難度,我們這裡重點介紹與最終結果密切相關的四個模組:靜態資料、快取策略、實時查詢和政策匹配。 

(1)靜態資料:能靜態處理的資料儘量靜態化,儲存到本地,可以是資料庫或快取,以方便快速地查詢,如航班資訊、運價資料和政策資料等。 

(2)快取策略:從中航信拿到運價資料之後,進行熱冷門資料分類,資料永不過期但持續更新,自主控制資料的更新頻率。 

(3)實時查詢:多渠道多供應實時獲取遠端資料,多資料來源查詢速度會變慢,遠端服務不可控。解決方案是三段超時,即前端使用者超時、中端運營超時和後端供應超時。 

(4)政策匹配:大量的產品資料和大量的業務規則不可能都提供給使用者,需要通過一定的演算法進行匹配過濾、排序等。 

靜態技術與任務打底

機票查詢的靜態資料主要有城市、機型、航司、運價資料等,這裡重點介紹較為複雜的運價資料。運價資料的獲取雖然間隔時間較長,但資料量大且更新頻次不同。運價資料是由中航信統一提供的,有兩種途徑:黑屏查詢和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的資料返回給客戶。對於BC的資料,由於在HTTP請求時我們採用非同步並設定了較大的供應端超時,所以它會在A返回之後,繼續非同步請求並將返回的資料儲存到快取中,以供使用者下次或其他使用者使用。當我們獲取了多供應商的產品資料後,這時會有一定重複的資料,需要進行規範化處理,將不同資料格式轉換成統一標準,然後去重並選取最優,最後根據運營策略進行政策匹配等。 

客戶端超時:客戶端是前端,需要處理最終展示和不同終端使用者的不同需求。客戶端採用多執行緒非同步讀取,這樣不會影響主執行緒的速度,同時併發請求,提升響應速度和使用者體驗。這裡的主執行緒請求時間可以理解為前臺終端裝置需要等待的時間,比如APP要求8秒內返回,那就設定為8秒;如果PC端B2B白屏網頁查詢,客戶可以等待時間為25秒,那麼就設定為25秒。客戶端的超時時間要大於或等於所有的運營端超時時間,例如客戶端超時是25秒,那麼運營端執行緒A的超時時間最大可以為25秒,如果執行緒A的絕大部分航線獲取時間是18秒,那麼執行緒B和C的超時時間最好不要超過18秒,這裡的使用者體驗要綜合考慮概率問題。 

政策匹配與演算法優化 

弄來這麼多產品,不可能都提供給客人,需要根據運營規則來進行匹配。機票政策就是機票產品的運營控制策略,如下圖所示,包括政策型別、客戶型別、航程型別、乘客型別、航司、航班、艙位、城市、日期、返點 、定額、Office號等多種屬性。 

機票垂直搜尋引擎之效能優化

為什麼有這麼多屬性呢?因為機票產品的運營規則很複雜,而這種規則的複雜性,直接導致在航班查詢的時候,機票政策的匹配也很複雜。對於這種大資料、複雜業務規則的資料處理,需要有一套專門的政策匹配演算法,具體如下: 

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

機票垂直搜尋引擎之效能優化

機票垂直搜尋引擎之效能優化

小結

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

本文作者介紹:張輝清,曾任中青易遊CTO、同程交通創新技術負責人、古大集團首席架構師、攜程架構師等職務。帶領過30~200人的技術團隊,將其研發能力提高1~2個檔次。現階段主要關注技術創新、技術創業、中小研發團隊的能力提升。

# 本文內容節選自《小團隊構建大網站 - 中小研發團隊架構實踐》一書。

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

相關文章