天天看點

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

作者| 阿裡文娛技術專家 恒磊、阿裡文娛進階開發工程師 新錢

一、背景介紹

随着現場娛樂行業的不斷發展,各類演出層出不窮,越來越多的演出開啟選座購票滿足用 戶的自主選座需求。大麥的選座不僅面向中小場館類的劇院演出,還面向大型體育賽事、大型 演唱會等超大型場館(如鳥巢近 10 萬座)。選座類型搶票的特點是“選”,由于“選”的可視化以及超大場館在資料量上對大麥是很大的挑戰。本文通過服務端和前端上的一些解決方案來探讨 如何支撐超大規模場館的高性能選座,通過本文的一些技術方案希望可以對讀者在一些高并發實踐中提供幫助。

二、核心問題

首先看一下普通商品的秒殺,拿某款手機秒殺來說,一般情況下,一場手機隻有幾個型号, 比如中低檔、高性能檔、旗艦等,處理好這幾個商品的庫存即可。對于選座類搶票而言,每一 個場次的所有的每一個座位都可以認為是一個不同的商品,場館大小不一,大的鳥巢有 10w 座 位。也即是說一個選座類搶票就涉及 10 萬級别的商品,如果多個項目同時開搶,整體數量會很 龐大。目前大麥電商側的商品次元是票檔,座位并不是商品粒度,是以無法利用集團的秒殺能 力,選座類搶票涉及電商、選座、票務雲産銷,是對大麥整體能力的考驗。

先來看看整個選座購票的流程:以林俊傑長沙測試項目購票為例。

使用者打開需要的場次項目詳情頁

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

②點選選座購買,打開選座頁面,檢視座位圖及票檔

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

③選擇一個看台區域,選擇喜歡的座位,點選确認選座

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

④進入下單頁面,填寫手機号收貨位址,建立訂單

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

⑤送出訂單完成付款、出票。 其中,2、3、4 環節都與選座相關。 從流程上看,選座的核心關鍵技術在于:

座位圖的快速加載。快速加載其實就是選座頁面的讀能力。選座頁面需要下載下傳座位底圖、 座位基礎資訊(排号等等)來做渲染,同時需要票檔、該場次每個座位的狀态,來決定是可售 還是鎖定還是已經售出。

對于大型場館座位 5 萬-10 萬,渲染一個選座頁面需要的資料量都很大。

②高并發。由于熱門演出票的稀缺性,同時搶票的人數可能達到幾十萬。如何支撐如此高 的并發和吞吐是一大考驗。

③座位狀态更新的及時性 當某個座位售出後,需要及時更新座位狀态。

④搶票體驗:搶票時熱門的看台某個座位可能幾十個人并發去搶,如何盡量提升使用者的體驗,盡量讓更多使用者一次性購買成功,體驗更好。

三、高性能選座實踐

針對高性能選座的核心要求,我們從如下幾個次元去闡述我們在選座類搶票上的實踐。

1. 動靜結合

選座的瓶頸資料量“首當其沖”。從邏輯上講,一個座位完整的展現到使用者面前,需要包含 座位的看台、排号、價格、售賣狀态等資訊,其中 看台、排号等等是不變的,并可提前預知的; 售賣狀态等時根據項目的進行會動态變化的。是以把選座的資料拆分為動态、靜态資料。對于 大型場館如 10 萬場館,使用者打開一個選座頁,座位的靜态資料(座位 id,票價 id,是否固定套 票,坐标 x,y,和舞台角度,哪個看台,幾排幾号等等),這些資料大概 15M 左右。再加上動 态資料如票檔狀态、顔色、看台狀态、座位狀态,10w 場館大概 2M 左右。也就是說如果不做 處理使用者僅僅打開選座頁就需要 17M 以上的資料量。如果選座資料存儲在 oss 上,如果每人下 載 15M,10w 人同時搶票則需要 1500G 帶寬,帶寬成本很高。為了解決靜态檔案通路速度問題, 将靜态資料從 oss 直接接入到 cdn。同時為了保障資料最新,靜态資料采用版本控制。

2. 靜态資料的預加載

上面提到帶寬峰值很高,為了降低峰值且提升體驗,用戶端引入了靜态資料預加載。靜态 資訊結合預加載的處理,為處理大資料量的座位資訊提供了時間上的餘量,使用者在打開選座頁 時優先顯示靜态資訊,可有效降低使用者等待時間,提升使用者的體驗。

通過大資料分析結合使用者的行為習慣,确定預加載的場次類型,提高預加載的命中率。

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

預加載+預解析,完成了繪制基本場館資訊的資料準備,再将資料提前與畫座 View 綁定, 預渲染 View 進而達到選座頁秒開效果。

3. 座位資料編碼

動态、靜态資料量大制約了我們實作高吞吐,同時也浪費了服務帶寬和使用者流量。是以需 要壓縮,壓縮到一定的可接受的範圍。隻有資料量足夠小,才有辦法做到高吞吐。

1)靜态資料編碼 在處理大資料量的座位(例如十萬級)僅有靜态資料的預加載往往是不足的,預加載并沒有從根本上處理座位資料量大的問題,同時對于類似體育比賽這種多日期多場次的場景,由于預加載的使用存在緩存量的控制,往往影響預加載的命中率。 而資料重編碼和資料壓縮的使用,是從源頭解決問題的有效思路。

座位資料的重編,舍棄傳統的 xml 和 json 格式,不僅可以有效壓縮資料大小,還對資料安 全提供了保障,即使被拿到了接口資料,因為缺乏資料編碼的協定,也無法擷取有效的原始信 息。

2)座位靜态資料壓縮整體架構 目前大麥針對自己特有的座位資料特點,結合高效二進制編碼方案進行座位資料的重新編碼,再使用通用的無損壓縮進一步縮小資料體積,進而減少了座位資料的網絡傳輸時間,從根本上解決大資料傳輸導緻的時延問題:

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

基于二進制的資料編碼,既保障了資料安全性,又保證了在資料解析中的高效性,即使數 據壓縮的使用也比 json、xml 的解析具有更少的時延。

同時兼具工具化的批量生産方式,又進一步解決了資料建構問題。

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

通過端上和 server 端的握手協商過程,實作了資料編碼和通用壓縮方式靈活組合,sever 端 可以針對不同的端下發相應的壓縮格式檔案:

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

結合 CRC 的思想,制定了相容 IOS、Android 和 H5 三端的基于座位屬性的縱向 hash 校驗。 相比 md5 等普通的散列計算方式,在處理 6 萬級座位多元度資訊時,在端上實作了十幾毫秒、 H5 側 50 毫秒左右的全量資料檢測,使得在不占用多長時間的情況,可以驗證數萬級座位解析 的準确性。

經過這編碼到檢測的完整鍊路,實作了減少資料的體積的同時,又能達到比傳統 xml 和 json

資料的高效解析、高安全性。

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

其中 quantum 是大麥端上自研的基于動态比特和字典的壓縮算法,結合大麥特有業務場景, 實作了高壓縮比和快速資料解析:

首次揭秘!看大麥如何掌控超大規模高性能選座搶票

3)座位動态資料的編碼處理 a)動态資料的難點選座動态接口主要涉及票檔情況、看台情況、座位狀态。資料量最大的是座位狀态。以一 個 5 萬座位的場館為例,每個座位都要傳回一個狀态供前端渲染。采用座位 id 和狀态鍵值對的 方式,由于座位較多使得整個傳回結果過大,5 萬座位的場館傳回 1M 以上的資料。如果打開 一個選座頁需要吞吐 1M 資料量的化,接口基本不可用了。之前的政策是按照分組政策,5 萬 大概會分 10 個組,這樣每個請求大概 100k 資料量,這樣才能達到接口基本可用,不過端上需 要請求 10 次才能拿到整個場次的狀态,可想而知性能會有多大影響。假如 5 萬座位的場館,10 萬峰值搶票,那麼僅僅這個接口就需要 100 萬的 qps,是以肯定會逢搶必挂。

b)方案

目前接口是通過 mtop 協定,我們思考的前提:目前mtop 不支援 byte[]數組流,隻支援 json等格式的字元串結構。如何把傳回的資料減小,采用一個盡量簡潔的方案,同時調用一次傳回 整個場館座位狀态,是我們努力的方向。

資料量大主要是因為有很多備援的座位 id。有沒有辦法不依賴這些座位 id?既然我們做的 動靜分離,靜态資料裡已經涵蓋了座位 id,我們動态接口裡隻需要對應的傳回狀态即可,即按 照靜态裡面的順序傳回座位狀态。同時我們把傳回結果進行簡單的相鄰狀态合并将進一步降低 傳回結果大小。假設使用者選座座位符合正态分布機率,平均長度 5w 座位平均傳回不到 20k。

當然如果我們 mtop 協定支援二進制流,那麼我們可以用 bit 位進行存儲,可以進一步降低 傳回結果的大小。

4. 高效緩存

1)緩存

面向這麼高的 TPS,tair 是不二首選。采用 tair + 本地緩存,來支撐如此高的資料峰值。 提到 tair,提一下我們這邊的一些政策。 使用者進到選座頁是一個個的看台,我們設計了一級 stand cache,即看台級别的 cache;使用者會進行選座位,我們又加了一級 seat cache,即為座位粒度的 cache。兩級 cache 保障使用者檢視台和使用者下單選座都能命中緩存。standcache 是熱點 key,從選座的場景是允許資料非準實時 的,是以引入了 tair localcache 和 guava localcache 來增加吞吐,以此降低對 tair 的讀壓力。

2)保護下遊系統

目前采用的政策是 對下遊的調用采用加鎖,tair 全局鎖。拿到鎖的才去請求票務雲底層數 據。拿到鎖的程序去更新 tair 緩存。其實從這裡看對 tair 的寫還是 qps 比較小的,但是每次争搶 鎖對 tair 的讀還是不算太小。通過采用本地的鎖 + 随機透傳來減少 tair 鎖耗費的讀qps。為了 對下遊依賴做降級,增加了資料快照,每次對下遊的調用記錄資料快照。當某次調用失敗采用 之前的快照進行補償。

3)保障資料更新及時

由于我們采用了 tair 全局鎖,可以按照秒級控制下遊調用。調用采用異步觸發。最短 1s 内 會觸發我們發起對下遊的調用。如果我們想最大化利用票務雲庫存能力,給使用者的延遲在 1s 以 内,我們有一些政策。拿到鎖的線程 1s 内調用資料更新任務,在資料更新任務裡做一些政策, 1s 内是發起 1 次還是多次對票務雲的調用,調用越多 tair 更新越及時。由于使用者有一定的選座動作,一般情況下 500ms 的延遲使用者基本無任何感覺的。

4)緩存預熱 預熱一下緩存,對使用者體驗和系統性能很有幫助。搶票類項目采用一定的政策做自動化預熱。

5. 安全及容災

1)安全 從上文看大麥座位資料做了編碼和加密,同時存儲路徑做了混淆,保障不到開搶時間座位資料無法被破解,保障了選座資料的安全性。此外選座頁布局防控政策,保障是真正需要點選座位才能完成下單,防止機刷、防止繞過選座直接下單。通過類似政策降低了選座的無效流量, 提高了穩定性。

2)容災

選座主要在以下幾個方面做了容災。靜态資料存儲在oss 上,目前采用跨地區存儲容災;tair 緩存采用主備緩存,出故障時可以做切換;服務端在 pc 和無線做了叢集隔離。

四、總結

本文通過在資料處理、選座性能、緩存等等政策上來闡述了筆者在大麥高性能選座上的一 些實踐。通過這些實踐目前大麥可以輕松的承載數十萬人的頂級流量的搶票項目。