導(dǎo)讀:百度搜索中臺系統(tǒng)不但承接了搜索的阿拉丁流量,也致力于構(gòu)建各個垂直業(yè)務(wù)的搜索能力。隨著業(yè)務(wù)的不斷發(fā)展,系統(tǒng)的流量規(guī)模已經(jīng)達(dá)到百億級別。而在百億流量的背后,是千級別的微服務(wù)模塊和數(shù)十萬的實例數(shù)量,如何保證這套復(fù)雜系統(tǒng)的高可用、高性能和高可控,全要素多維度的可觀測性成為搜索中臺系統(tǒng)能力的關(guān)鍵。
本文首先會介紹什么是可觀測性以及云原生時代為什么更要關(guān)注可觀測性,然后闡述搜索中臺是如何以極低的機器成本打造百億流量的實時指標(biāo)監(jiān)控(Metrics)、分布式追蹤(Traces)、日志查詢(Logs)和拓?fù)浞治觯═opos)。
1)什么是可觀測性
大家對監(jiān)控并不陌生,只要有系統(tǒng)存在,就需要有監(jiān)控幫我們?nèi)ジ兄到y(tǒng)發(fā)生的問題。而隨著業(yè)界傳統(tǒng)技術(shù)架構(gòu)往云原生架構(gòu)的邁進(jìn),可觀測性逐漸在越來越多的場合中被提到。如Distributed Systems Observability、Monitoring in the time of Cloud Native等都是對分布式系統(tǒng)可觀測性的一些解讀。在CNCF的云原生定義中,也將可觀測性當(dāng)成云原生架構(gòu)很重要的一個特性CNCF CloudNative Definition 1.0。
可觀測性是監(jiān)控的一個超集。監(jiān)控關(guān)注的是一些具體指標(biāo)的變化與報警,而可觀測性不僅需要提供對分布式系統(tǒng)所有鏈路運行狀況的高級概覽,還需要在系統(tǒng)發(fā)生問題時提供系統(tǒng)鏈路細(xì)化的分析,讓開發(fā)和運維同學(xué)“理解”系統(tǒng)發(fā)生的一切行為。
目前,業(yè)界廣泛推行可觀測性的基本要素包括:
-
指標(biāo)監(jiān)控(Metrics)
-
分布式追蹤(Traces)
-
日志查詢(Logs)
經(jīng)過一些實踐之后,我們還拓展了一個要素:拓?fù)浞治觯═opos)。「分布式追蹤」是從微觀角度去看一個請求的完整鏈路,而「拓?fù)浞治觥故菑暮暧^角度去分析問題。比如某個服務(wù) Qps 比平時擴大了數(shù)倍,我們需要定位異常流量的源頭,就依賴拓?fù)浞治龉ぞ摺?/span>
2)云原生架構(gòu)下可觀測性的必要性
在云原生時代,傳統(tǒng)的服務(wù)架構(gòu)和研發(fā)運維模式正在進(jìn)行著范式轉(zhuǎn)變。微服務(wù)、容器化、FAAS(serverless)等技術(shù)從根本上改變了應(yīng)用的研發(fā)模式和運維方式。但是,云原生架構(gòu)在帶來業(yè)務(wù)迭代效率指數(shù)級提升的同時,也產(chǎn)生了一些新的挑戰(zhàn)。從單體應(yīng)用往微服務(wù)進(jìn)行的轉(zhuǎn)變導(dǎo)致原本聚焦的系統(tǒng)變得分散,服務(wù)與服務(wù)之間連接的復(fù)雜度迅速提高,我們對系統(tǒng)整體的掌控力也在逐漸變?nèi)?。在這種情況下,如何去快速定位異常,做到系統(tǒng)的清晰可視,就成為了亟需解決的問題。
二、我們面臨的挑戰(zhàn)
1)超大系統(tǒng)規(guī)模
隨著微服務(wù)化等技術(shù)的使用和新業(yè)務(wù)的接入,百度搜索中臺的服務(wù)和實例規(guī)模不斷增加,服務(wù)間的鏈路關(guān)系也日趨復(fù)雜,在這樣一個龐大系統(tǒng)中建設(shè)可觀測性,也面臨著更多的挑戰(zhàn)。
對于日志的trace來說,目前搜索中臺天級別的請求量已經(jīng)達(dá)到了百億級別,如果使用常規(guī)的技術(shù)方案(如Dapper的思路),將日志放到集中式存儲里,意味著我們要付出上百臺機器資源,成本是非常高昂的。部分團隊使用抽樣或針對錯誤請求進(jìn)行記錄的方式,這種方式在搜索中臺場景存在著明顯問題:一. 抽樣無法保證覆蓋線上case。二. 很難有一種有效的方法識別錯誤請求,此外,用戶對一些正常請求仍然有trace需求(如誤召回問題)。
同樣地,對于指標(biāo)的數(shù)據(jù)聚合來說,在超大系統(tǒng)規(guī)模下,如何優(yōu)化資源占用和時效,也是一個極具挑戰(zhàn)的問題。
2)從應(yīng)用到場景的觀測要求
隨著搜索中臺業(yè)務(wù)場景的不斷豐富,我們的觀測視角也在發(fā)生著變化。過去更多關(guān)注的是應(yīng)用維度的信息,而現(xiàn)在一個應(yīng)用里可能有幾十種業(yè)務(wù)場景,不同場景流量的規(guī)模是完全不同。如果只關(guān)注應(yīng)用維度的指標(biāo),便可能在一些場景異常時,上層無法感知。如下圖就是一個典型的例子:場景三的流量因為較小,無法從應(yīng)用級別的指標(biāo)中提現(xiàn),因此在異常發(fā)生時,監(jiān)控沒有報警。同時,這種細(xì)分場景的指標(biāo)也可以輔助上層做一定的決策,如不同的場景,其中一個場景通過同步加載,而另一場景通過異步加載,兩者的超時要求是不一樣的,這時候就可以通過這種細(xì)分場景的指標(biāo),指導(dǎo)我們做精細(xì)化的控制。
但是,從應(yīng)用到場景的細(xì)分,導(dǎo)致系統(tǒng)的指標(biāo)量級急劇擴大,達(dá)到了百萬級。這對于指標(biāo)的聚合和計算來說,就成為一個新的挑戰(zhàn)。
3)對拓?fù)滏溌返暮暧^分析
在云原生架構(gòu)下,應(yīng)用與應(yīng)用之間的連接關(guān)系變得越來越復(fù)雜。分布式追蹤可以幫助我們定位某個具體請求的問題。而在系統(tǒng)出現(xiàn)一些宏觀問題:流量劇增,97分位耗時增加,拒絕率增加等,就需要拓?fù)浞治龉ぞ邘椭覀冞M(jìn)行定位。同時它對上層決策也有比較強的指導(dǎo)意義。如下圖右側(cè)的例子:商品搜索有兩類場景,第1類場景有運營活動,預(yù)計增加300qps的流量,如果沒有拓?fù)浞治龉ぞ叩脑?,我們就很難評估各個服務(wù)的容量Buffer。
三、我們做了什么
我們在去年,對可觀測性的四個要素進(jìn)行了探索和實踐,并發(fā)布了全要素的觀測平臺,為保障搜索中臺的可用性提供了有力保障。
1)日志查詢、分布式追蹤
隨著業(yè)務(wù)規(guī)模的增長,搜索中臺整體的日志量級達(dá)到了PB級的規(guī)模,通過離線存儲日志數(shù)據(jù),再進(jìn)行索引的方式會帶來巨大的資源開銷。而我們在這里使用了一種突破性的解決方案:在離線結(jié)合,離線存儲了少量的種子信息,在線直接復(fù)用線上的日志(0成本)。
具體做法是:
-
在流量入口層將logid、ip、訪問的時間戳存下來,存到一個kv存儲里。
-
當(dāng)用戶使用logid檢索的時候,在kv存儲中查詢logid對應(yīng)的ip和時間戳。
-
通過ip和時間戳去對應(yīng)的實例獲取完整的日志信息。
-
通過規(guī)則解析日志,獲取下游實例的ip和時間戳信息。
-
重復(fù)3-4的廣度遍歷過程,得到完整的調(diào)用鏈路拓?fù)洹?/span>
但是這里仍然存在一個問題:Trace時間較長。
實例需要需要對自己的日志文件進(jìn)行全量 grep,這在日志文件大、請求鏈路長的時候,會導(dǎo)致trace的時間較長,同時也會帶來穩(wěn)定性的沖擊。這里我們使用了按時間動態(tài)N分搜索的思路,利用請求的時間信息和時間有序的日志結(jié)構(gòu),快速進(jìn)行N分查找。
以下圖給大家舉例:圖中日志文件是 20 點的日志文件,當(dāng)前需要查詢 20 : 15 分的一個日志請求。因為 15 分鐘剛好是小時的 1/4,所以會先 fseek 這個文件的 1/4 位置。當(dāng)前 1/4 段的日志信息在 20 : 13,這個時候下半段的日志文件就是 47 分鐘的日志數(shù)據(jù),那就會再往下偏移 2/47,重新進(jìn)行fseek。重復(fù)這個過程就可以快速查詢對應(yīng)的詳細(xì)日志信息。
這種檢索方式可以獲得非常快的收斂速度,單實例的日志檢索耗時控制在 100ms 以內(nèi),對 io 的影響基本忽略不計。同時,用戶整體的檢索時間也控制在了秒級別。
2)指標(biāo)監(jiān)控
因為我們的觀測視角從應(yīng)用級別發(fā)展到了場景級別,指標(biāo)數(shù)量也從萬級別增加到了百萬級別,所以我們對監(jiān)控架構(gòu)進(jìn)行了重新設(shè)計。這張圖就是升級后的一個架構(gòu)圖。
它的主要思想是線上實例嵌一個依賴庫,這個依賴庫會收集所有的指標(biāo)信息,并將它做一定的預(yù)聚合,之后采集器輪詢式的去獲取線上的實例的指標(biāo)數(shù)據(jù),然后把聚合后的數(shù)據(jù)寫到tsdb里。值得注意的一點,這套方案和業(yè)界的一些指標(biāo)方案較大的不同:實例維度的指標(biāo)會在采集器里實時聚合,轉(zhuǎn)換成場景或服務(wù)維度的指標(biāo),隨后實例的維度指標(biāo)會被丟棄,不再存儲到tsdb中。因為實例維度的指標(biāo)參考意義有限,我們是使用聚合后的數(shù)據(jù)等來分析應(yīng)用的運行情況。
在這套架構(gòu)里,我們對計算和存儲進(jìn)行了很多的優(yōu)化,從線上指標(biāo)變化到平臺展現(xiàn),只需要2s的反饋時間,資源開銷非常輕量。以指標(biāo)的聚合為例:線上實例只進(jìn)行累加操作,而采集器會存上一次抓取的快照信息,和當(dāng)前這一次采集做對比,進(jìn)行線性差值計算。這種方式對線上實例的資源開銷是肉眼不可見的。同時也可以方便的去產(chǎn)出Qps、延遲等信息。
除了Qps、延遲之外,我們也優(yōu)化了分位耗時的計算方式。
分位耗時的計算常規(guī)方案是將請求的耗時做排序,然后取它的分位位置上的耗時數(shù)值。這種計算方式在請求量級較高的時候,資源占用非常高。因此我們采用了分桶計算的方式,按請求的耗時進(jìn)行分桶,當(dāng)請求執(zhí)行結(jié)束時,在對應(yīng)耗時的桶里加1;而在計算分位值時,先確定分位值所在的桶,桶內(nèi)數(shù)據(jù)則認(rèn)為服從線性分布,通過這樣的思路可以推導(dǎo)如下圖的公式。
這樣的好處是資源開銷低,可實時計算,但是缺點是會損失一部分精度。這個精度取決于分桶的粒度,在搜索中臺使用的桶大小是30ms,一般誤差在15ms以內(nèi),可以滿足性能觀測的需求。
3)拓?fù)浞治?/span>
拓?fù)浞治龅膶崿F(xiàn)利用了指標(biāo)監(jiān)控的運作機制。
首先,對流量進(jìn)行染色,并將染色信息通過RPC傳遞到各個服務(wù)。通過這種方式,讓每個span(注:span的定義來自Dapper論文)持有場景的標(biāo)識以及上游span的名稱。場景標(biāo)識可以區(qū)分不同場景的流量,而span名稱和上游span名稱可以建立父子的連接關(guān)系。這些span復(fù)用了上述指標(biāo)計算的機制,通過將span的信息存入指標(biāo)中,產(chǎn)出對應(yīng)的性能數(shù)據(jù)。當(dāng)用戶提供一個場景標(biāo)識時,平臺會把它的全部指標(biāo)提取出來,根據(jù)指標(biāo)內(nèi)的span信息,串聯(lián)成完整的調(diào)用拓?fù)洹?/span>
四、最后
到這里可觀測性的四個基本要素基本講述完了。在這四個要素之上,我們孵化了很多的應(yīng)用產(chǎn)品,如歷史快照、智能報警、拒絕分析等。通過這些產(chǎn)品,可以更好的幫助我們快速去發(fā)現(xiàn)和分析問題。
當(dāng)然,可觀測性的工作并不止步于此。我們也在依托這套觀測系統(tǒng),打造一些自適應(yīng)、自調(diào)整的柔性機制,在異常出現(xiàn)時,能夠自動容忍和恢復(fù),最大化的保持系統(tǒng)的生命力。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!