天天看點

播控系統近端調用能力:去中心化 SDK

作者| 阿裡文娛開發工程師 張滿

作為大型基礎服務,播控系統有幾十個上遊業務方,并且其中大部分都是直接參與視訊播 放生産鍊路的重要應用。這些業務方比如 CMS、媒資、播放服務、搜酷和 OTT 等對播控服務 的 RT 和成功率的抖動很敏感,播控的任何抖動直接影響視訊播放鍊路,進而影響使用者觀看體驗。

随着播控應用的業務方數目和調用量不斷上漲,系統流量不斷增大但是機器資源有限,如何在資源有限的條件下解決系統穩定性?

除了持續進行系統優化, 我們以去中心的思路來解決問題:提供一個封裝播控核心服務的 近端調用 SDK,大流量業務方使用 SDK 完成内容播控的需要,以此降低對播控中心服務的依 賴,減少風險;對于播控中心系統,SDK 抵擋了大流量的沖擊,提升系統穩定性的同時節省了 機器資源。

一、播控 SDK 的技術架構與進展

播控系統作為控制内容播放的服務,業務方的請求到達播控後,處理流程可以分為兩步:

第一步是先擷取視訊關聯的播控政策, 會進行分布式緩存、本地緩存以及資料庫的查詢;

第二步是根據查詢出的資料進行靜态計算并傳回結果。

由于查詢分布式緩存和本地緩存具有極高的緩存中率,是以可以将查詢緩存和靜态計算的 過程遷移到播控 SDK 中,完成大部分請求的響應,剩下沒有命中緩存的部分,再進行 RPC 調 用擷取結果。播控中心系統和 SDK 的關系圖如下:

播控系統近端調用能力:去中心化 SDK

播控中心系統和 SDK 共用基礎設施資源,并且具有相同的靜态計算過程。與之前所有業務 方都集中請求播控系統,由播控系統統一收集資訊并進行計算的調用方式相比,播控 SDK 以去 中心化的方式來提供服務,由業務方機器來收集資訊并進行靜态計算,防止由于播控系統的故 障,造成所有業務方請求播控都失敗,減少了系統性風險。同時業務方引入播控 SDK 後,99% 的查詢和計算都在本地完成,減少遠端請求的通信耗時和網絡延遲, 依賴的播控服務的穩定性 大幅度提升。對于播控中心系統來說,SDK 抵擋了業務方流量,減少機器成本的同時,提升了 系統穩定性。

目前,已經有幾個較大的業務方接入了播控 SDK,經過 SDK 處理的流量占播控系統總體 流量四成以上,相當于年度節省上百萬的機器成本。

二、播控 SDK 遇到的技術挑戰和解決方案

播控 SDK 在去中心化過程中,遇到三個核心技術挑戰:

1)接入播控 SDK 的業務方在多個環境多套機房, SDK 如何屏蔽業務方環境差異,與播控 中心系統提供一緻的播放控制服務功能;

2)業務方機器資源有限,如何提升 SDK 的性能和減少計算資源消耗;

3)播控 SDK 嵌入多個業務方環境運作,如何監控 SDK 的運作狀态,并且出現問題時具備 有效的預警和穩定性方案。

接下來從以上三個方面來具體介紹播控 SDK 解決上述問題的方案。

1. 多機房多環境的資料和服務一緻性

播控 SDK 要和播控中心系統提供一緻的服務,需要從兩個方面保障:所用資料一緻性和計 算過程一緻性;

1)資料一緻性的保障。目前集團出于異地容災等方面的考慮,采用多機房多單元方式部署; 接入播控 SDK 的業務方所在環境複雜,與播控系統本身所在環境是隔離的;SDK 所用的大部 分資料來自分布式緩存和本地緩存,業務方的環境差異給 SDK 的擷取緩存資料帶來麻煩;為了 確定不同環境下的資料一緻性,SDK 采用如下的結構進行資料擷取和資料更新:

播控系統近端調用能力:去中心化 SDK

針對不同環境下擷取分布式緩存的資料,我們采用兩種方式解決:

a)同單元内使用跨機房通路的方式。如圖 2 所示,業務方 B 的 SDK 使用跨機房通路的方式擷取分布式緩存 A 的資料,對于可以接受跨機房通路延遲的業務方,很輕量級地解決了環境的差異;同時,SDK 通路的緩存資料和播控中心系統通路的緩存資料是同一份,是以資料是一 緻的;

b)播控系統額外部署業務方所在環境的緩存系統。如圖 2 所示,業務方 C 所在的環境額 外部署了分布式緩存 C,SDK 從分布式緩存 C 中擷取資料,避免了緩存通路的跨機房延遲;雖 然 SDK 通路的緩存和中心系統通路的緩存不是同一個,但是緩存資料的最終來源是同一個資料庫,是以隻要確定不同環境的緩存都是從同一個資料庫的主庫中擷取的資料,緩存資料也是一 緻的。

針對 SDK 的本地緩存,主要存在緩存更新和資料實效性問題,我們采用兩種方案確定本地緩存資料一緻性:

a)對于實效性很高的本地緩存資料,使用消息中間件-廣播消費的方式将記憶體緩存失效的 消息通知到每一台機器,比如消息源 A 将消息廣播到業務方 A 的每台機器上;當業務方所在環 境與播控的消息源所在環境隔離時,采用消息全球路由的方式(比如消息中轉中心 B 和消息中轉 中心 C), 将播控系統消息源的消息投遞到其他環境;

b)對于實效性不高的本地緩存資料,使用定時任務調用 RPC 接口定時重新整理;

2)計算過程一緻性的保障。

a)業務代碼一緻性。由于播控 SDK 和播控中心系統的功能大緻相同,是以如果 SDK 和中 心系統業務邏輯備援度高,會産生大量相似的代碼,後期任何改動需要維護兩份,會給未來埋 下很多隐患。經過評估後,我們決定将整個播控核心接口主流程進行重構,抽象出一公共的模 闆二方包; 針對 SDK 和主系統不一樣的地方,留出抽象方法,分别實作,達到最大複用功能模 塊的目的。

b)接口響應一緻性。為了確定對任意一個請求,SDK 和中心系統的傳回值一模一樣,我們使用線上流量回放工具作為最後的品質驗收标準。每次涉及到任何改動,我們都會使用回放工具錄制線上的請求導入 SDK 中進行回放, 對比傳回結果, 及時發現差異和異常。

通過資料一緻性和計算過程一緻性的保障手段,播控 SDK 和中心系統的資料差異延遲控制 在毫秒内,能夠提供一緻的服務功能,滿足不同業務方的不同業務訴求。

2. 如何兼顧 SDK 的高性能和低消耗

SDK 運作在業務方的機器上,很多時候業務方機器資源緊張,必須要在有限的資源内提升SDK 性能,降低計算資源消耗。SDK 性能優化集中在業務和技術層面,如下圖所示:

播控系統近端調用能力:去中心化 SDK

1)日志優化。在高并發系統中,日志會成為系統的瓶頸;除了定制高性能的日志參數外,還要從列印日志的源頭進行優化;比如進行日志壓縮,隻保留關鍵日志資訊,減少日志中的字 符數量等;

2)減少序列化和反序列化。序列化和反序列化是高CPU 消耗的操作,使用本地對象緩存 代替字元串緩存以及提升記憶體緩存命中率來減少 RPC 調用等手段,來減少序列化和反序列化;

3)對象拷貝優化。基于 CGLIB 的位元組碼生成實作對象拷貝來代替反射,接近原生對象屬 性指派方法;

4)業務代碼邏輯優化。減少重複調用,減少對象建立以及提升接口批量處理能力等。 經過上述優化,播控 SDK 的 CPU 消耗和 Load 壓力相比優化前降低了 60%以上;

3. 有效的監控預警和穩定性保障方案

1)監控預警

在各個業務方機器上運作的 SDK 如果沒有有效的預警體系,當問題發生時,就不能第一時 間發現。為了建立監控體系,我們做了以下工作:

a)SDK 中做好業務日志埋點和日志采樣;

b)使用全鍊路工具标記 SDK 中的關鍵方法;

c)SDK 定時收集緩存命中率、單機 QPS 以及接口成功率和 RT 等資訊,并上報; 整個監控預警體系的建立如下圖所示:

播控系統近端調用能力:去中心化 SDK

基于上述的監控資訊,将分散在各個業務方機器上的日志統一收集到日志中心,并建立重 要名額的預警基線,確定能夠第一時間發現問題。

2)穩定性方案

有了問題發現機制,必須要有問題解決機制;SDK 中為了應對不同程度的穩定性問題,提 供了不同程度的降級方案,如下圖所示:

播控系統近端調用能力:去中心化 SDK

a)流量動态切換方案。當業務方機器能夠承受的 SDK 流量上限超過門檻值時,多餘的流量 會動态分散到播控中心系統;這在實際中是很有效的,在一些單機 1000 QPS 甚至更高的場景下,確定 SDK 不會壓垮業務方機器。極端情況下,所有流量都可以回切到播控中心系統。

b)資料庫不可用降級方案。當資料庫出現故障時,及時與資料庫切割開來,使用緩存的資料繼續對外服務,防止出現更大面積的故障。

c)黑名單降級方案。當分布式緩存出現故障時,使用黑名單降級方案,SDK 此時隻控制 涉黃涉暴涉政等敏感視訊不透出;接口 RT 和成功率仍然能確定正常。

播控 SDK 建立的監控預警和穩定性保障體系,經曆雙 11 和多次實戰考驗,能夠在分鐘内 發現問題并解決問題。

三、總結

本節介紹了播控系統的近端調用能力,在系統流量不斷上漲、機器資源有限的局面下,以 去中心化的方式來分散中心系統的壓力,解決了系統穩定性問題。其中重點講述了播控 SDK 的 三個核心技術挑戰:“服務一緻性”“資源使用率”和“穩定性保障”,以及解決這些問題的思路。 在這些解決方案中,很多部分觸及到了高并發系統的共性問題,在一些公開場合的技術分享中, 諸如日志性能優化、緩存更新方式和減少序列化、反序列化等這些點都能引起大家的共鳴,也 期待這些經驗能夠幫助到他人。去中心化是目前軟體系統的發展趨勢,播控作為大型基礎應用, 在去中心化的道路上做了一次重要的嘗試,并且取得不錯的進展。未來播控 SDK 會繼續優化和 推廣,作為播控中心系統能力的一種補充,繼續發揮重要價值。