百度搜索與推薦引擎的雲原生改造

以下文章來源於百度 Geek 說 ,作者傳玉、Linda

導讀:從去年開始,百度 MEG(移動生態事業羣)架構平臺上的用戶產品逐步進行雲原生改造,如今已基本完成。現階段更多關注動態彈性能力、動態管理機制的建設。我們邀請到來自百度推薦技術架構部的傳玉老師, 跟大家聊聊百度搜索與推薦引擎雲原生改造的階段性策略,以及對未來發展的思考。

**嘉賓簡介 :**傳玉

2012 年起專注於搜索引擎與推薦引擎方向;2016 年開始負責自有的資源調度和容器編排系統的研發工作;2019 年開始負責部分通用基礎組件的研發工作,並開始在 MEG 用戶產品內部全面推進雲原生架構改造。

01 核心關注兩個 “效率”,實現降本增效

“說雲原生的目標是讓整個開發上線應用的過程更簡單,這一點我是同意的。百度的搜索與推薦引擎規模都非常龐大、業務極其複雜,尤其是搜索,有着 20 多年的歷史,無法完全按照一套新的理念來設計邏輯。所以,我們在嘗試雲原生時,必須結合我們自己的基因和現狀。”

雲原生架構的主要價值在於效率的提升,包括資源利用效率和研發效率兩個方面。

**從資源利用效率上,**期望通過容器化和動態資源調度實現在線服務的充分混布,讓集羣整體資源使用更加均衡,更加高效,從而降低整體的機器成本。此外,通過雲平臺實現高效率的資源化交付取代物理整機交付,提升資源的流轉效率,讓內部的資源能夠更快速地流轉到重點業務上,支持業務的快速發展。

**在研發效率上,**一方面通過微服務改造,解耦不同業務團隊的迭代,減少團隊間的互相影響,去提升業務迭代效率。另一方面期望把通用基礎架構能力下沉到雲原生基礎設施上,提升新業務架構能力的基線水平。

例如一些局部故障容錯能力,在一些業務線上類似的架構機制已經很成熟了,但對於新的業務線很難直接複用,往往還需要再踩坑,參照成熟業務線的經驗,逐步建設,如果我們能把這些通用的能力以標準化和規範化的形式沉澱到雲原生基礎設施裏,那創新業務線就能比較簡單地複用,少走彎路,儘可能少欠技術債。

此外,雲原生架構對研發效率上的提升,還體現在降低線上問題的處理以及維護上人力和時間。

通常業界有個說法:一個存儲系統好不好用,關鍵看他的運維水平。

但實際上,不僅是存儲系統,對於很多創新項目來講,如果太多的人去支持維護線上服務的運行解決線上問題,那麼投入研發上的人力就相對減少了,相應的發展速度可能就會受影響

通過一些雲原生的基礎設施,我們可以把各種常規的運維操作標準化和自動化,比如機器故障的自動維修,服務實例故障自動遷移,服務容量的自動化調整。一方面可以減少運維的人力成本,另一方面很多情況下自動化的系統能比人工做的更好。

“在之前,我們也是有自動化機制的。但應用雲原生架構帶來的好處,是讓我們能夠通過一個更規範、更標準、更可持續發展的路徑,去做這些自動化的機制。就是把那個大量的人力從這種線上服務的維護中解放出來。在團隊規模不變的情況下,維護人力減少了,能全力投入研發上的人力自然就多了,整體研發效率也就上來了。”

總體來說,雲原生最大的意義在於提高效率,提高了整體研發的 baseline。

尤其是在做新產品時,能夠省去購買資源的成本,在基礎階段也省去用太多的人力投入來保障產品上線順利。成本越低、能做的創新就越多。這樣就讓每一個新產品都避免輸在起跑線上。

02 規範服務設計標準,爲雲原生改造立好規矩

MEG 架構平臺在 2019 年時已經全面雲化。但是,多數服務的遷移僅僅是部署方式從物理機部署轉變爲 PaaS 平臺容器內部署,並沒有針對雲環境以及雲能力進行架構上的改造和升級來獲得更大的成本和效率上的收益。基於這一問題,期望通過進一步規範 MEG 架構平臺服務設計標準,實現從雲化架構到雲原生架構的轉變。

“實現雲原生化之前,我們已經具備一定的基礎。首先是從整個組織上具備了微服務的思想;其次是從實踐上制定了一系列微服務最佳實踐的標準,建立了《MEG 用戶產品架構雲原生內部規範》;第三,我們已經有一系列公共的基礎設施。”

傳玉參考了業內廣泛認可的雲原生應用的特徵,結合百度內部的先行實踐,爲了保證雲原生架構落地的效率和效果,從以下三個方面來規範服務模塊設計:

**1、微服務化:**每個服務粒度應該在限定的範圍內;

**2、容器化封裝:**一個服務的部署,應該只依賴基礎架構以及本容器內的組件,而不應該依賴其他業務服務;

**3、動態管理:**每個服務應該可以動態調整部署,而不影響自身對外承諾的 SLA。

*** 業務整體評估方式:**

**1、**未接入 PaaS 的服務,以不滿足標準計算;

**2、**以服務爲單位評估是否滿足規範,只有當一個服務同時滿足上述所有標準時,才認爲一個服務是滿足雲原生架構規範的;

**3、**每個業務線以百分制計算雲原生規範指數,計算方式爲(符合規範的服務模塊所佔的 quota 總量 / 總 quota),使用 CPU quota/MEM quota,按比例低的計算;

**4、**各單項分數,僅作爲內部指標參考, 用於分析瓶頸,推動落地。

 03 劃重點,雲原生化的階段性實現路徑

從雲化到雲原生化,是一個非常複雜的過程。在制定了雲原生改造規範後,陸續經歷了 4 個階段,分別是:**微服務改造、容器化改造、動態管理、進階雲原生,**而 MEG 的雲原生化進程並未停止,而是朝着第 5 個階段——聲明式架構繼續探索。

第一階段:微服務改造

起初,百度 MEG 架構平臺實現全面雲化時,將所有的架構服務、資源都託管到內部的雲平臺上,但是當時仍遇到了對資源的利用問題。MEG 架構平臺推行雲原生的第一件事,就是要求所有的服務去做微服務改造,消滅巨型服務。

“這些巨型服務,會導致整體的資源分配容易出現碎片,比如某個服務佔用一臺機器 80% 的資源,那剩下 20% 很有可能分不出去,就會出現獨佔的現象,不能混布。還有一些服務在部署之前,要對整機的環境做一些修改。

因此,雖然當時所有的資源都託管在了雲平臺上,但我們在使用時仍然與直接使用機器差異不大,OP 投入了很多,整體線上資源利用率,包括資源的分配率,相對較低。”

微服務拆分之後,帶來了幾個變化:首先是性能提升。

雖然多了一些 RPC 的開銷,但拆分之後,每一個服務都可以被針對性的優化,所有的擴縮容操作亦可只針對這一服務的邏輯進行。因此從整體成本、延遲等各方面使性能達到大幅提升。

其次是研發效率提升。

按原來的產品和策略的迭代,很多時候一個服務需要幾百人共同進行,上線耗時長。但拆分之後,雖然多出幾十個模塊,但一個模塊只需兩三個人迭代即可,也可以隨時隨地上線。這對研發效率整體提升是很大的。

“比如說我們的 Feed 視頻推薦服務,在拆分前是一個巨型服務,迭代頻繁。單實例 450 CPU,100G 內存,單模塊越 40+ 策略 RD 參與開發,每天上線 feature 10 + 個。所以在運營過程中產生了大量資源碎片、上線時間長、內存迭代困難。

我們做了 3 件事:

**第一,**按推薦業務邏輯,拆分爲聚合和召回兩層;

**第二,**召回層按召回算法區分,拆分爲若干並行的召回服務,召回服務部分可丟;

**第三,**聚合層拆分爲機器學習預估服務和聚合服務兩塊,機器學習服務使用 avx 指令集加速。”

Feed 視頻推薦服務改造的成果是:

l  單個大模塊拆分爲 10 + 個小模塊,最大的模塊內存佔用 < 40G.

l  整體 cpu 佔用減少 23%,內存佔用減少 84%

l  延遲降低 50+ms,穩定性從不足 99.9% 提升到 99.97%

l  迭代效率大幅提升,徹底消除了搭車上線互相 block 的情況.

第二階段:容器化改造

MEG 架構平臺做容器化改造,就是要求所有的服務把它依賴的東西,都放到容器內。實現所有服務的一鍵式的部署,也就是自動化的部署。

可能現在的一些新興的 互聯網企業中並不存在這一的問題,因爲大家很多服務本身就是基於 Docker 的。但百度搜索系統具有二十年曆史,必須花時間去做這件事。這個過程中,一個典型是改造搜索的 BS 模塊,它的年齡幾乎和百度搜索一樣大。

二十年前,百度架構師在設計 BS 時,考慮的是儘可能佔滿整機資源。

“那個時候 SSD 非常昂貴,所以設計 BS 時,就希望能把 SSD 用滿,同時,爲了方便,並沒有全部顯示申請,比如你聲明瞭用 10G,而實際上卻用了 60G。這在當時沒什麼問題,因爲一臺機器只有一個服務,使用資源時無論是顯示還是隱式,都跟別人沒關係。現在的磁盤硬件已經跟二十年前完全不同了,單個服務的計算量往往不足以佔滿徵集整機資源,爲了避免浪費,就需要把其他服務混布上去。這樣一來,問題就出現了,就得改。”

第一件事,每個服務顯式地聲明自身需要佔用的資源,改掉貪婪式搶佔的策略。

把所有的資源放在他自己的容器裏。也就是說,把 BS 從一個機器級的服務,變成了一個容器級的服務,不佔用容器外資源。做到這一點,才能讓容器編排系統的調度能力真正發揮作用。

第二件事是提升服務的部署效率。

有一些比較老的服務,可能部署的時候需要去拉很多額外的數據,甚至部署的時候還需要 op 去人工做一些機器的參數和配置調整。這都會導致部署沒法自動化執行,或者部署的速度太慢。爲了改善效率,需要把服務對於物理環境的依賴都消除,只依賴容器內的環境。此外,我們也需要做 P2P 的下載優化,和一些數據的實時化的改造,去優化服務啓動的速度。

“我們之前曾經用過一個存儲數據類的服務,邏輯上來說是能遷移的,但實際上一個實例的遷移大概耗費 8 小時。這種的可遷移性就沒有太大意義。因爲存儲 數據服務受副本數 / 容量 / 併發數的限制,比如說一個集羣有成百上千個實例,但最多一輪只能遷移幾個, 然後遷移一輪的話,要耗費 8 個小時。那整個集羣遷移的時間就會非常長。想進行內核升級、操作系統升級、故障維修等就會非常麻煩。因此,我們要做 P2P 分發優化,做數據下載和數據分發的優化,把部署速度提上去。”

第三階段:動態管理

動態管理這件事,主要說的 “動態”,比如線上服務是否能隨時遷移、隨時擴縮容。

它分爲兩個層面:

一方面從業務本身來看,動態管理要求所有的服務都具備一定程度的彈性和容錯能力。

因爲線上的實例但凡涉及到擴縮容或遷移,就會出現短時間內的重啓或不可用。這就首先要求線上所有服務都具備一定的故障容忍能力。其次,服務需要具備自動的負載均衡的能力(最簡單的方式就是使用 naming service 來訪問服務),有新的實例加入,需要能自動去打散流量,有實例故障或者退場,也需要能及時屏蔽

另一方面從基礎設施層面來看,既然所有的服務都能隨時做遷移和擴縮容。

那我們就可以在服務的容量和流量上按需操作 實現自動化的按需分配。

“一旦某個業務要做一個運營活動,就需要臨時做大量的擴容操作。這個過程在非雲原生的模式下原來很麻煩,要先去找一批物理機,然後把服務部署到這批新機器上實現擴容,做完了活動以後再把服務下掉,之後再退出物理機,整個過程涉及到大量的人工操作,成本是比較高的。但在動態改造後,找物理機的操作就沒有了。我們所有的服務在一個大的資源池裏面。任意業務短時間內需要額外的資源,直接在裏面擴縮容就好了。因爲不同業務的需求時段也不同,還能錯峯使用。

“再有就是資源使用的彈性上,比如說對於我自己的推薦系統來說,如果資源池裏有額外的資源可用,這能讓我的推薦系統 通過更多的複雜計算 來提供更好的用戶體驗。所以在沒有運營活動時,我們用這部分閒置資源來提升推薦和檢索效果。當有運營活動時,我們再把這份資源吐出來給運營活動。這樣方便我們整體對資源進行平衡使用,而且這個過程應該是一個代價非常低的一個自動化的操作。”

第四階段:進階雲原生

爲了繼續降低成本、提升效率,從 2021 年開始,MEG 架構平臺的雲原生改造,在動態管理的基礎上增加了像 Serverless、Function as a Service 等進一步的操作。

在改造之前,整個系統的那個容量是基本固定的,一旦有突發流量就只能降級。通過 Serverless 機制,實時監控流量,發現異常就能在幾分鐘內自動完成擴容。

而 Function as a Service 的話,是讓研發效率提升到極致的一個方向。它能讓業務同學只關心自己想要實現的邏輯。至於在架構上怎麼拆分微服務、怎麼做流量的調控、怎麼做做容量管理,全部交給底層的系統來執行。

第五階段 聲明式架構

傳玉提到,**其實在進階雲原生階段做的一些事情,都在向着聲明式架構靠攏。**比如 Function as a Service 就是聲明式架構中關鍵的一環,包括 Serverless 機制的實現,最終目標也是希望能把策略和架構徹底解耦。

“現在很多架構在設計的初期都是沒什麼太大的問題的。但隨着業務發展,運行了一段時間後往往都需要重構,因爲隨着業務的變化,系統面臨的業務場景已經不一樣了。但架構的調整是非常複雜的,一般都會傷筋動骨,還會涉及到大量的業務策略邏輯遷移等。我們期望儘可能的把業務和架構拆分開,把業務邏輯和架構設計拆分開。這樣業務描述邏輯時儘可能簡單,我們的系統可以根據這些描述自動拆分 Function,再把這些 Function 發送到系統裏去執行。”

如果能做到架構 & 業務分離,那麼 MEG 架構平臺會變得非常靈活。

包括有哪些節點、執行哪些 Function、用這些 Function 怎麼去做連接、怎麼去做組合,全部交由自動的推導系統去實現。如此一來,我們的系統會變成聲明式的,也就是說你在上面聲明你的業務邏輯,它會自動推導出需要怎樣的架構,自動去執行。

“這樣這當然是一個最終的理想態。我們在實現的路上,還需要做很多很多事情。”

以上,是百度 MEG 架構平臺完成雲原生改造的一些關鍵路徑。

在後續的分享中,傳玉還會圍繞服務治理、自動化、混沌工程等方面,重點聊聊過程中的一些問題和解決辦法。

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