TOP100summit:【分享實錄-途牛】價格中心繫統的優化之路

本篇文章內容來自2016年TOP100summit途牛旅遊網高級架構師,技術委員會開發組長趙國光的案例分享。
編輯:Cynthia算法

導讀:價格中心繫統是途牛網衆多系統中很重要的一個,幾乎全部的售賣價格計算都由此係統產生。初期因爲缺少合理設計,沒法及時知足業務高速增加的需求,出現價格計算速度慢、系統不穩定、增長功能困難等問題,系統面臨巨大壓力,在這種狀況下咱們啓動了系統優化。通過優化系統的穩定性獲得巨大提高,特殊場景下的性能提高爲原來的幾十倍,平均性能提高爲原來的幾倍。本文將就途牛價格中心繫統的優化實踐做深刻分享。數據庫

1、旅遊產品的特色性能優化

旅遊產品是各類資源的整合,包括機票、酒店、門票、簽證等全部旅行過程當中使用到的各類服務。以三亞五日遊產品爲例,第一天飛到三亞併入住酒店,而後各類玩,第五天飛走,其中涉及到不少種服務。架構

在計算過程當中須要處理這些場景:併發

● 產品的每一個團期都須要排列選出最低價格的資源組成;
● 同一資源在不一樣的團期下價格可能不一樣(淡旺季,不一樣供應商報價不一樣,資源庫存影響);
● 須要考慮同行程下的酒店連住天數,選出連住多天總價最便宜的酒店資源;
● 某些資源只有計算時經過多個條件篩選才知道其價格(如飛機散客票);
● 某些產品配置不少資源,如上千酒店。負載均衡

所以,獲得一個產品的價格須要不少的數據和計算。另外,資源的價格會頻繁變化,好比機票的價格;或者因一批低價格的庫存賣光了那麼這個資源就沒法再以低價售賣,價格就要漲。這些狀況就會使價格發生變化。這種變化的頻率很高,加上資源的數量較多,天天達到幾百萬次,且每一個資源會被多個產品使用,因此每一個資源變化都會引發多個產品的價格計算。這些因素形成價格中心面臨兩大難點:計算複雜、計算量大。運維

2、重構實踐異步

在整個系統優化重構的過程當中咱們遇到了不少問題,正是這些問題獲得了很好的解決,才使得系統優化成功。分佈式

2.1 系統最關注什麼?微服務

系統最關注的是響應時間?吞吐量?併發數?功能正確?仍是穩定性?這些都是咱們關注的,但當魚和熊掌不可兼得的時候,咱們更關注什麼?這個問題關係到咱們的技術選型以及更深刻地理解系統。

舉個例子,假設是一個對響應時間要求很高的系統,一個請求要求當即獲得響應,那麼就不太適合過多的異步處理方式。價格中心繫統更專一吞吐量,即資源的價格變化必須可以反映到產品的價格上。在響應時間方面不是強制要求必須毫秒級或秒級,事實上只要幾秒內能夠變過來就能夠,由於客人在價格變化的一瞬間預約產品的機率是很低的。某些場景下響應時間能夠更長,好比夜裏刷價格,因此咱們徹底能夠採用異步處理的方式。

2.2 系統的瓶頸在哪裏?

系統的性能優化每每落到CPU/IO/內存這三個裏面。那咱們的系統瓶頸在哪裏?這個問題決定着系統優化該往哪走。拿價格中心繫統舉例,假如CPU很低、IO時間很長、內存使用量很大,就能得出一個結論:速度上不去,時間都消耗在IO上了,CPU得不到有效利用。進而得出對策:提高併發線程數,把CPU打上去。可是這樣作會帶來內存的消耗增長,因此不合適。

通過分析就會有疑問:這麼多IO讀取出來的數據佔用了內存,而CPU較低,是否是有冗餘的數據讀取?帶着這個疑問再次檢查發現確實存在,這只是一個附帶的發現,通過分析咱們基本肯定的方向是降IO,經過控制計算規模下降內存使用量。

2.3 抽象領域模型

抽象領域模型爲了解決什麼問題?

● 原系統中的功能邏輯混亂,耦合嚴重;
● 你們對一個功能如何實現缺少統一的認識;
● 產品和開發之間的溝通缺少統一的語言。

領域模型凝聚了領域知識的元素,是系統運行不可或缺的成員,但領域模型不具有系統總體運行所具備的知識,只負責模型內部的邏輯。

系統至少要有領域層和應用層,領域模型在領域層完成各自的邏輯實現,應用層再將這些領域模型關聯起來。咱們通過抽象將系統提煉出大的領域模型爲資源、產品、促銷、交通、基礎等。

2.4 微服務的劃分

劃分微服務是爲了解決如下問題:
● 功能耦合;
● 數據耦合,即沒有劃分和保護的數據被多個功能模塊依賴,致使一處數據的改動將波及大面積的功能模塊;
● 升級的影響範圍,因某個功能須要擴充實例將致使全部實例都從新部署,某一個小功能引發的上線也將是整個應用的上線。

具體作法是:經過抽象,基於以前創建的領域模型劃分出符合系統特色的微服務,每一個服務應對系統的一類複雜度。不一樣的微服務之間在邏輯功能、被調用頻率、依賴的數據、實例個數等方面都是不同的。咱們的系統通過提煉劃分爲資源管理服務、產品價格管理服務、計算控制服務、促銷計算服務、價格查詢服務。

微服務之間的配合推薦採用異步消息隊列的方式,這樣服務只關心本身的處理邏輯,而不用關心本身產生的數據被誰以哪一種方式處理,服務之間是互相不感知的。

固然這是這個系統的特色決定的,由於能夠稍微犧牲一點響應時間。經過RESTFUL接口的方式調用也是不錯的選擇,這時服務提供方必定是提供通用的服務,即不會在自身邏輯裏出現「當調用者是XX的時候如何處理」這種判斷。

2.5 控制每次計算的粒度

咱們的系統還面臨一個特殊的問題:一個旅遊產品由多種資源構成,好比酒店/門票/機票等,正如前文所說,一個產品的價格計算可能有多種資源和選擇。

好比一個三亞5日遊的產品,能夠從北京/南京/上海/西安等多個城市出發,這些城市的航班都不同,會有許多航班線路可供選擇,數量與能夠去三亞的城市數量成正比。而這種城市數量會有多少,程序事先沒法知道,徹底由業務人員的產品設計決定。

這種狀況帶來的問題就是:計算一個產品的價格時,不容易預先知道計算量大小,有時城市不多那麼計算量就小,而有時出發去目的地的城市不少那麼計算量就很大。

這至少會帶來兩個麻煩:
● 一是系統的能力不容易評估,由於每次技術的粒度都不得而知,沒有統一的衡量標準;
● 二是內存會有很大的浪費。

通過分析,咱們認爲從北京出發到三亞的產品價格和從上海去三亞的產品價格不要求在同一個時間產生,因此能夠分開計算。這樣就能夠縮小每次計算的粒度,使每次計算的粒度控制在一個相對原子的大小上。這就大大下降了內存的使用,同時也加速了計算速度。

2.6 無縫升級

每次升級都要考慮如何作到對外無感知、同時可回滾的設計,將風險控制在最低。通常若是涉及到數據庫結構變化,能夠選擇雙寫,新結構數據庫穩定以後再將老庫做廢。

但咱們遇到一個問題:但願改變輸入規則,將配置方式由藍色方式改成綠色方式,由於綠色的方式更靈活,更符合業務需求,但問題是線上已經有大量的藍色方式數據配置,把這些數據全刪掉再按照綠色方式配置上去是不可能的。

那麼怎麼作到平滑切換?除非找到一個算法將藍色配置映射成爲綠色,遺憾的是沒有這種方法。

咱們的作法是將藍色數據配置和綠色數據配置都向一個固定的模型去映射,把它們所有視爲規則,那麼藍色和綠色就是四種規則。這樣就作到了新老數據共存和平滑升級。

3、技術實現

3.1 擴展立方體

隨着業務對計算資源、存儲資源的需求不斷增長,另外一方面摩爾定律失效,人們沒法找到擁有巨大資源又價格合適的計算機來支撐本身的業務,因此轉而經過大量廉價的小型計算機一塊兒工做來達到超級計算機的目的。當計算需求增長,只要增長小型機的數量,就能夠近似線性地增長系統性能。擴展性,是分佈式系統的重要考量因素。

在圖所示的擴展立方體中:
● X軸表明每一個結點同質(同類型、同功能),只要增長結點數就能夠增長系統處理能力;
● Y軸表明基於不一樣業務的擴展;
● Z軸表明不一樣用戶類型(優先級、地域等)的擴展。

目前咱們的系統主要是基於X軸和Y軸的擴展。

咱們的存儲水平擴展方式是分表分庫,但分庫容易帶來跨庫Join的問題。咱們是基於產品ID做爲分表關鍵字的,基本上沒有產品之間須要關聯計算價格的場景,因此基本規避了跨庫Join的問題。

3.2 RESTFUL調用組件

在服務治理上咱們開發了一個RESTFUL的調用組件,經過它來解決服務發現/調用管理的問題。服務提供者將自身標識註冊到註冊中心,服務消費者經過註冊中心得到可提供服務的列表。

3.3 消息隊列

咱們在較多場景下使用了消息隊列。消息隊列的一個好處是解耦,在發送端看只須要將消息送到隊列,send and forget,不須要關注消息會被誰以哪一種方式處理。

另外,負載均衡能夠在消費側完成,發送方無感知。這樣就能夠動態地增長或減小消費者數量。固然這樣作也基本上要求業務的設計是無狀態、異步化的。

4、案例總結

4.1 架構是爲業務服務的。

評價架構的優劣要看是否更好地支撐業務發展,而不是使用了什麼技術。只有最適合本業務特色的架構和技術選型纔是好的。因此只有深入理解業務自己纔有好的架構。

諸多開源中間件的出現,減小了業務人員須要本身實現的功能(除非開源的項目不知足要求),而架構師也從設計實現更多地轉向對業務需求的判斷,從而進行架構決策和技術選型與模式的運用。

本案例是百億次計算量的系統優化,其實第一個應該討論的話題就是這100億次是不是必要的。事實上咱們確實經過優化下降了計算量,也下降了單次計算規模,這些都是創建在對業務的理解之上的。因此架構永遠是從業務出發。

4.2 服務之間的邊界要清晰,儘可能耦合小。

DDD的思想能夠幫助咱們找到服務邊界。

4.3 儘可能異步化設計,這樣的耦合很小,邏輯上更清晰。

異步的系統要穩定得多,某一個系統出現瓶頸的時候還有消息中間件幫助緩衝。同步的調用在等待時(線程會阻塞)會間接影響併發和吞吐量。另外,異步的系統在升級時會更容易,系統之間的限制要小一些,能夠在隊列裏面積壓一些。

4.4 無狀態省去了不少負載均衡的煩惱, 不須要作黏性。

能夠很容易地作到水平擴展.有狀態系統在水平擴展時是很是痛苦的。

4.5 小步迭代,可回滾低風險。

咱們作到了每一次上線都是可回滾的,數據庫的設計在上線後的一段時間內都是向下兼容的。並且新老數據是能夠並存的。

11月9-12日,北京國家會議中心,第六屆TOP100全球軟件案例研究峯會,劉曉濤:途牛研發總監將分享《天下武功惟快不破-微服務實踐快速響應瞬息萬變的市場》。

TOP100全球軟件案例研究峯會已舉辦六屆,甄選全球軟件研發優秀案例,每一年參會者達2000人次。包含產品、團隊、架構、運維、大數據、人工智能等多個技術專場,現場學習谷歌、微軟、騰訊、阿里、百度等一線互聯網企業的最新研發實踐。大會開幕式單天體驗票申請入口:www.top100summit.com/?qd=juejin

相關文章
相關標籤/搜索