百度的評論系統是怎麼設計的?

danny_2018 發表於 2022-06-28

  度評論中臺為百度系產品提供便利接入、持續穩定的評論能力,是百度社群氛圍體系內最重要的基礎能力之一,日均流量達到百億規模,在業務不斷髮展過程中,百度評論中臺實現了功能快速迭代、效能穩步提升,本文將從整體介紹百度評論中臺的架構設計,同時結合具體案例講述如何構建高可用、高效能的分散式服務。

  1 背景

  評論作為使用者主動表達提供情緒/態度/觀點的重要方式之一, 其產品形態是以資訊作為載體,建設生產-分發-瀏覽的使用者內容生態,最終促進內容與使用者,使用者與使用者,使用者與作者之間的價值互動氛圍。

  在閱讀過一條資訊後,使用者往往會瀏覽到評論區,或是抒發內心情感,或是尋找一些共鳴,也可能只是滿足吃瓜群眾的好奇心,有吸引力的評論區板塊可以滿足使用者的互動訴求,同時也可以增加使用者的產品粘性,促進業務發展;那麼如何構建一套評論系統,在業務上能夠支撐產品形態的多樣化以及持續的迭代,在效能上能夠提供穩定的能力輸出,下面我們將會詳細介紹百度評論中臺的架構設計思路以及在業務發展過程中的一些挑戰與探索。

   2概念介紹

  評論從生產到讀取歷經多個環節,下圖是評論生命週期中各個環節的簡易模型:

百度的評論系統是怎麼設計的?

  評論資料的生產由使用者觸發,評論系統維護了與資源關聯的主題資料,通過主題資訊來檢索歸屬的評論內容,評論資料本身維護了發表人,層級關係,是否展現狀態,內容,點贊數,回覆數,時間等等,每個資料維度用於特定的展現場景以及資料分析。

  在使用者生產內容過程中,系統識別惡意請求,針對使用者、資源、內容等維度進行層層過濾,完成資料落盤,資料採用分散式資料庫儲存,同時根據查詢維度進行垂直/水平拆庫拆表,以解決業務持續增長帶來的資料讀寫效能瓶頸,資料層面的變更最終落入大資料中心,用來分析業務現狀以及未來的發展發向。

  3 服務設計

  上文鋪墊了評論業務的相關概念,接下來我們側重於介紹整體的服務設計,評論服務最初立足於百度App業務,為Feed等內容體系提供穩定便捷的評論能力,隨著公司在中臺方向上的戰略轉型,評論服務重新定位為評論中臺,面向百度系的各個產品線,角色的轉變,引發了架構設計方面的巨大改變,同時也帶來了新的技術挑戰:

  

百度的評論系統是怎麼設計的?

  從業務接入角度來看,接入業務方多,需求量大,定製化要求高,需要中臺側對外能夠給予業務側友好的快速接入,對於此部分需求,我們作為首箇中臺方完成了服務託管移動開發者中心(百度移動開發管理平臺)的接入,藉助該平臺管理介面許可權、技術文件、流量鑑權、服務計費以及售後諮詢等能力,大大提升了接入效率。

  對於中臺側內部,通過建設統一的接入層閘道器,實現容災觸發、流量染色、流量控制、異常檢測等外掛能力,既可以為業務提供便利的技術支援,在中臺內部產生技術變更時,也可以做到業務無感知;

  從能力輸出角度來看,不同產品線的業務特點對於基礎能力有著不同的訴求,這就需要中臺側對外能夠滿足業務需求,對內在架構設計中充分考慮通用化來保證有限的中臺人力的研發效率。基於此,我們將介面能力不斷抽象,在程式碼層面上保證低耦合、高內聚,針對不同的產品需求設計元件能力,專項解決痛點問題,同時我們也嘗試針對特定的功能場景,提供友好的開發框架,通過與業務側開源共建的方式來提升需求上線的效率,解放一定的中臺人力,也取得了不錯的效果。

  從系統效能角度來看,接入流量隨著新增產品線而日益增長,不斷考驗中臺服務的效能,我們需要承諾核心介面SLA視角99.99%的服務穩定性。從架構上看,去除單點服務,邏輯機房內部形成隔離域,無跨地域請求,考慮極端場景,設計技術方案防止快取穿透,快取擊穿,服務雪崩,保證服務的最小可用單元,從容量上看,保證高峰期容量滿足N+1的冗餘,具備單機房切空的能力,核心指標的報警覆蓋至運維/研發/測試同學等等;

  總體來看,建設思路就是,服務分層治理,不斷沉澱中臺通用化能力,對於產品和技術的升級,不斷完善基礎建設。

  4 挑戰與探索

  上文以整體視角介紹了百度評論中臺的架構設計,下面我們列舉了幾個業務發展迭代過程中遇到的具體問題,來詳細介紹下百度評論中臺是如何進行技術探索並實施落地的。

  如何提升服務效能與迭代效率?

  背景:

  一個系統在歷經無數個版本迭代後,能夠承載的功能越來越豐富,同時也會面臨著開發成本日益增長的問題,業務邏輯夾雜著歷史包袱,程式碼塊混亂冗餘,牽一髮而動全身,這個時候對系統本身的技術升級便勢在必行。

  評論列表類介面是評論服務中的核心業務,歷史上大部分的功能迭代列表類介面都會參與其中,這也促使了列表類介面更快地暴露出問題。

  從下圖優化前的業務邏輯處理流程不難看出,介面定義模糊,承載功能較多,相關的邏輯交織在一起,導致程式碼可讀性不高;在業務處理部分,資料依賴比較多,不同的資料獲取之間還存在著依賴關係,服務呼叫只能順次執行,效率低下,這些問題會影響到日常開發的工作效率,並且在效能上也不可控,為系統穩定埋下了隱患。

  

百度的評論系統是怎麼設計的?

  思路:

  面對這一系列問題,我們對列表類服務進行了一次大刀闊斧的改革,採用三條路徑來解決核心問題:在介面層面,按功能拆分,定義單一職責的介面來解耦邏輯;在資料依賴層面,對下游呼叫進行排程管理,實現自動化,並行化;在資料渲染層面,採用流水線的裝飾器來定義業務主線邏輯與支線邏輯,整體做到優化後的服務介面功能專一,程式碼邊界清晰,依賴服務排程管理,資料打包靈活,可持續擴充,那麼我們是如何實現這一過程的?下面介紹下具體的解決方案。

  方案:

百度的評論系統是怎麼設計的?

  上圖是一個介面下發資料的整體流程,總結起來可分為三個階段:

  第一階段:作為介面的前置條件校驗,對基礎引數進行校驗,過濾請求;

  第二階段:依賴資料的集中獲取,這裡是服務優化的核心部分,這裡以評論一級列表介面為例,一級評論列表介面的資料下發,包括了一級評論,二級外漏評論,評論總數,主態可見評論資料,標籤資料等等,每個資料來源存在著一定的依賴關係。

  比如,一級評論,主態可見評論,評論總數優先順序最高,因為不依賴其他資料來源便可以直接請求,二級外漏評論則需要一級評論資料獲取到的父級評論列表作為基礎依賴才能夠執行,這樣二級外漏評論的優先順序次之,抽象來看,每個業務介面都可以梳理出自己的服務依賴關係,那麼接下來的問題就變成如何將這些依賴關係管理、排程起來,這裡我們採用了圖引擎排程模型來完成這個任務:

  該模型實現過程分為三個步驟:

  第一步:定義,列舉業務邏輯中所需要的所有依賴服務,並對映成節點,每個節點是資料依賴呼叫的原子化節點,該節點中不參與介面維度的業務邏輯;

  第二步:定義他們之間的關聯,生成有向無環圖,每個節點維護其依賴節點的個數,用入度值來表示;有向無環圖的特點是節點與節點之間只有一個方向,不能成環,這種資料結構恰好符合業務節點之間的執行邏輯,把一個個服務依賴呼叫對映成有向無環圖中的節點,每個節點的入度值來表示該節點的依賴節點數,其中頂點就是圖中入度為0的節點,沒有任何節點指向它;

  第三步:由頂點開始,不斷併發執行所有入度值為0的節點,上層節點彈出後,通過依賴關係尋找被依賴的節點,並對該節點的入度值做減操作,通過這種拓撲排序的結果輸出,實現自動化的節點執行;

  總結來說,將各個介面的節點關係進行配置化管理,當流量請求時,讀取該介面的節點配置,生成有向無環圖,節點的任務由排程器統一管理執行,每個節點的依賴資料輸出會儲存到當前請求的排程器中,到下游節點任務執行時,從排程器獲取上游的資料結果作為入參,完成本節點的執行邏輯;

  第三階段:資料渲染階段,通過階段二獲取到所有依賴資料後,從排程器中獲取所有節點中的依賴資料結果,定義流水線式的格式化裝飾器,按功能拆分,對響應值進行層層修飾,以實現資料渲染的模版化處理。

  通過這種方式改造系統後,介面的服務效能大大提升,平均響應耗時在99分位維度上有了明顯的降低,同時受益於Go語言的高效能,節省了物理機資源,重構後的程式碼可維護性也大為提升。

  如何構建高效能、低延時的評論排序能力?

  背景:

  評論是生產使用者內容的服務,那麼對評論內容的運營則決定著整個評論區的氛圍,對於優質/有趣或帶有特殊屬性的評論內容應該得到更多的曝光率,同時我們也希望低俗/辱罵/無意義的評論內容得到更少的關注,這樣使用者之間的互動才能得到正向的迴圈,這就要求評論服務構建一套排序機制,在產品層面上能夠滿足排序的需求,在技術上也可以做到排序資料快速收斂,不影響服務效能的前提下快速迭代。

  思路:

  在制定技術方案之前,我們需要考慮到幾個核心問題,首先是如何對評論內容進行排序?

  最容易想到的方案是為每條評論評估一個分值,按照分值的大小來輸出一篇文章下的評論內容,以達到排序的效果;那麼既然每條評論有了評分屬性,接下來就要定義這個評分的公式,按照這個思路我們可以羅列出很多影響評論分值的因子。

  比如一條評論的點贊數,回覆數,建立時間等等,同時為這些因子設定相應的權重,組合起來可以計算出總分,在這個過程中,我們需要考慮公式的迭代給系統帶來的效能衝擊,當一個公式被確定下來,並不能馬上推送到線上,而是需要小流量來評估排序結果帶來的收益才能決定公式的因子或者因子權重是否是一組正確的組合,這便涉及到可能存在多組公式並存的情況,並且可以預料到公式的調整將會是頻繁的迭代。

  根據這些思路,我們最終開發出評論排序框架,採用離線計算評論分值,公式配置化,扇出併發模型等技術手段實現了智慧化評論排序功能,下面我們詳細看下架構設計。

  方案:

百度的評論系統是怎麼設計的?

  評論排序服務分為兩部分,離線粗排服務與線上精排干預。

  首先介紹下離線粗排服務,我們將評估評論分值/輸出排序列表的任務放在離線模組中執行,在資料量較大的情況下離線運算不會影響到線上服務。離線模組會監聽評論行為佇列,例如評論回覆,評論點贊,評論刪除,評論置頂等能夠影響評論列表資料變更的行為,離線排序服務消費到行為資料後通過策略公式計算出評論分值,最終儲存到排序索引中,這個流程涉及到的技術點如下:

  單排服務;當一條評論資料發生變更時,觸發單條評論分值的重新計算,判斷是否需要觸發全排服務,如果需要則將全排指令寫入全排佇列中,否責將最新的分值評估更新至排序索引中。

  全排服務;從全排佇列中讀取全排指令,獲取到評論所屬的主題ID,遍歷該主題ID下的所有評論,重新評估每條評論的評分,寫入至排序索引中。此處使用了Golang語言的扇出模型,佇列通過channel實現,管理多個協程併發消費channel的全排指令,減少資料訊息的積壓。

  排序運算元:在評估評論分值過程中,使用排程器併發獲取排序因子所需要的資料,例如評論基礎資訊,主題物料資訊,策略模型服務,提權/降權詞表,重複內容庫等,獲取到的元資訊通過排序公式的權重完成評估過程。

  語義化公式:通過語義化公式識別,實現配置化上線,這裡的考量是,線上的效果需要不斷調整每個運算元的權重來小流量驗證,那通過這種方式可以實現快速上線完成驗證,對研發效率及產品迭代都是非常高效;

  排序索引:排序索引採用Redis作為儲存介質,通過zset資料結構來維護一篇文章下的評論排序列表。不同的公式組成不同的策略,在多組策略同時生效時,排序索引會以文章維度生成多個策略的排序結果,同時維護多套ID索引,評論線上服務通過小流量讀取策略組來命中不同的排序結果,方便AB實驗。

  離線粗排服務會針對評論的相關屬性輸出排序結果,線上部分,我們又對排序結果做了個性化的二次干預,包括個人評論提權,通訊錄/關注好友評論提權,以及精排模型干預,這些策略幫助我們更為精準地定位使用者群體的喜好,增加使用者瀏覽評論的共鳴感。

  如何保證服務的持續穩定性?

  背景:

  隨著系統承載的業務流量越來越大,對服務穩定性建設方向上,評論團隊也投入較大的資源/人力佔比,一方面持續保證系統服務的高可用,不斷提升系統容錯能力,突發異常情況下能夠快速應對,保障業務的最小可用單元,另一方面在業務邏輯反覆迭代過程保證系統服務的高效能,不斷提升使用者體驗。

  穩定性建設是個持續優化的過程,我們通過不斷探索,調研,選擇適合評論服務的技術方案並落地,評論業務特點是面向C端使用者,社會熱點事件會對業務產生直接影響,會引發讀寫流量的突增,其中寫流量的增加,對下游服務,下游儲存會產生不小的負荷,同時,過多的寫流量也會考驗讀流量的快取命中率,一旦出現某一主依賴異常,整體服務將處於不可用的狀態,針對這種風險,通過我們在熱點,快取,降級三個方面著手,為服務的穩定性保駕護航,下面看下具體實現方案:

百度的評論系統是怎麼設計的?

  快取管理:

  對於讀流量的突增情況的處理方式通過設計多級快取,提高快取的命中率來處理,根據評論業務特點,我們設計了評論列表快取,評論計數快取以及評論內容快取等,還使用了空快取,來針對特定場景下大部分資源無評論的情況,防止快取穿透。

  在接受業務讀流量請求時,首先使用LRU的本地快取抵擋一波流量,檢視是否能在最熱最近的記憶體快取列表中獲取結果,本地快取並沒有命中,將會從Redis獲取快取,如果是突發熱點,Redis的命中率很低,流量回源到db依然有很大的風險,所以這裡使用了一層例項鎖,從例項維度控制併發量,只允許一條請求透傳到下游,其他請求等待結果,用這種方式來防止快取擊穿。

  熱點機制:

  熱點事件往往會引發流量的突增,熱點事件產生時,通常會伴隨著Push類的通知,更加引發單篇資源的集中式讀寫請求,而且這種熱點事件產生時間比較隨機,很難做到提前預判,單篇資源讀寫流量的升高,會導致快取命中率下降,甚至快取徹底失效,大量請求直接打到資料庫,進而導致服務雪崩。

  為了避免熱點事件給系統帶來不可控的衝擊,我們設計了一套熱點自動發現/識別系統:通過訊息佇列監聽資源維度產生的評論行為,例如評論發表,回覆,點贊,稽核等等,通過計數來判定當前資源是否夠熱對評論行為進行計數統計。

  當一篇資源下的評論行為持續增多,達到某一閥值(動態可配置)時,該資源被判定為熱點資源,並將該資源推送至熱點配置中心,命中熱點的資源,其資源下產生的評論行為將寫入熱點佇列,非同步入庫,同時,寫操作後不再對快取進行清理,而是重建快取,來保證命中率。通過這一套機制,我們成功應對了一系列引發全民熱議的熱點事件,保證了使用者體驗。

  容災降級:

  當出現極端的故障時,對系統的穩定性會產生巨大的影響,比如下游服務承受不住突增的業務流量,請求超時,例項問題引發的單點故障,機房網路問題導致不可用等等,我們的服務每日承載著百億級別的PV流量,幾秒鐘的服務不可用就會產生巨大的損失。

  因此容災降級能力是考驗系統服務高可用的一個重要標準,我們在這方面做了一系列的措施來提升系統應對風險的能力,建設業務在異常狀態下的最小可用單元。

  在容災機制上,容災觸發細分為主動與被動,當業務與到可用性毛刺抖動時,由接入層進行感知,自動進入被動容災邏輯,寫請求進入佇列非同步入庫,讀請求直接返回容災資料,提升容災資料使用率。

  主動容災與運維平臺打通,實現按介面、按機房、按比例來判定服務是否降級成容災狀態;在依賴管理方面,梳理業務弱依賴,一旦發生某一依賴服務異常,可以直接對依賴進行摘除。

  在混沌工程方面,為了能夠應對線上各種突發狀況,對服務進行故障設計、故障注入,並針對服務給予的反饋,制定相應的預案建設,並將故障演練例行化,定期檢驗系統能夠承受的風險級別。

  5 總結

  百度評論中臺發展至今,歷經了角色定位/技術架構的轉變與升級,不斷探索應用創新,打造極致的使用者體驗,目前,評論服務為百度系20+的產品提供評論功能,峰值QPS達到40w+,日均PV達到百億規模,同時能夠保證SLA視角的介面穩定性在99.995%以上。在未來的發展規劃中,百度評論中臺在服務創新、中臺建設、穩定性等方面還會繼續深造,助力建設優質的百度社群氛圍。


來自 “ 分散式實驗室 ”, 原文作者:分散式實驗室;原文連結:https://mp.weixin.qq.com/s/wveq1JA4AzHNJVpws6lJhA,如有侵權,請聯絡管理員刪除。