開發與維運

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

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

作為大型基礎服務,播控系統有幾十個上游業務方,並且其中大部分都是直接參與視頻播 放生產鏈路的重要應用。這些業務方比如 CMS、媒資、播放服務、搜酷和 OTT 等對播控服務 的 RT 和成功率的抖動很敏感,播控的任何抖動直接影響視頻播放鏈路,進而影響用戶觀看體驗。
隨著播控應用的業務方數目和調用量不斷上漲,系統流量不斷增大但是機器資源有限,如何在資源有限的條件下解決系統穩定性?
除了持續進行系統優化, 我們以去中心的思路來解決問題:提供一個封裝播控核心服務的 近端調用 SDK,大流量業務方使用 SDK 完成內容播控的需要,以此降低對播控中心服務的依 賴,減少風險;對於播控中心繫統,SDK 抵擋了大流量的衝擊,提升系統穩定性的同時節省了 機器資源。

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

播控系統作為控制內容播放的服務,業務方的請求到達播控後,處理流程可以分為兩步:
第一步是先獲取視頻關聯的播控策略, 會進行分佈式緩存、本地緩存以及數據庫的查詢;
第二步是根據查詢出的數據進行靜態計算並返回結果。

由於查詢分佈式緩存和本地緩存具有極高的緩存中率,所以可以將查詢緩存和靜態計算的 過程遷移到播控 SDK 中,完成大部分請求的響應,剩下沒有命中緩存的部分,再進行 RPC 調 用獲取結果。播控中心繫統和 SDK 的關係圖如下:

image.png

播控中心繫統和 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 採用如下的結構進行數據獲取和數據更新:

image.png

針對不同環境下獲取分佈式緩存的數據,我們採用兩種方式解決:
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 性能優化集中在業務和技術層面,如下圖所示:

image.png

1)日誌優化。在高併發系統中,日誌會成為系統的瓶頸;除了定製高性能的日誌參數外,還要從打印日誌的源頭進行優化;比如進行日誌壓縮,只保留關鍵日誌信息,減少日誌中的字 符數量等;
2)減少序列化和反序列化。序列化和反序列化是高CPU 消耗的操作,使用本地對象緩存 代替字符串緩存以及提升內存緩存命中率來減少 RPC 調用等手段,來減少序列化和反序列化;
3)對象拷貝優化。基於 CGLIB 的字節碼生成實現對象拷貝來代替反射,接近原生對象屬 性賦值方法;
4)業務代碼邏輯優化。減少重複調用,減少對象創建以及提升接口批量處理能力等。 經過上述優化,播控 SDK 的 CPU 消耗和 Load 壓力相比優化前降低了 60%以上;

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

1)監控預警
在各個業務方機器上運行的 SDK 如果沒有有效的預警體系,當問題發生時,就不能第一時 間發現。為了建立監控體系,我們做了以下工作:
a)SDK 中做好業務日誌埋點和日誌採樣;
b)使用全鏈路工具標記 SDK 中的關鍵方法;
c)SDK 定時收集緩存命中率、單機 QPS 以及接口成功率和 RT 等信息,並上報; 整個監控預警體系的建立如下圖所示:

image.png

基於上述的監控信息,將分散在各個業務方機器上的日誌統一收集到日誌中心,並建立重 要指標的預警基線,確保能夠第一時間發現問題。
2)穩定性方案
有了問題發現機制,必須要有問題解決機制;SDK 中為了應對不同程度的穩定性問題,提 供了不同程度的降級方案,如下圖所示:

image.png

a)流量動態切換方案。當業務方機器能夠承受的 SDK 流量上限超過閾值時,多餘的流量 會動態分散到播控中心繫統;這在實際中是很有效的,在一些單機 1000 QPS 甚至更高的場景下,確保 SDK 不會壓垮業務方機器。極端情況下,所有流量都可以回切到播控中心繫統。
b)數據庫不可用降級方案。當數據庫出現故障時,及時與數據庫切割開來,使用緩存的數據繼續對外服務,防止出現更大面積的故障。
c)黑名單降級方案。當分佈式緩存出現故障時,使用黑名單降級方案,SDK 此時只控制 涉黃涉暴涉政等敏感視頻不透出;接口 RT 和成功率仍然能確保正常。
播控 SDK 建立的監控預警和穩定性保障體系,經歷雙 11 和多次實戰考驗,能夠在分鐘內 發現問題並解決問題。

三、總結

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

Leave a Reply

Your email address will not be published. Required fields are marked *