溢米教育推薦平臺的效率與穩定性建設 | SOFAStack 使用者說
本文來自 SOFAArk 使用者—溢米教育投稿,分享其內部使用 SOFAArk 元件後極大提高內部推薦系統的開發效率和穩定性的案例。感謝溢米教育對 SOFAStack 的支援,同時也歡迎更多使用者投稿 Join us。
SOFAArk 是一款基於 Java 實現的輕量級類隔離容器,主要提供類隔離和應用(模組)合併部署能力,由螞蟻金服開源貢獻。
寫在前面
個性化推薦,相信大家都不陌生,簡單來說就是根據每個人的偏好經過模型計算推薦出適合的東西,這些東西可以是視訊、商品、文章、電影等。經過網際網路這幾年的發展,個性化推薦已經無處不在,不管是電商、教育、遊戲、金融行業,推薦系統對業務的提升都有著非常重要的幫助。溢米教育作為一家網際網路教育平臺,近幾年推薦業務發展非常迅速,技術團隊也在持續的進行能力提升。業務快速增長的同時,亟需一個高效率、高穩定的推薦系統來支援推薦場景。
本文是根據我們內部推薦平臺效率與穩定性建設的實際經驗整理,介紹了溢米教育推薦系統的改造優化。在整個過程中我們基於公司架構做了分析,確認了技術選型和改造方案,最終選擇基於 SOFAStack 社群開源的 SOFAArk 元件開發框架,極大的提升了我們推薦系統的開發效率和穩定性。希望能給有同樣困擾的技術團隊參考。
背景
一次完整的個性化推薦,通常包括召回、過濾、排序等步驟。雖然步驟不多,但是涉及到的邏輯是非常多的,包括 abtest、使用者畫像、物品畫像、離線資料、線上資料、模型系統、欄位補全等等。個性化推薦極為依賴場景定製化,不同的場景對應不同的處理邏輯。
我們可以想象,把這一堆處理邏輯都放在一個系統裡面,應用會變得十分臃腫和複雜,隨著業務系統不斷的迭代更新,逐漸會變得難以維護,開發效率和系統穩定性都會面臨不小的挑戰。不幸的是,隨著溢米業務快速發展,內部的推薦平臺已經變得 “過勞肥”。不管是迭代效率、效能、穩定性都遇到了瓶頸,比如:
-
釋出耗時: 演算法團隊一個人跟進一條業務線,導致業務迭代頻繁、應用釋出非常頻繁,由於系統本身複雜性,這麼一個龐然大物釋出一次非常慢,降低了工程師效率;
-
系統臃腫: 所有模組統一維護,包含了儲存、演算法、業務等,幾乎每次迭代都是隻增不減,降低了系統可維護性;
-
覆蓋風險: 多個團隊共同維護一份程式碼,分支上容易存在衝突,合併程式碼存在覆蓋風險,降低了團隊合作效率;
-
版本不一致: 不同業務團隊使用的 jar 包版本不一致,每次升級一個 jar 包都會引起很多問題,導致各個團隊在開發期間都要花費不少精力解決依賴衝突。
基於上述背景,溢米推薦平臺不得不進行應用瘦身和系統改造,從而提升平臺的開發效率和穩定性。然而在實際的改造過程中,我們不難發現這兩者其實是互相沖突的。為了提高穩定性,我們肯定要做到流程上的把控,比如測試、灰度、釋出等流程的規範,這勢必會影響業務迭代效率;反過來如果要提升效率,那麼在流程上肯定會有一定的捨棄,隨之而來的是穩定性的潛在風險。 但是人總是需要夢想驅動的,每個工程師都希望能用一種架構或者方案,同時解決很多通用的問題,節約成本,提升效率, 讓設計人員能夠不至於疲於奔命, 解放生產力來完成更多有創新有挑戰的工作。
調研
效率和穩定性並非一定是二選一,在進行推薦平臺升級改造之前,我們梳理了溢米內部影響業務效率和系統穩定性的主要因素。
開發效率 | 系統穩定 | |
---|---|---|
影響因素 | 業務複雜度+開發複雜度 | 業務變更:程式碼變更+資料變更 |
業務迭代流程+開發流程 | 非業務變更:配置變更+程式碼變更 | |
業務變更+服務變更上線 | 流量變化 | |
穩定性流程 | 硬體故障 |
關於開發效率,從上面可以看出來除了開發部分是依賴平臺所能提供的便利和開發者個人技術能力之外,其餘大部分都是流程上的把控。這些流程上的把控一是為了保障業務迭代的正確性,二是為了提升業務迭代帶來的線上服務穩定性,但是簡單的流程不足以把控住這些點,而過度複雜的流程會很大程度上影響業務迭代效率,所以我們需要思考並且尋求一種平衡,比如如何降低業務開發複雜度?如何提升平臺提供的便利?如何在不影響穩定性的情況下簡化業務迭代和維護流程?
關於穩定性,我列舉幾個在溢米內部遇到的幾個類似案例:
- 推薦服務效能優化上線,功能性測試沒有問題,但是沒有經過壓測導致高峰期服務能力下降,最終導致整個服務不可用,而上游由於沒有做好服務治理也受影響變成了服務不可用;
- 推薦服務所依賴的某個資料來源或者 RPC 響應從 10ms 突然增長到 100ms,從而導致推薦服務主要執行緒池耗盡,最終導致服務不可用;
- 上游壓測或者流量推廣或者爬蟲導致流量激增,但是推薦服務沒有做好限流導致服務被打垮而不可用;
- 推薦系統依賴業務系統提供的RPC服務進行過濾,由於此RPC服務變更導致響應變慢,而推薦服務沒有區分強弱依賴導致整體服務超時;
- 某個業務由於排期時間緊張,測試周期太短,上線後導致其它業務異常。
結合這些案例和上文總結的系統穩定性影響因素,可以發現除了硬體故障是不可控之外,其餘幾點基本都是因為變更而引起的。那麼如何不受變更影響而提升穩定性呢?上面我們介紹過最主要也是最有效的是變更流程控制,通過測試、灰度、釋出流程規範,其餘也可以通過技術手段來控制,比如效能優化、服務治理、業務隔離、強弱依賴區分、多機房容災、擴容等等。
針對以上開發效率和穩定性分析,最開始確定如下了改造目標:
- 場景模組化
- 系統瘦身,拆分模組,提高系統可維護性
- 模組複用,提升開發效率
- 模組開發時隔離
- 各模組單獨迭代開發,解決之前統一迭代開發的程式碼衝突問題
- 各模組單獨測試,提升測試效率
- 模組執行時隔離
- 模組執行時類隔離,解決模組間包衝突問題
- 模組間有明確的服務邊界,一定程度的故障隔離
- 模組動態可插拔
- 動態升級,秒級釋出回滾
改造
為了滿足改造目標,我們初步確認了三個選擇:
1)採用自定義 SPI 的 ServiceLoader 動態載入實現;
2)採用自定義 Classloader 實現;
3)尋求開源軟體支援。
基於資源成本、時間成本的考慮,我們選擇了尋求開源支援,螞蟻金服開源其分散式架構吸引了我們的關注,經過技術判斷,我們最終決定使用 SOFAStack 社群開源的 SOFAArk 元件開發框架。
SOFAArk 定義了一套相對簡單的類載入模型、特殊的打包格式、統一的程式設計介面、事件機制、易擴充套件的外掛機制等,從而提供了一套較為規範化的外掛化、元件化的開發方案。更多內容可以參考官方文件:
SOFA JVM 服務: https://www.sofastack.tech/sofa-boot/docs/sofa-ark-ark-jvm
SOFAArk 官方文件: https://www.sofastack.tech/sofa-boot/docs/sofa-ark-readme
SOFAArk 原始碼: https://gitee.com/sofastack/sofa-ark
通過 SOFAArk+SOFABoot 的組合,我們將應用進行拆分,分為宿主應用+資料模組+業務模組:
- 主應用: 負責整個容器的狀態保持;
- 資料模組: 負責資料通訊,包括 Redis,DB,RPC 等基礎服務;
- 業務模組: 只需要負責呼叫資料模組進行業務實現,最終資料通過主應用進行與外部互動。
我們建立了一套模組化開發、測試、釋出流程,能夠在業務中臺上面進行模組開發,並且制定一套模組拆分、開發標準:
- 越底層的模組,應該越穩定,越具有高度複用性;
- 不要讓穩定模組依賴不穩定模組,減少依賴;
- 提升模組的複用度、自完備性;
- 業務模組之間儘量不要耦合。
資料模組改造前,由於每個業務團隊使用的方式不一致,演算法團隊使用的儲存又非常複雜,資料量又非常的龐大,經常會遇到擴容、縮容、資料遷移等各式各樣的問題,這對演算法開發、運維都帶來了極大的困擾,但是經過模組化改造之後,我們可以對所有的資料層出口都進行收攏,所有的底層儲存都由資料模組控制,不管是升級、擴縮容、遷移,只需要對資料模組進行升級釋出,業務模組完全不需要做任何事情,這對演算法開發人員來說肯定是節約了很大的成本、解放了大部分的資源,而且統一在資料模組進行穩定性維護也相對簡單。
未來規劃
模組化、平臺化、自動化的好處顯而易見,大家都很清楚,場景標準化和可快速擴充套件性大大提升了業務迭代效率,新業務的接入成本也大大降低,在新場景上面可以低成本創新,從而滿足高速發展的業務體系,但是有沒有想過平臺化帶來的問題呢,我這邊列舉幾個點:
- 平臺問題的放大
- 平臺化之後大部分細節只有平臺開發人員瞭解,一方面會導致人為因素問題擴大,其次也會對使用者習慣帶來挑戰
- DevOps的落地問題
所以綜上可見改造不是一蹴而就的,未來我們會持續迭代,如運維平臺化建設進行整個系統平臺化落地,打造一套完整的推薦中臺服務。
總結和致謝
目前大部分的推薦場景已經完成了模組化的拆分,已經穩定的在生產線上運行了幾個月,在此感謝螞蟻金服 SOFAStack 的開源貢獻,同時也非常感謝 SOFAArk 開源維護者:善逝,在使用過程中,SOFAStack 團隊提供了高效和專業的支援。
SOFAArk 原始碼: https://gitee.com/s