原創|阿裡巴巴淘系技術
引言
2020年雙11,第一次改變節奏,從光棍節變成雙節棍,從一個峰變成了兩個峰,在新的挑戰下,如何做好技術保障,做好技術支撐,所有技術人都進入了一個新的學習過程。新的形勢下,顯著特點是時間跨度長、活動周期長以及使用者互動玩法更多。
從單使用者CC分享到群内分享,以及直播間互動消息等,作為電商的消息IM承接着整個互動的場地,使用者在整個“互動消息”場景下,可以進行實時分享、聊天、客服溝通、商家優惠、商家優惠活動和紅包以及商品秒殺等。
“消息”作為使用者和使用者之間架起“連接配接”的重要橋梁,消息連接配接了使用者和使用者、使用者和商家、使用者和平台等。如何做到高并發強互動下消息有序地呈現在使用者面前,是消息團隊亘古不變的主題,尤其是在使用者的互動行為不确定性情況下,在面對不确定性的流量和規模時,系統應該怎樣做到“絲般順滑”的體驗呢?本文将帶着讀者一起來進行深入探讨。

(推薦閱讀:讀者對傳統的IM系統架構有所了解)
互動場景挑戰
直播間:淘寶直播帶來新的流量變化,百萬線上已經成為常态化,大量的直播間7X24小時直播帶貨,使用者在直播頻道頁頻繁地進出不同的直播間,有時候被某個直播間吸引,停在那裡等着優惠、紅包和寶貝,随着主播在直播間喊一嗓子,推送一張寶貝卡片,幾十萬人蜂擁而至秒殺。這樣的場景每天都在上演...
互動PK群:主互動玩法“超級星秀貓瓜分20億紅包”開啟的時候,意味着大量互動拉贊、分享到好友、分享到群成為流量的入口,無論淘密碼/圖檔等,大量的消息卡片被轉發、二次轉發帶來的分享裂變效應,每天09:00和晚上22:00成為活躍的峰值,每個組隊的使用者拉群互贊,這樣的場景從10月20日到11月11日持續每天固定時段上演...
不确定性流量:分享面闆入口一次清單排布改變,營銷活動的一次優惠推送,直播頻道頁一次營運活動都可能導緻直播間/群的流量瞬間波動,紛湧而至的使用者帶來了大量的互動行為,各種點選/分享/消息發送紛至沓來,如何應對這樣的流量和規模,作為平台系統,必須能夠做到應對不确定性流量能力和機制,必須從流量入口到流量出口端到端考慮整體的全鍊路架構,是否存在單點瓶頸和缺口,尤其在大促前期,系統架構梳理、強弱依賴梳理、上下遊鍊路串聯、破壞性壓測、脈沖流量壓測和全鍊路壓測保障和優化,以及配合相關的流量控制、預案保護、業務流量隔離機制、資源調控等手段,才得以做到“不确定性流量”向“确定性流量”轉變,才可以更大程度上保障系統高可用和極緻使用者體驗。
問題定義之群聊
随着2018年淘系電商首推“雙11合夥人計劃”,更簡單直接的雙11玩法,給大衆帶來更多期待和驚喜。尤其是蓋樓互贊活動更是把“群聊”推上風口浪尖, 在手淘APP内部分享比在微信和釘釘等社交/企業軟體分享更加便捷和高效, 使用者不停地在群内互動分享拉贊,通過好友助力提升蓋樓積分。基于傳統的IM架構技術,尤其在群内聊天或者分享,每條消息按照群内人數進行寫擴散,按照主互動500人群規模來計算,平均群大小320+,1:N的寫入必然導緻寫入DB的RT以及存儲壓力,按照DB庫承接120w/s寫入速度,導緻消息上行3K/s的極限,而實際參與互動分享的使用者在峰值的時候遠大于這部分互動分享和聊天消息流量,其次叢集的寫入不可能完全給IM聊天消息,還有其它的營銷活動、交易、物流等通知類型的消息。基于“寫擴散”架構,在高并發互動場景下遇到了瓶頸,導緻消息大量的延遲下推,影響最終使用者體驗。
基于寫擴散的擴散比1:N,能否做到1:1寫入?答案是肯定,針對群内的消息可以分為“非個性化消息”和“個性化消息”,所謂“非個性化消息”就是大家看到都是一樣的,應該隻需要寫一條資料,群内成員可以共享取這條資料,所謂“個性化消息”,指定某個成員發送的單邊消息,譬如進群歡迎語等。在群内,99.99%都是“非個性化消息”,也就是可以從1:N壓縮到1:1寫入,基于這個理論假設,需要考慮“讀擴散”讓每個使用者的消息從對應的“群會話消息隊列同步“資料,而不是從”使用者隊列同步“資料,其中同步隊列圍繞隊列offset偏移量進行,通過隊列的自增syncId保證有序,每個用戶端維護相應的隊列的同步位點,采取“用戶端存儲位點的去中心化“方案,實作”下行消息的推拉“結合,通過隊列位點syncId進行比對,如果服務端消息隊列syncId-用戶端隊列syncId=1,表示雲端消息無空洞,否則攜帶用戶端的隊列和對應的syncId到雲端重新同步區間資料,實作最終一緻性。
業界IM:騰訊QQ、騰訊微信、網易雲通訊、抖音IM、釘釘IM、脈脈IM、支付寶IM
備注:市面上APP80%都具備IM聊天能力,均采取寫擴散簡單模式進行雲端消息同步
讀寫擴散技術方案對比
1,寫擴散技術
優點:
1,整體架構簡潔,方案簡單,維護使用者同步隊列實作資料同步機制
2,無論是單聊還是群聊等會話消息,寫入使用者次元同步隊列,集中擷取同步資料
3,推和拉情況下,存儲模型和資料處理簡單,且天然支援個性化資料
缺點:
1,群會話消息,天然存在1:N寫入擴散比,存儲壓力N倍壓力,線上使用者收到消息延遲增大
2,多個群内消息隊列混合在同步隊列,無優先級處理能力,無法針對互動群等做隔離
2,讀擴散技術
1,降低寫擴散N倍的DB存儲壓力,減少下行線上使用者端到端擴散的RT時間
2,提升消息上行叢集整體的吞吐量,使用者體驗更流暢
3,端到端實作會話級别的同步優先級隊列,實作差異化服務
1,整體架構偏複雜,需要維護每個動态會話消息同步隊列,端側需要實時感覺新增的動态同步隊列
2,用戶端冷啟動需要分散讀取多個會話消息同步隊列資料,對于存儲會帶來讀QPS壓力
3,讀寫擴散混合模式
核心在于架構的演進推進“讀寫擴散混合模式“落地,結合兩者的優點進行雲端一體化資料同步技術,覆寫幾千萬互動群使用者,保證整體峰值上行消息以及使用者在群内端到端延遲體驗,做到一條上行消息500ms以内到達群内其他使用者端側,讓整體使用者體驗提升明顯,群内強互動成為可能。
問題定義之直播互動消息
電商直播呈現大直播若幹個(大于30W同時線上)、中直播間幾百個、小直播幾萬個這樣分布,尤其是晚會和主播帶來的熱點直播間效應,對系統整體的架構存在熱點帶來嚴重挑戰。熱點問題的産生需要從不确定性的流量來源說起。
直播間人員規模天然和群聊不一樣(單個群<=500人),一個直播間可以突破40萬-200萬之間裝置同時線上,直播間在另一個層面是“特殊的群”,群維護了群和群成員強關系,直播間維護直播和裝置之間的訂閱弱關系,在擴散次元群按照500人進行分庫分表切片模式分發下行消息,直播間需要以直播間幾十萬裝置作為分段切片進行分發。 同時直播間的指令消息如果不加以幹預,會形成超大的流量熱點和擴散問題,那麼針對這個問題如何應對?
1,直播間互動全鍊路和核心處理節點
簡易時序圖如下:觀衆互動消息->網關接入->應用系統Buffer(秒級直播間次元消息)-> 編碼、合并、批量消息流->直播間次元裝置擴散->裝置長連通道推送->裝置接收->解碼消息->業務處理
2,充分利用直播間線上人數
針對大直播間和小直播間區分對待,充分利用線上人數這個關鍵性名額,譬如小直播間不做buffer隊列處理,所謂buffer,就是維護topic次元的緩沖隊列,支援N秒或消息條數的異步flush機制,實作削峰過程,其中針對“可靠消息”進行持久化緩存存儲,如果目前消息推送失敗,重試3次或者下一條消息再次攜帶失敗的可靠消息,整體按照推拉結合的方式,端側做重複消息去重控制。
3,使用者進出房間關系維護
從使用者第一次進直播間,發起訂閱請求,最終通過大小直播間分片進行路由到指定的直播間,針對特殊大直播間提前做好叢集分片,或者通過每天的離線資料分析大直播間的賬号,主播開播建立直播間的時候,提前做好分片确定性,在脈沖綁定關系的時候,流量分散到N台訂閱叢集進行綁定關系建立。
4,流控政策考慮
流控不等于一刀切,而是針對不同的subType指令進行控制,針對可靠消息(紅包、優惠、寶貝卡片)等進行持久化存儲,利用多次消息下推攜帶機制,同時兼顧端側拉取機制,保證消息最終一緻性且在3秒以内到達端側。
5,一緻性hash問題-熱點直播間
一緻性Hash的架構必然存在熱點問題,如果在直播間進行分散架構,必然存在指令風暴問題,基于此需要進行Hash熱點二次打散處理,針對這樣的熱點問題技術上是可行的,熱點問題散列到多台IP機器上進行流量承接,另外需要考慮直播間次元的統計資料分布式合并等問題,需要用到分布式鎖并發寫入統計資料,且直播次元資料合并計算,類似JDKStriped64原理。
對比兩套架構思考
1,規模差異化架構思考
因為早期兩套系統各自演進應對不同的流量和産品需求,使用者規模化和産品要求帶來的差異化架構,對比“群聊”和“直播間互動”兩類互動場景,群聊基于消息、會話、會話視圖以及附加消息存儲和消息漫遊能力進行整體設計,而對于直播間來說,圍繞直播間大規模實時互動進行抽象設計,充分實作buffer/批量/訂閱關系切片等機制。對于關系來說,群關系是強關系,需要使用者确認加群,才可以進群、退群、檢視群好友等;對于直播間來說是弱關系,使用者進直播、退出直播都是自動完成關系建立和取消,當然使用者可以後續進入回放直播間。是以,在功能上和模型設計上需要進一步思考,尤其現有回放直播間需要一套錄制/回放指令機制,儲存互動指令等關鍵性指令資料,而這點在消息IM場景完全支援了,包括使用者可以漫遊曆史消息等。技術的發展不會一塵不變,針對合适的場景進行差異化架構和設計才是最重要的,同樣在應對不确定性流量這個場景下,解決問題的方式是不完全相同的,這個過程需要反複疊代和優化,圍繞端到端使用者體驗這個核心目标進行技術演進才是最重要的價值選擇和方向判斷。
2,不确定性流量的QoS思考
不确定性的流量如何轉為确定性流量,是技術必須要解決的“确定性”問題。 尤其面對流量需要确定性進行分解,分優先級保障不同的消息QoS能力是“高可用架構永恒不變”的主題,就像應用系統的限流,需要分場景進行流控一樣。基于這樣的思考推演,QoS分級機制來承諾消息服務SLA,最終才可以做到隔離/優先級/差異化處理,完成整體的消息順滑體驗。
小結
面對不确定性的流量,需要進行流量再細分以及面向不同的場景采取不同的處理方案去應對,慣用的手段是指令合并處理、鍊路隔離和共享、租戶存儲隔離、流量打标機制區分場景來源等,以及有相對确定性的流量大腦進行觀測,在峰值流量來臨之前,需要具備流量感覺和預警機制,做好流量的優先級劃分,應急預案是快速失敗限流還是慢速等待消費以及優先級控制等機制;同時在系統層面,需要做到水準擴充能力,也就是能否通過彈性擴容的方式應對高流量的峰值,另外需要做到整體全鍊路合理的架構設計,避免“寫入放大”以及“讀取放大”的單點問題産生,需要針對入口流量和出口流量進行比對,是否可以做到上下遊1:1的情況下,盡可能地避免單點瓶頸帶來叢集瓶頸乃至整體不可用。
“高可用架構“是技術人員永恒不變的主題之一,随着使用者規模增長以及集中流量爆發的情形下,更需要敏銳地找到全鍊路單點問題,提前預判定義出面臨的問題,然後給出合理的優化方案,最終灰階切流以及全鍊路壓測驗證保證整體方案有序推進,尤其面對的線上系統優化,好比開着飛機換輪胎一樣。具備優化效果資料和監控是衡量每一步的預期收益,隻有這樣才可以做好“架構演進”,才可以持續傳遞更好的使用者産品體驗,赢得使用者的喜愛,以及互動效果和産品流暢性才可以得到使用者滿意度提升。架構演進是個動态化的過程,需要持續投入和改進,推動全鍊路整體落地。