歷時三個月,微博推薦引擎架構蛻變之路

嘉賓|馬駸

整理|李慧文

可靠性保障是一個複雜的系統工程,特別對於可靠性已經出現問題的線上服務,在業務迭代、成本約束、人力投入等方面的約束下 ,提升其可用性就不再是單純的技術問題了。

微博推薦引擎作爲各類推薦業務在線服務的樞紐環節支持着微博熱門流、小視頻後推薦等業務,在快速的迭代過程中,其可靠性問題逐漸暴露出來。同時隨着業務需求的變化,其在物料規模、已讀過濾等方面的限制逐漸成爲了限制迭代的瓶頸點。頻發的抖動與宕機,快速膨脹到幾十萬行的代碼,極大地消耗了開發同學的精力。在多重的壓力下,推薦引擎已經滑向了失控的邊緣。

在 QCon 全球軟件開發大會(2021)北京站上,微博研發中心基礎架構部架構師馬駸分享了微博推薦引擎在數月的時間裏從不可控回到可控,可用性由不足 2 個 9 提升至 3 個 9 以上,同時提升業務支持能力的經驗。我們整理了他的演講,以期幫你係統性解決可靠性問題。(下文以馬駸老師第一人稱敘述)

我從去年 9 月底開始負責微博推薦引擎的改造,歷時三個月大幅提升了其性能。今天我將分享該項目經驗,包括:微博推薦引擎架構及當時情況的介紹、在線業務穩定性分析、推薦引擎中的改造實踐。

1 微博推薦引擎介紹

微博推薦引擎服務於微博各類推薦業務,如服務熱門流、熱點流、視頻後推薦等,是推薦系統的樞紐,需結合特徵、模型、物料等環節驅動業務運行,其架構如下圖所示:

推薦引擎架構

用戶請求推薦內容時會先到達推薦前端,隨後在總控上開啓推薦流程。第一步,總控會獲取本次刷新相關的信息,如用戶興趣、引流微博特徵、已讀信息等。

第二步,總控將相關信息輸入召回引擎,召回引擎根據這些信息獲得備選微博 ID。召回分兩類:一類爲標籤召回,即根據用戶信息、熱點業務規則進行排序;另一類爲模型召回,即變換數據形式,用向量的方式通過本地或遠程模型服務獲取物料。

第三步,獲取備選 ID 後,排序引擎會先補充相關特徵信息將備選 ID 構造成完整物料,通過 Hash 等方式將之轉化爲可供排序模型使用的特徵向量,送到排序模型打分,完成排序

第四步,總控在插入廣告後通過前端填充內容,完成推薦。

此外,訓練將接收引擎及客戶端用戶行爲日誌,實時更新排序、召回模型;物料將實時更新物料庫,將特徵的更新總結爲物料包流和更新流,供引擎實時更新和加載。

推薦引擎可靠性挑戰

微博推薦引擎快速迭代中暴露的問題主要是 穩定性和業務支持。

穩定性表現爲單臺引擎(如前文排序引擎)工作幾個小時後即會發生一次宕機、內存溢出、超時啓停等問題。如有突發流量更疲於應對。此外,當時物料規模、已讀存儲能力等方面的設計已無法滿足現在業務的需求。

改造系統比打造新系統更難,不僅需要梳理數 10 萬行代碼,同時改造中系統還在迭代不能下線,再加上團隊人力不足,外部的壓力(如公司對成本、機器利用率等的要求)等,該問題已經超越了技術問題。

系統可靠運行的因素

在線系統穩定運行依賴於三個方面:系統本身架構設計和代碼的質量;自動化的工具(如擴縮容、異常治理等);運維、監控人員人力。 這三方面如同一個木桶,有一個長板即可支持較大的流量:如若系統健壯則運行時必然問題較少,或若運維人力足沛也可解決多數問題。

然而事實上,多數公司均難以 100% 保證某一長板,此時需要結合公司具體情況保證基本質量,出現錯誤時多數依靠工具解決,少數依靠運維人員。

對於當時的微博推薦引擎來說,質量爲核心問題,但投入大、見效慢;雖有如異常處置等簡單工具建設,但是組織簡單且互有衝突,甚至無擴縮容工具,開發空間大,只需適配微博內部成熟工具體系,即可乘高決水,事半功倍;同時急需從零到一引入運維團隊。

2 改造實踐

微博推薦引擎改造分爲三個階段 。第一,通過工具建設先穩住系統,保障後期改造的精力;第二,集中人力大量重寫核心環節,提升系統質量;第三,再次優化工具建設,降低維護穩定所需人力。

具體我將分享:物料存儲結構改造、已讀服務改造和擴縮容工具。

初始階段,我們接入了微博成熟的運維工具,組合了原有自動處置工具、優化了上線腳本,實現了基於 QPS 和超時率的簡單自動縮擴容功能。

質量改造 - 物料

排序引擎運行的第一步爲將物料初始化爲帶特徵的物料,一次需處理數萬條數據,原物料攜帶特徵多,一次請求所需信息量大,因此我們選擇了單機存儲所有物料。

存儲原使用基於內存映射的外部存儲引擎。該引擎溝通速度慢,溝通佔用大,存在內存性能問題(微博推薦引擎的核心問題所在),還限制了物料規模。因此我們重寫了該引擎,重寫時考慮了兩個方面:單條物料存儲和整體物料存儲。

物料具有以下特徵:特徵數量數百但平均填充率較低,整體數據較稀疏,大量特徵爲字符串型。 若用類實現則稀疏數據會造成內存浪費,大量字符串會造成內存碎片浪費,長期使用無法保證穩定性。因此 物料的結構設計需滿足三方面要求:內存需連續不可有碎片;稀疏情況下空間的節約;不可影響系統性能。

我們實現瞭如下圖的二級索引結構:

如圖所示,我們將物料分成了四段,白色部分爲頭部,保存基本信息,紅色部分爲一級索引,黃色部分爲二級索引,綠色部分爲實際數據段。

該結構一級索引爲 Bitmap,每一位均可表示是否有一個字段存在物料中, 實現了稀疏的支持。二級索引爲所有存在字段的偏移量位置,對於字符串爲編譯量,對於數字或浮點數存儲數據本身,保證了存儲速度。此外該存儲結構內存連續,滿足了上述三條要求。

整體物料存儲我們採用了 Concurrent HashMap 結構, 更新速度可達每秒鐘數萬,滿足了物料數量的要求。

質量改造 - 已讀

已讀功能爲推薦流程的核心環節,推薦系統需要依賴用戶已讀數據,將用戶未讀內容進行排序。微博推薦系統原已讀是基於 bloom filter 實現的。

如圖爲微博原 30 天已讀方案實例:共四個 filter,每十天存儲一個 filter,每次讀取覆蓋最近 30 天的四個 filter,取回 bloom filter 後通過或運算將其合併成一個 bloom filter 供後續業務使用。

該方案第一 結構不合理,面對所有用戶 bloom filter 大小均不變,因此:高消費的用戶使用微博頻率高,填充率高,則誤判高;低消費用戶閱讀量小,空間利用率低,浪費資源。第二,該方案直接讀取存儲的 Redis,存儲一旦出錯服務也難免受牽連,穩定性差。第三,該方案各業務直接讀取資源本身,判斷邏輯需各服務獨立實現。

因此我們做了如下改造:第一,將以讀獨立成爲一個服務,各個業務調取服務而非緩存;將常用判斷邏輯封裝爲 SDK,便於業務改動。

第二,存儲方式上保持了 bloom filter 形式,但是串的長度和單位的大小均可變。 在寫入時不按照固定時長寫入,而是前一個 filter 填充率達到閾值時纔開啓一個新的 bloom filter,根據前一個 filter 填充速度選擇下一個 filter 的大小。如此可安全節省原來一半以上的空間:高消費用戶 bloom filter 串雖較長,但體積也會較大,可減少誤判;超高消費用戶限制最大串長度,已讀記錄時長雖會縮短,但是能保證其已讀內容相對長久;低消費用戶可用較小的 bloom filter 完成已讀記錄。

第三,在穩定性上,一方面我們 建立了獨立的短期(如幾個小時)已讀存儲,在主要資源不可用時提供降級服務;另一方面,我們 優化了 Redis 的資源訪問方式,Meta 信息及最新一個 bloom fileter 需從主庫讀取, 保證信息時效性,已不更新的其他信息讀取從庫即可,可緩解 Redis 的存儲資源。

外部工具 - 擴縮容

外部工具擴縮容一般應對兩類問題:日常流量波動,如中高峯晚高峯需自動擴容應對流量高峯;熱點事件突發流量,需要基於冗餘度的自動擴縮容和熱點應對機制。

日常流量應對較爲簡單,此處不再贅述。突發流量特徵如下:

圖中紅線代表流量,綠線代表系統承穩能力(可理解爲機器數量),綠線在紅線之上方可保證系統正常運行。綠線高於紅線的部分爲冗餘度。

流量在 t1 時刻到來,此時紅線會快速上升,在 t2 時刻超過綠線,擴容系統會在 t1 後某點發現流量,觸發擴容,最終機器在 t3 時刻到位。

實現該突發流量擴容需做到:第一,在 t1 到 t2 之間快速發現流量的到來,如此時還未做處理,到 t2 後便已超時;第二,建立降級策略以供擴容時暫用,如停止某些次要功能、減少推薦處理條數。第三,減少擴容時間(即 t1 到 t3 的時間),優化程序啓動速度。

具體問題可根據歷史流量數據和公司情況處理:如公司成本壓力小可將冗餘度調高,將綠線整體上移;如服務自身啓動快,可省略降級策略。

微博推薦引擎依賴微博已有的成熟擴容基礎設施,解決了流量快速發現問題;結合前文的物料改造,引擎啓動速度從 20 分鐘提高至了 5 分鐘。

此外,微博推薦引擎在各環節上均加入了計算量條數和請求的動態降級能力,根據當前實際 QPS 與承載能力選擇降級比例。例如當前可處理計算量條數的 80%,如果流量增加則只處理 70%。自動機制之外,如有熱點事件預警可全公司提前動員,每日 push 場景可提前處理。

靈活的工作方法

靈活的工具可提高開發效率。我們在接入微博現有的工具體系時,先做了一個可手動查看效果及接管自動擴容邏輯的界面,提高了掌控系統的速度。利用大數據類的分析工具可通過錄制大量請求、查看其 UID 或者某些特症等分析異常請求原因。

此外,本次改造中大量工作爲梳理舊業務代碼,繁瑣無聊,團隊士氣也至關重要。

微博推薦改造項目共歷時三個月,正確處理請求比例從不到 99% 提升至 99.9% 以上,服務耗時降低 25%,不增加資源支持單機 500 萬 -1000 萬物料,啓動速度提升至原先的 4 倍。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8Ik7RVRgcy3yae48kfnS-g