百度搜索穩定性問題分析的故事(下)

圖片

導讀:百度搜索系統是百度歷史最悠久、規模最大而且對其的使用已經植根在你們平常生活中的系統。坊間有一種有趣的作法:不少人經過打開百度搜索來驗證本身的網絡是否是通暢的。這種作法說明百度搜索系統在你們心目中是「穩定」的表明,且事實確是如此。百度搜索系統爲何具備如此高的可用性?背後使用了哪些技術?以往的技術文章鮮有介紹。本文立足於你們所熟悉的百度搜索系統自己,爲你們介紹其可用性治理中關於「穩定性問題分析」方面使用的精細技術,以歷史爲線索,介紹穩定性問題分析過程當中的困厄之境、破局之道、創新之法。但願給讀者帶來一些啓發,更但願能引發志同道合者的共鳴和探討。前端

全文5110字,預計閱讀時間11分鐘。算法

上週,在《百度搜索穩定性問題分析的故事(上)》中,已經介紹了咱們是如何經過全面的數據系統建設解決問題追查的死角,沒看過的朋友能夠從新看下這篇文章。接下來,將分享咱們如何進行故障的自動化、智能化分析,提升問題追查的效率。後端

第4章 再創新:應用價值的再釋放

4.1 巨浪——故障分析的「終點」

拒絕的分析是一個定性的過程,根據拒絕query激發的日誌信息,就能夠定位業務層面的緣由,或者定位到引發異常的模塊。網絡

這個過程能夠抽象爲下面幾步:架構

(1) 故障(拒絕)信號的感知工具

(2) 故障單位(query)全量信息(日誌)的收集post

(3) 根據收集到的信息進行故障單位(query)的歸因編碼

(4) 對批量故障單位(query)的緣由進行再歸類,以及特徵挖掘url

整個過程須要在秒級完成,時效性要求很高。過程的順利執行面臨下面8個挑戰:spa

挑戰1:如何實現快速的日誌檢索。在採集到拒絕信號以後,拒絕的分析須要快速拿到日誌原文,這些信息若是直接從線上掃描,速度和穩定性上顯然達不到要求。

挑戰2:拒絕定位的實時性和準確性之間的矛盾如何解決。日誌越完整,拒絕緣由的分析結果越準確。可是由於網絡延遲等緣由,分析模塊沒法保證立刻拿到全部的日誌。接收到拒絕信號後就開始分析,能夠確保分析的實時性,可是準確性難以保證。而延遲一段時間再分析,可能會拿到更完整的日誌,可是會影響拒絕分析的實時性。

挑戰3:如何準確全面地描述故障。生產環境的故障「五花八門」,若是逐個進行表達和管理,維護成本會很是高。須要尋找一種方案,把全部的故障(規則)系統、準確、全面地管理起來。

挑戰4:特徵工程如何進行。在拿到日誌原文以後,咱們須要肯定從日誌中應該拿哪些信息,如何採集這些信息,而且以程序能夠理解的方式將這些特徵表達出來,最終和拒絕緣由關聯起來,即特徵的選擇、提取、表達和應用。

挑戰5:如何還原query現場。在線系統爲了保證可用性,關鍵模塊上都會有重查。在定位拒絕時,須要還原出完整的調度樹,這樣才能看到由根節點出發到葉子節點各條路徑失敗的緣由,否則可能會獲得矛盾的結果。以下圖所示,A-一、B-1和B-2節點都發生了重查,當拼接錯誤時(C模塊的實例掛到了錯誤的B模塊節點下),B-1(或B-2)的錯誤狀態和掛在它之下的C模塊的日誌狀態多是矛盾的,沒法得出正確的定位結論。

圖片

挑戰6:如何對拒絕特徵進行深度挖掘。自動定位難以定位到根因,更精確的定位依賴人工參與的繼續分析。分析工具須要能從各類拒絕中找到彙集特徵並以必定的優先順序展現給用戶,爲根因定位或者止損提供更多線索。query中能夠提取的信息包括query的查詢詞(word),發送query的client端ip,query的語種或者處理query的機器所在的物理機房等。好比,當發現系統拒絕都和某個ip的攻擊流量有關時,能夠對該ip進行封禁止損。

圖片

挑戰7:級聯故障如何感知。當某個模塊故障引發拒絕時,可能會產生級聯的次生故障,表現爲拒絕直接緣由多樣化。下圖展現了 一種典型的級聯故障:E異常後B對C發起了大量重查,首查疊加劇查流量完全把D壓垮,最後A對B也開始發起大量重查。拒絕的流量在個個模塊都有可能命中限流策略,表現爲不一樣的拒絕緣由。所以,在產生故障時,依賴某一個時間點的拒絕統計信息可能會掩蓋引發拒絕的根因。

圖片

挑戰8:如何定位未知故障。故障是偶發的,咱們進行拒絕緣由劃分的時候所使用的劃分集合,沒法完總體現系統可能出現的拒絕緣由。對於未知故障或者未被歸入到拒絕定位規則中的拒絕,咱們須要有手段「製造」故障,發現未知或者未採集到的故障。

圖片

下面,將依次介紹咱們是如何解決這8個問題的。

4.1.1 索引鏡像技術

爲了實現日誌的快速檢索,日誌索引由在線採集模塊提取後,除了推送本機創建索引以外,還將定位須要的子集主動推送至旁路索引模塊,該模塊會以日誌對應的queryID爲key寫入內存介質的全量索引存儲中。這裏的索引支持多列稀疏存儲,相同queryID的多條日誌location能夠追加寫入。這樣,單條拒絕query的location信息能夠已O(1)的時間複雜度拿到,接下來並行地到目標機器上撈取日誌,並將其寫入持久化的故障日誌存儲中。最後對這些日誌進行特徵提取並分析拒絕緣由。

圖片

4.1.2 流式分析

爲了解決問題2,咱們借鑑了流式分析的理念。不管是分析模塊收到了拒絕信號仍是增量的拒絕日誌信號,都觸發一次拒絕緣由的分析,並更新結論。這裏有2個關鍵點:一是分析自動觸發,線上只要發生拒絕,拒絕分析就開始工做。二是增量更新,只要某個拒絕query的日誌有更新,就從新觸發故障緣由分析。對於入口模塊,在線採集端會根據其日誌中的指定字段判斷是不是拒絕,並將這個信號連同索引一塊兒推送到旁路索引模塊。旁路索引模塊在收到該信號後會當即通知分析中心對這個queryID進行分析,所以分析流程能夠在拒絕報警發出以前觸發,最大化故障定位止損效率。當旁路索引模塊向分析模塊觸發完一次分析請求後,會將這個queryID記錄到全量索引存儲的pvlost表中,當後續有非入口模塊日誌的索引到達時,旁路索引模塊拿該索引中的queryID到這個表中查找,便可判斷是不是須要觸發增量分析。增量分析會合並全部已知日誌,並更新分析結論。

4.1.3 完備labelset

在入口模塊接收到用戶query後,該query會經多個模塊的處理。每一個模塊都有讀取、解析請求包,請求後端,處理後端返回結果,以及最後的打包發送流程。在這個抽象層級上,請求處理各個步驟的劃分是足夠明確的,而且均可能出現失敗而引發query在該模塊的拒絕。因此,咱們對這個處理過程當中可能失敗的緣由進行了枚舉,構建了單模塊故障緣由完備模板,將該模版應用到全部的必查模塊就構成了故障緣由的完備集合。

圖片

4.1.4 特徵工程

在肯定了完備labelset(拒絕緣由)以後,咱們須要在程序中實現自動的特徵提取、表達,並和拒絕緣由創建映射。不一樣模塊的業務日誌差別很大,爲了解決特徵的提取問題,咱們實現規則提取引擎,輸入爲日誌原文和提取規則,輸出爲採集到的特徵。特徵的類型主要有2種:指定內容是否存在、值是多少。在提取出特徵以後,咱們使用一個向量表示各個特徵的取值,當向量中某些特徵的取值知足指定的條件(等於、在指定範圍等)時,就給出對應的拒絕緣由。

圖片

4.1.5 單query現場還原

日誌分析模塊拿到的日誌只是相互獨立的節點,進行query現場還原後才能開始分析。從入口模塊開始,搜索系統的各個模塊會把本身的span_id,以及所調度的多個後端的span_id打印出來,依據這些信息便可還原調度現場。須要注意的是,模塊發起的首查和重查是有前後順序的,經過對一個節點的孩子節點的span_id進行排序,便可還原這種調度上的前後次序。在還原調度樹以後,將調度樹由根節點到葉子節點路徑上的全部異常日誌彙總,從中拿到全部的特徵並和規則列表進行比對,便可獲得該路徑(調用鏈)的拒絕緣由。

圖片

4.1.6 智能rank算法

問題6的難點在於:在一批query全部維度的特徵中,找到有明顯彙集性的一個(一組)維度。這能夠進一步表示爲:在不一樣維度之間進行排序,找到排名最考前的維度,而排序的依據就是該維度內部取值是否有高度的彙集性。爲了解決這個問題,咱們借用了熵的概念——當拒絕的query在某個維度上取值彙集越強時,它的熵就會越低。在構建排序模型時,咱們對不一樣維度的取值進行了變換,確保不一樣維度可比,並加入了人工經驗肯定維度權重。這樣就能夠在出現拒絕時,按照順序給出拒絕query在不一樣維度的彙集性,幫助定位根因或制定止損策略。

4.1.7 時間線分析機制

爲了準確感知到拒絕的演化過程,咱們實現了timeline機制。收到拒絕報警後,該工具會自動從巨浪獲取拒絕信息,按照秒級粒度進行拒絕緣由數量統計,並進行二維展現,以下圖所示。在該展現結果上,能夠看到不一樣秒級時間各類拒絕的數量,以及不一樣拒絕緣由隨時間的變化趨勢,幫助咱們定位根因。

圖片

4.1.8 混沌工程技術

問了解決問題8,咱們引入了混沌工程的技術。混沌工程提供了向在線服務精確注入各類故障的能力,這樣就能夠拿到豐富且帶標記的樣本補充到定位知識庫中。這樣不只解決了日誌樣本問題,還可提高對未知故障的預測能力,從「亡羊補牢」進化到「未雨綢繆」,防患於未然。

這8大技術,很好的解決了前面的8個問題。在定位效果上,準確率可達99%,出現拒絕後,產出模塊粒度的拒絕緣由能夠在秒級完成,分析能力可覆蓋大規模拒絕。

4.2 長尾批量分析

搜索系統中存在着一些響應時間長尾,爲了解決這個問題,咱們基於全量tracing和logging數據,實現了一套例行長尾緣由分析機制。該機制定時從入口模塊拿到響應時間長尾的query,再對每一個query調用全量調用鏈的接口拿到完整的調度樹。在分析長尾緣由時,從入口模塊開始,經過廣度優先遍歷的方式,逐步向後端模塊推動,直到找到最後一個響應時間異常模塊,即認爲長尾是由該模塊引發的。

模塊響應時間異常的定義爲:該模塊的響應時間超過了正常請求的極限響應時間,而且它所調用的模塊的響應時間是正常的。在肯定異常模塊以後,能夠進一步從全量調用鏈中有針對性的拿到該模塊的日誌,從日誌中根據規則找到該模塊處理耗時異常的階段。

圖片

4.3 異常狀態全流程追蹤

爲了確保用戶體驗的穩定性,搜索會按期分析未召回預期結果的query。query沒有返回預期結果,多是由於它命中了「搗亂者」寫入的cache,也有可能它穿透了cache,召回了有問題的結果,這裏問題的緣由多是偶發的或者是穩定的。咱們須要能篩選出能夠穩定復現的問題進行追查。爲了實現這個需求,咱們先拿到各個query的tracing以及logging信息,根據這些信息能夠:

(1)找到哪些query命中了「搗亂者」寫入的髒cache;

(2)哪些query穿透到了後端並從新進行了檢索。

將命中cache的query和寫入cache的query關聯起來,便可獲得下圖所示的結果——異常狀態的全流程追蹤。只要異常效果持續時間內的cache命中是連續的,而且觸發了屢次cache的更新,那麼就能夠認爲在這一段時間內,故障是穩定復現的,能夠投入人力追查。

圖片

第5章 總結

本文首先介紹了百度搜索可用性保障的困境,超大的服務規模、極高頻的變動和參與人數、海量數據和請求量、多樣且多變的故障種類等構成的複雜系統,對年只能停服5分鐘的極端嚴格可用性目標構成了極大挑戰。而後,以時間順序介紹了咱們對百度搜索可用性保障的解決經歷和經驗。

首先,爲了解決問題追查死角的問題,咱們建設了可觀測基礎——logging、tracing、metrics,這些沒有精細加工的基礎數據解決了可用性保障中的一部分問題,可是咱們發現基礎數據的自動化程度較低、智能性較差,複雜問題須要大量人力投入,分析效果強依賴人工經驗,甚至根本沒法分析。

更進一步,爲了解決可用性保障的效率問題,咱們對體系中的各個組件進行升級,使可觀測性的產出變得可觀測,複雜的效果故障由不可追查變得可追查,拒絕分析從人工變得自動、準確、高效。在整個體系建設過程當中,咱們從數據的消費者,變成數據的生產者和加工者,經過數據的生產、加工、分析全流程閉環,使得百度搜索中各類故障無處遁形、無懈可擊,使得百度搜索可用性保障擺脫困境,持續維持較好的用戶口碑,同時本文也但願給讀者帶來一些啓發,更但願能引發志同道合者的共鳴和探討。

本期做者 | ZhenZhen;LiDuo;XuZhiMing

招聘信息

關注同名公衆號百度Geek說,點擊菜單欄「內推」便可加入搜索架構部,咱們期待你的加入!

推薦閱讀

|百度搜索穩定性問題分析的故事(上)

百度關於微前端架構EMP的探索:落地生產可用的微前端架構

社羣編碼識別黑灰產攻擊實踐

PornNet:色情視頻內容識別網絡

---------- END ----------

百度Geek說

百度官方技術公衆號上線啦!

技術乾貨 · 行業資訊 · 線上沙龍 · 行業大會

招聘信息 · 內推信息 · 技術書籍 · 百度周邊

歡迎各位同窗關注

相關文章
相關標籤/搜索