天貓雙 11 互動性能優化

lilmm038 7年前發布 | 9K 次閱讀 性能優化 軟件架構

2016雙11晚會狂歡夜當晚,千萬粉絲坐在家里拿起手機就可以“同步”參與和舞臺明星的“雙向互動”,善于思考的你一定會去想,對于技術人員來說,如何扛住這海量的用戶請求,準確公平地讓每個粉絲貢獻出力量又得到回報,同時,讓一切過程分秒不差的出現在電視和手機里,是一個大大的難題...

今天的分享將會為你揭秘:

  1. 如何扛住4小時不間斷的點贊請求?

  2. 同時,如何秒級實時的統計出PV、UV,和用戶點贊的排行?

  3. 如何實現,讓統計數據,同步出現在電視畫面和手機畫面?

  4. 新職業“互聯網導播”是做什么的?

兩個案例,一個是聽起來很簡單的點贊功能;另外一個是在電視信號延遲的情況下,怎么做到電視和手機“同步切換”的。最后,我們的“互聯網導播”是怎么工作的?如何保障各種互動的平滑進行的。

這幾張圖是晚會當天手機、電視屏幕的一些場景截圖,為了方便大家理解后面的內容,請收好。

圖一是晚會的招牌互動玩法: 紅黑大PK ,這個玩法去年第一屆晚會就有,今年和去年邏輯大體相同:舞臺上的明星分成紅黑兩隊進行游戲PK,游戲開始之前,手機可以在用戶的這個頁面,選擇押寶其中的一隊,等舞臺上分出勝負之后,押中的用戶就可以搖一搖開寶箱,有機會獲得1元商品的購買特權。圖中看到的這場PK,我們在短短幾秒內送出了10w份面膜套裝。

紅黑PK今年和去年不一樣的地方在于,今年我們做了玩法升級,支持了 “雙向互動” 。什么是雙向互動?圖中可以看到每張手機的截圖,右下方都有點贊的按鈕。第一張圖里,在我選擇了黑隊之后,贊也變成了黑色氛圍,點擊它就會給黑隊加油助力。舞臺上,主持人可以實時看到每個隊伍的點贊情況,電視機前的觀眾也可以看到一樣的數字。就如第二張圖的上部,王祖藍右邊就是紅黑兩隊點贊的比例。獲得用戶點贊數量多的隊伍,會獲得一些游戲規則上的傾斜,比如:獲得一些道具,減少一些時間等,增加獲勝的概率。這樣用戶的參與感更強,用戶不止是被動等待紅黑PK的結果,還可以通過努力點贊,影響到最終的勝負。讓自己喜歡的隊伍獲勝,同時也為自己贏得獎品!

紅黑PK的升級版只是今年"雙向互動"玩法的其中一種,其他玩法還有:AB劇:我們提供A劇情和B劇情,直接由用戶決定劇情的發展路線。跨屏搶星衣:點贊滿足條件后,明星會脫下身上的衣服,丟向屏幕,送給參與互動的觀眾。圖為女神林志玲丟出他的Burberry風衣。

圖三是一個下一節轉場時的明星預告和紅包入口。手機頁面,什么時候由互動環節頁面切換到這個畫面、這個畫面什么時候結束掉,這個完全是和電視同步的。當主持人口播開始押寶,或搶紅包時,用戶低頭一看手機,按鈕就在那里,就可以無縫的參與進來。這個是由我們現場的“互聯網導播”實時操控。技術上如何做到這點的,我們后面也會講。

圖四,是在天貓APP中獨有的舔屏版晚會直播。除了內容非常獨特可以舔屏之外,也是讓身邊沒有電視的用戶,能打開手貓觀看直播,同樣無縫的參與互動。

再來看另一個“雙向互動”玩法 “點贊得答謝” ,比如這場SNH48團體的歌舞表演中,觀眾點贊后,我們后臺會實時統計出一個用戶點贊數的排名。點贊多的用戶,他的淘寶頭像和昵稱,就有機會展示在電視屏幕,并獲得偶像的親口答謝。

這種雙向互動的玩法,結合粉絲經濟,產生出了巨大的能量。但技術如何實現并支撐,也是一個大難題。有的同學可能會說,點贊有什么難的,一個AtomicInt就能解決...別急,繼續往后看。

關于點贊,我們的評估是 千億級 。千億什么概念?全世界人口是70多億,要達到這個數字,需要全世界每人點贊14次。怎么承接如此集中而又巨大的點贊量,并實時給出排行榜。

上圖是一個最普通的點贊鏈路設計,首先它是可行的,互動很多小型的類似點贊活動就是用這套方案實現的。用戶手機來點贊,請求通過負載均衡策略到服務端集群的其中一臺服務器,再到可持久化的集群,這個持久化集群可以是db、也可以是緩存,但我們大多是用緩存。圖中可以看到我們的幾個需求,我們要知道 單一節目的點贊PV/UV、用戶在某一節目的點贊PV、某一節目的用戶點贊數排行榜 。純點贊,可能一個AtomicInt、AtomicLong就能搞定,但是現在我們多出來的這個數據需求,就不那么簡單了。

先來看看這個鏈路的問題。首先,我們評估的1000億點贊數,平均到晚會的4個小時,算出來每秒需要承接700w的點贊。平均700w的QPS,目前很少有集群能撐到吧?

第二,單一節目的點贊PV,這個緩存的key,在同一時間,只會有一個存在,所有的QPS都是到這一個key上的。所以這里肯定也有熱點key問題。

然后,針對UV,傳統的做法是找個持久化的地方存一下用戶來玩過的標識。每次點贊的時候,再查一下,查不到,則UV加一。那么這又多了至少一次緩存的讀寫,QPS那么要double了。

最后,排行榜這個東西,利用redis的zscore、zrank,是可以輕易完成的。但是在晚會這個量級,這么大QPS的前提下,必然也是存在瓶頸的。

我們怎么解決的呢?

先是我們簡單粗暴的第一招。客戶端本地離線點贊,比如x秒提交一次,或者數字到100提交一次 ,這個辦法有效的降低了qps。(但其實這個離線的閾值并不能太大,因為用戶可能在操作完就離開了客戶端,最后一次都是丟失的。)這里用x=10舉例,這樣接口qps就直接降到了70w。

看到評估數字從700萬降到了70萬,是不是大家也都松了一口氣?

就這樣,前面的第一個服務端QPS的問題就解決了。相應的, K2-用戶點贊PV ,因為和用戶相關,沒有熱點key問題,所以也是ok的(單用戶點贊QPS理論不會達到集群限制)。

接下來,看看熱點key的問題。

因為是計數的PV服務,服務端集群的各個服務器直接無須依賴持久化的舊值。所以我們可以在服務端做一個離線。比如,服務端Y秒才上報持久話一次,這樣極限情況,緩存的QPS就等于機器數,這樣就解決了熱點問題。而且,通過內存先做PV的統計,這是純內存的邏輯了,不會成為性能瓶頸。

值得一說的是,這兩個地方的離線,都需要做好并發控制。客戶端的離線,要支持節目的瞬時切換不丟數據。服務端的離線,不能讓RT相對高的上報請求,阻塞RT低的內存技術請求。這里關于數據結構有些Tips:客戶端離線用一個map結構,key是節目id,值是計數器。計數時做incr,上報異步做,成功后desc。服務端離線稍復雜一些,我們構造了一個數據結構,叫做MIT(memory increase tool),如圖是一個包含時間戳long和計數器atomicLong的數據結構,然后再封裝了一些每隔x秒自動持久化,以及并發處理。這個并發處理要求在持久化時,不能阻塞atomicLong的計數,也不能出錯。

再來說UV。

其實完全可以基于incr的初始值,判斷有沒有來過,省去一次uid去重的讀寫緩存。是不是?

這樣依賴,UV的QPS絕對會遠遠小于70w,甚至忽略不計。

前面節目PV、UV、用戶PV的問題,都想到辦法解決了,就剩下點贊排行的問題了。

排行這里,我們仿照選舉機制,設計了一種先單機排序的方案。比如:100個城市同時選舉總統,用戶可以去不同城市投票,把每個城市選出的候選人,合并一下,必然能找出票數最多的。

其實可以發現,這和前面的MIT緩存機制很像,沒錯,這里的單機排序,也是可以定時持久化的,比如1秒1次,然后獲取排行榜時,只需要去所有機器上,拿到列表,然后合并就可以了。在實際場景, K2-用戶點贊PV 這個key incr之后返回的數據,其實已經是用戶實時最新的點贊數據了,其實可以直接參與排行。當然,先和排行最后一名相比較,比最后一名多,再參與排行,這是一個小優化。

然后,這個數據結構,也是需要有一些要求:

  • 線程安全

  • 自動排序

  • 自動逐出

  • 定時持久化時不阻塞

  • 高并發寫入也有高性能

這里總結一下:

  • 客戶端最后x秒有損,但服務端y秒緩存可以無損,加個定時鐘補償推動,incr 0就行了。

  • 緩存計數器的一般實現是int,在1000億目標下,單節目有溢出風險,可以嘗試21億進制。

  • 非熱點的用戶PV緩存,也要做好限流。我們認為這個場景不會超,若超則是作弊用戶,但服務端也要自我保護限流。

  • 內存排序的建議實現方式是:基于跳表(skipList)

今年玩法比較復雜,為了便于理解,先說說去年的“同步”這件事。

圖中是紅黑PK的幾個時間點,可以看出舞臺畫面,呈現到電視機,都會有60s的延遲。我們的解決辦法如圖:

  1. 后臺工作人員,在主持人發出指令時,同時操作數據;

  2. 在60s內,這個數據的變化,手機被同步到了;

  3. 手機知道了60s后,電視機畫面會發生什么,于是設置定時器,到點了自動跳出相應內容;

這樣就實現了,手機內容和電視畫面保持一致。這里,較為困難的就是 2. 60s內讓手機知道 ,為了保證這個能盡量100%覆蓋,我們用的方式是輪詢,40s輪詢1次,于是60s內會有2次,經過去年的實際驗證,這種方式是簡單、靠譜、穩定的。

然后我們來看今年的問題,這也是由“雙向同步”玩法而引入的。前面說過,用戶選完紅黑,可以給選中的隊伍點贊,增加支持隊伍的獲勝概率,這里就需要一個“點贊結束統計” 的時間點。

在這個時間點之前,電視里還有一個L屏,可以實時的看到點贊的進度。那么問題來了,這個點贊的數據,怎么來呢?

我們可以分析一下,最下邊,綠色條是用戶可以點贊的時間段。舞臺說點贊結束的時候,就需要拿到一個數字,但用戶實際結束點贊,需要1分鐘之后。怎么讓舞臺現場預知到1分鐘之后的點贊數呢??

答案是沒法知道...科幻世界里才有這技能...

所以我們的統計只能在time6這個點,就截止掉。然后time6魚time6'之間的點贊數據,我們依然會統計,但是就不能作為雙向互動的依據了。

你以為問題解決了? 其實才剛剛開始...

現場在time6獲取到的點贊結果,會在time6’出現在觀眾的電視畫面,但手機怎么獲取到這個值?這時候后臺點贊計數器,其實已經是1分鐘之后的數字了?舉個例子,現場在time6這個點,贊數由100變為101,電視畫面L屏是合成進去的,在time6'的時候,也是剛好100變為101,這個沒有問題;但手機要完全同步,它需要在time6'的時候,顯示的是time6的是點贊數,這個數字從哪里來?計數器里的已經差了1分鐘了。甚至這個問題并不只是一個time6實際點存在,整個點贊期間,都存在這個問題。

怎么解決?我們發明了一種 時光隧道 機制,點贊計數的時候,定時鐘按照一定的時間片,緩存起來一份快照數據。手機端請求時,經過一些時間的計算、hash到時間片,就可以取到60秒之前的數據了。這樣就解決了這個問題。

整個時間延遲的解決過程,我們偶爾需要向前感知60s,一會需要向后回溯60s,分清楚過去、現在、和未來,保持正確性、體驗一致性,這就是我們的玩轉時間。

在時間的處理上,還有一些性能的熱區問題。比如下面標紅部分,押寶通道開啟、寶箱開啟時,押注接口和抽獎接口,都會迎來史上最高峰。一方面我們要保證這些接口性能容量已經優化到了極致,一方面,還要讓其他接口,不要在這里競爭資源。比如前面說道的,40s輪詢一次,但這個峰值前后的40秒不會有事件變化,其實這里就可以跳過至少1次輪詢。還有中間的進度條峰值,就干脆和輪詢結合在一起,只是變為5s查一下,這樣QPS會是之前的8倍,但是因為可以錯峰,這時候并沒有押注或抽獎,所以抗住不是問題。

協議架構。首先是剛剛說的輪詢接口、押注接口、抽獎接口。通過淘系的長鏈接sdk,ssl的spdy協議,訪問到了后臺互動服務。為了性能極致,像剛剛的輪詢接口,就是一次內存讀;押注接口,就是一次緩存寫;還有前面重點說的點贊接口,平均也就是1次緩存寫。這里的緩存是專用的高性能緩存,阿里系的tair中間件。上面的通用緩存,是給抽獎服務使用的,抽獎服務不用硬抗大流量,合理限流就行。

這里需要重點說明的是下行鏈路,“開啟押寶通道”這類事件的變化,是怎么通知到手機的。

可以看綠色箭頭,導播在控制臺點擊“開啟押寶通道”按鈕后,會寫入一次“配置開關中間件”,這個中間件就是昨天下午第一場的講師叔同團隊開發維護的,非常穩定好用。配置開關保存成功之后,會刷入到時間表的內存,這樣輪詢接口就能讀到數據了。

今年,我們還使用了另外一條鏈路,是基于spdy協議實現的反向推送,在現有長鏈接基礎之上,封裝了一個topic主題的概念,反向推送時,只需要向這個主題下的所有在線用戶做推送就可以了。

為什么會有兩種方式?手機是移動設備,網絡穩定性較差。長鏈接推送通道也存在失聯可能性,我們設計了一個消息失聯的回調機制,當一臺手機失聯后,會自動切換到輪詢模式,增強健壯性,讓更多的用戶可以繼續正常參與到晚會的互動中來。

再總結一下。如圖。

繼續下一個話題前,先說一個前面提到的雙向互動“跨屏搶星衣”的流程,原理也是前面說的時間同步機制,不過結合了AR玩法和雙屏酷炫動畫銜接,給用戶一種穿越、跨屏的震撼感覺,成為了晚會的一個爆點。

這里其實要求更多的團隊和系統,做到協調一致的,怎么保證,這是就是我們下面要說的“互聯網導播”。

“互聯網導播”現在并沒有一個公共的解釋。完全是雙11天貓晚會首創的工種。

再介紹“互聯網導播”之前,先說一下,傳統的導播,也就是“電視導播”。

電視導播一般在直播車內,盯著很多屏幕,每一個屏幕是一路攝像信號。然后他操作一個硬件“控制臺”,通過一個個按鈕,講最合適的畫面,輸出到一路最終的信號里,然后通過衛星,到了千家萬戶的電視機里。

而“互聯網導播”有些類似,他也有“控制臺”,不過這個控制臺是高度定制化的Web頁面。他盯的不是屏幕信號,而是現場畫面以及留意主持人口播Q點。然后,他切換的是手機里的互動內容,并且解決了延遲的問題,做到了同步電視而切換。

并且“互聯網導播”會比電視導播更加危險,電視導播切錯了一個畫面,幾秒內切回來不一定有人發現。而“互聯網導播”切錯了一個內容,幾秒內可能就是成百上千萬的資損。所以,互聯網導播的控制臺,我們也稱之為“核按鈕”。

最后,總結一下這兩年做“互聯網導播”的心得。

  1. “控制臺”的依賴,也要簡單到極致。比如,寫入就只寫入一個中間件就行。

  2. 現場可視化。包括兩部分:控制臺操作結果可視化、現場用戶參與情況可視化。

  3. “控制臺”按鈕合理校驗。比如:開啟押注一定要關閉押注之前的校驗。

  4. “控制臺”按鈕固化,單一功能。但靈活是說,遇到萬一,也有其他按鈕,可以迅速糾正。

  5. 不同操作者,做好隔離,防止互相影響。

 

來自:http://mp.weixin.qq.com/s/jy9kGn-l2_PTgoaHkxGS4g

 

 本文由用戶 lilmm038 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!