一分鐘精華速覽
分布式鏈路追蹤系統(tǒng)在企業(yè)的APM體系中扮演著重要的角色。本文分享了去哪兒旅行構(gòu)建分布式鏈路追蹤系統(tǒng)的實(shí)踐經(jīng)驗(yàn)。從APM整體架構(gòu)設(shè)計(jì)入手,講述了日志收集、Kafka傳輸和Flink任務(wù)處理等環(huán)節(jié)的性能優(yōu)化實(shí)踐和踩坑經(jīng)驗(yàn)。
同時(shí),作者結(jié)合豐富的分布式系統(tǒng)架構(gòu)經(jīng)驗(yàn),探討了APM系統(tǒng)和Trace數(shù)據(jù)的價(jià)值。通過(guò)閱讀本文,你將了解到去哪兒旅行在構(gòu)建APM體系中所面臨的挑戰(zhàn),并學(xué)習(xí)如何應(yīng)對(duì)這些挑戰(zhàn),實(shí)現(xiàn)更高效的性能監(jiān)控和管理。 作者介紹
去哪兒旅行基礎(chǔ)平臺(tái)架構(gòu)師——王 鵬 TakinTalks穩(wěn)定性社區(qū)專家團(tuán)成員。畢業(yè)于大連理工大學(xué),10年以上大型分布式基礎(chǔ)架構(gòu)經(jīng)驗(yàn),專注于大型分布式基礎(chǔ)架構(gòu)和大數(shù)據(jù)處理領(lǐng)域。曾就職于58集團(tuán),主要負(fù)責(zé)58到家基礎(chǔ)架構(gòu)工作。后進(jìn)入去哪兒旅行,負(fù)責(zé)分布式鏈路追蹤系統(tǒng)的建設(shè)以及APM體系的搭建。在大數(shù)據(jù)、高并發(fā)的場(chǎng)景有豐富的經(jīng)驗(yàn)。
溫馨提醒:本文約7000字,預(yù)計(jì)花費(fèi)10分鐘閱讀。
TakinTalks穩(wěn)定性社區(qū),公眾號(hào)后臺(tái)回復(fù) “交流” 進(jìn)入讀者交流群;回復(fù)“1012”獲取課件資料;
背景
APM并不是一個(gè)新的概念。從2012年到2016年,市場(chǎng)上涌現(xiàn)了許多開(kāi)源的APM組件,如SkyWalking、Jaeger等??梢哉f(shuō),在過(guò)去幾年中,隨著技術(shù)的發(fā)展和系統(tǒng)的復(fù)雜性增加,分布式鏈路追蹤系統(tǒng)和應(yīng)用性能管理(APM)已成為許多公司不可或缺的工具。
大多數(shù)公司都會(huì)根據(jù)其技術(shù)棧和業(yè)務(wù)體系來(lái)構(gòu)建自己的APM體系和分布式鏈路追蹤系統(tǒng)。以去哪兒旅行為例,我們的主要業(yè)務(wù)涉及搜索查詢和電子商務(wù)交易等領(lǐng)域。由于業(yè)務(wù)體系的不同,在技術(shù)選擇、方案設(shè)計(jì)方面可能存在一些差異。
在構(gòu)建和應(yīng)用APM體系的過(guò)程中,去哪兒遇到了許多挑戰(zhàn)。例如,在日志收集、Kafka傳輸以及Flink任務(wù)處理等環(huán)節(jié)遇到了一些問(wèn)題。這次會(huì)分享如何克服這些性能瓶頸,以及在這個(gè)過(guò)程中積累的經(jīng)驗(yàn)和教訓(xùn),希望這些經(jīng)驗(yàn)對(duì)其他公司在解決類似問(wèn)題時(shí)能夠有所幫助。
一、APM整體架構(gòu)是如何設(shè)計(jì)的?
作為一個(gè)OTA交易平臺(tái),去哪兒旅行的業(yè)務(wù)系統(tǒng)分為搜索和下單交易部分。從流量來(lái)看不會(huì)特別大,OTA的交易量無(wú)法與零售電商交易相比。因此,去哪兒在構(gòu)建APM體系上與其他電商公司可能存在一些不同。例如,大多數(shù)公司APM的Trace部分采用采樣策略,但對(duì)我們來(lái)說(shuō),每一次請(qǐng)求、每一次查詢或者每一次交易,尤其是交易鏈路的Trace非常少,每天幾百萬(wàn)的交易量,產(chǎn)生的Trace不會(huì)太多。因此,最終采用了交易鏈路全采樣的技術(shù)方案。
此外,從2020年開(kāi)始,全公司技術(shù)棧之前的虛擬機(jī)模式轉(zhuǎn)向了云原生的開(kāi)發(fā)架構(gòu)。在這三年中,從應(yīng)用層、開(kāi)發(fā)層和容器層,都已經(jīng)完成了遷移。在遷移完成后,需要將可觀測(cè)性的相關(guān)體系遷移到云上,或者說(shuō)適配云原生的開(kāi)發(fā)環(huán)境。
在構(gòu)建APM體系的早期,由于眾多開(kāi)源技術(shù)尚未出現(xiàn),進(jìn)行了大量的自研工作。例如,早期我們依賴自研的Java中間件記錄Trace。但現(xiàn)在,開(kāi)源社區(qū)已經(jīng)提供了許多優(yōu)秀的方案,可以根據(jù)公司環(huán)境、階段和技術(shù)路線做出合理的選擇。
經(jīng)過(guò)技術(shù)分析與選型后,去哪兒旅行的APM體系采用插樁Agent模式和中間件埋點(diǎn)并行的方式(如圖)。其中,紅色部分是重點(diǎn)改造部分。
(去哪兒旅行APM體系整體架構(gòu))
首先,左上部分主要是如何記錄和獲取Trace信息。部分中間件以硬編碼的方式獲取Trace數(shù)據(jù),另外,一些開(kāi)源的第三方組件通過(guò)Agent模式獲取了Trace。
其次,關(guān)于如何收集這些數(shù)據(jù),去哪兒旅行采用了開(kāi)源的Apache Flume日志收集組件,并對(duì)其進(jìn)行了一系列改造。改造的原因是原生組件并未提供如配置管理功能、限流控制等一些必要的功能。
第三,處理層的任務(wù)非常繁重,選擇了Flink作為數(shù)據(jù)處理任務(wù)框架。數(shù)據(jù)處理不僅需要實(shí)時(shí)處理Trace的詳細(xì)數(shù)據(jù),還需要存儲(chǔ)并分析出的Trace異常、后置采樣、鏈路分析等等。
最后,Metrics部分則是一個(gè)標(biāo)準(zhǔn)的收集和處理流程,通過(guò)Statsd將數(shù)據(jù)存儲(chǔ)到時(shí)序DB,最終有Prometheus + Grafana去展示。
總的來(lái)說(shuō),去哪兒旅行的APM體系整體架構(gòu)設(shè)計(jì)結(jié)合了開(kāi)源技術(shù)和自研成果,以實(shí)現(xiàn)更高效的性能監(jiān)控和管理。
二、遇到了哪些“坑”?
2.1 日志收集組件的性能瓶頸優(yōu)化
在Trace數(shù)據(jù)收集過(guò)程中,確實(shí)存在許多挑戰(zhàn)。由于許多業(yè)務(wù)和監(jiān)控系統(tǒng)基于Trace和Metrics來(lái)判斷是否發(fā)出告警,因此這種收集需要比離線日志更實(shí)時(shí)。然而,這也意味著它們需要在保持高性能的同時(shí),保證不會(huì)影響宿主機(jī)的性能,這是一個(gè)非常大的挑戰(zhàn)。
2.1.1 問(wèn)題表現(xiàn):Trace數(shù)據(jù)中斷
在對(duì)系統(tǒng)進(jìn)行改造前,發(fā)現(xiàn)有大量的Trace出現(xiàn)了數(shù)據(jù)中斷的問(wèn)題。這種問(wèn)題表現(xiàn)為Trace的某些部分(比如Span ID為1.4和1.4.2的部分)突然消失,而后面的部分(比如Span ID為1.5)又突然出現(xiàn)。這種情況可能由兩種原因?qū)е?,一種是中間件里沒(méi)有這部分?jǐn)?shù)據(jù),另一種是中間件里有數(shù)據(jù)但是沒(méi)有傳送過(guò)來(lái)。無(wú)論是哪種原因,都需要對(duì)系統(tǒng)進(jìn)行深入地分析。
2.1.2 抽樣分析:日志組件和配置問(wèn)題
嘗試把以上問(wèn)題拆解成可視化的指標(biāo),以便于理解和處理它。首先,查看了整個(gè)Trace的問(wèn)題比例,可以通過(guò)圖上的監(jiān)控看到Trace中斷率達(dá)到了驚人的70%~80%。這個(gè)結(jié)果說(shuō)明大部分的Trace數(shù)據(jù)都存在問(wèn)題。
為了進(jìn)一步確定問(wèn)題的原因,我們對(duì)100個(gè)問(wèn)題數(shù)據(jù)進(jìn)行了抽樣分析。分析結(jié)果顯示,有一半的問(wèn)題是日志收集組件的問(wèn)題,也就是Qflume組件的問(wèn)題;另一部分問(wèn)題則是配置問(wèn)題,即沒(méi)有正確配置數(shù)據(jù)收集,導(dǎo)致數(shù)據(jù)沒(méi)有被收集到。除此之外,還存在一些其他的問(wèn)題。
對(duì)于配置問(wèn)題,可以通過(guò)統(tǒng)一刷新配置來(lái)解決。
而對(duì)于日志收集組件的問(wèn)題,則需要進(jìn)行更深入的分析和改造。首先需要對(duì)其內(nèi)部工作流程進(jìn)行了解。從左到右,這個(gè)流程圖展示了日志處理過(guò)程。
在最左側(cè),業(yè)務(wù)應(yīng)用通過(guò)異步隊(duì)列將日志輸出到磁盤文件。這個(gè)隊(duì)列的長(zhǎng)度是有限的,用來(lái)控制內(nèi)存占用。如果隊(duì)列滿了,新的日志就會(huì)被丟棄。這就是日志丟失的一個(gè)原因。
還有其他兩個(gè)瓶頸——一個(gè)是系統(tǒng)通過(guò)單線程同步讀取日志,這個(gè)讀取速度跟不上日志生成的速度。另一個(gè)是系統(tǒng)使用同步發(fā)送Kafka來(lái)傳輸日志。
2.1.3 優(yōu)化效果
為了解決這些問(wèn)題,采取了兩個(gè)措施。首先,增加了異步隊(duì)列的長(zhǎng)度,但是也不能讓它過(guò)長(zhǎng),以免消耗過(guò)多的內(nèi)存。其次,將單線程讀取改為批量讀取,每次讀取一個(gè)批次的日志。此外,還將同步發(fā)送改為Kafka異步發(fā)送,發(fā)送完一批日志后立馬發(fā)送下一批,這樣可以大大的提高吞吐量。
這樣優(yōu)化后,分鐘級(jí)傳輸?shù)臄?shù)據(jù)量有了顯著的提升,可以達(dá)到每分鐘80億甚至100億條數(shù)據(jù)量。
2.1.4 踩坑點(diǎn)1:傳輸失敗率大幅提高
問(wèn)題描述: 盡管解決了日志組件的性能問(wèn)題,可以快速地讀取和發(fā)送數(shù)據(jù)。然而,隨之而來(lái)的問(wèn)題是Kafka的數(shù)據(jù)量非常不穩(wěn)定,呈現(xiàn)出明顯的波動(dòng)。
原因分析: 在查看相關(guān)數(shù)據(jù)后,發(fā)現(xiàn)了一個(gè)嚴(yán)重問(wèn)題:頻繁的內(nèi)存溢出(OOM)。這個(gè)問(wèn)題的原因在于,優(yōu)化后的日志組件以批量的方式讀取數(shù)據(jù),這會(huì)占用大量的內(nèi)存。如果內(nèi)存不足,就會(huì)發(fā)生OOM。
一種解決這個(gè)問(wèn)題的方法是增大內(nèi)存,但這并不是一個(gè)長(zhǎng)久之計(jì),因?yàn)橘Y源有限,不能無(wú)限制地增加內(nèi)存。另外,Trace日志的實(shí)時(shí)性要求并不像業(yè)務(wù)那么高,晚幾秒甚至十幾秒都是可以接受的,只要數(shù)據(jù)最終能夠傳輸過(guò)去就可以。
如何解決? 解決思路是在保證高性能的前提下,對(duì)數(shù)據(jù)傳輸進(jìn)行限流,讓日志組件在一個(gè)可控的內(nèi)存使用范圍內(nèi)高效的工作。
限流方案包括設(shè)定時(shí)間窗口和對(duì)單條日志大小做限制。在設(shè)定時(shí)間窗口的方法中,時(shí)間窗口是滑動(dòng)時(shí)間窗口,也可以是一條日志的處理時(shí)間。比如設(shè)置時(shí)間窗口為一秒、兩秒或五秒,然后規(guī)定在這個(gè)時(shí)間窗口內(nèi),限制數(shù)據(jù)傳輸?shù)拇笮?,比如不能超過(guò)200M。
盡管設(shè)置了時(shí)間窗口,但日志組件仍可能會(huì)出現(xiàn)OOM的問(wèn)題。原因在于有些日志非常大,一條日志就有幾兆甚至幾十兆。這種情況雖然不合理,但卻確實(shí)存在。如果遇到這樣的日志傳輸過(guò)來(lái),很可能會(huì)導(dǎo)致服務(wù)癱瘓。因此,團(tuán)隊(duì)還需要對(duì)單條日志的大小進(jìn)行限制,如果日志過(guò)長(zhǎng),就需要進(jìn)行截?cái)嗵幚怼?/p>
另外,如果出現(xiàn)OOM,團(tuán)隊(duì)也需要進(jìn)行斷點(diǎn)續(xù)傳的工作。不能重新傳輸已經(jīng)傳輸過(guò)的Trace,因?yàn)檫@樣會(huì)造成大量的資源浪費(fèi),且重復(fù)傳輸本身也是有問(wèn)題的。
通過(guò)這些限制,就可以保證堆內(nèi)存的使用不會(huì)超過(guò)限制,同時(shí)保持日志組件的高性能。
2.1.5 踩坑點(diǎn)2:接口耗時(shí)增長(zhǎng),吞吐量下降
問(wèn)題描述:
在解決日志組件內(nèi)存溢出問(wèn)題之后,又遇到了新的挑戰(zhàn):業(yè)務(wù)線反饋接口耗時(shí)突然大幅上升,吞吐量大幅下降,甚至有些業(yè)務(wù)應(yīng)用被操作系統(tǒng)直接終止,導(dǎo)致故障出現(xiàn)。這個(gè)問(wèn)題在一開(kāi)始是令人困惑的,因?yàn)橐呀?jīng)解決了OOM的問(wèn)題,并且對(duì)內(nèi)存使用進(jìn)行了嚴(yán)格的限制。怎會(huì)出現(xiàn)影響業(yè)務(wù)系統(tǒng)的情況呢?
原因分析:
在排查問(wèn)題時(shí),發(fā)現(xiàn)有問(wèn)題的服務(wù)器上,CPU利用率非常高,達(dá)到197%,內(nèi)存的使用率也非常高,幾乎已經(jīng)沒(méi)有剩余空間。那么,這是由什么原因引起的呢?回顧之前做的優(yōu)化工作,發(fā)現(xiàn)在優(yōu)化日志傳輸?shù)牟襟E中,將Kafka的發(fā)送操作變成了異步發(fā)送。而在異步發(fā)送過(guò)程中,會(huì)大量占用堆外內(nèi)存。
之前針對(duì)堆內(nèi)內(nèi)存做了限制,但是對(duì)堆外內(nèi)存并沒(méi)有做限制。如果Kafka大量發(fā)送數(shù)據(jù),但是由于某些原因傳輸不過(guò)來(lái),那么這些數(shù)據(jù)就需要放在堆外內(nèi)存中等待發(fā)送。這就是導(dǎo)致內(nèi)存使用率高漲,最后操作系統(tǒng)終止業(yè)務(wù)進(jìn)程。
如何解決?
那么,如何限制堆外內(nèi)存的大小呢?或者說(shuō),如何限制進(jìn)程使用的內(nèi)存空間呢?
從Docker這個(gè)容器技術(shù)中找到了靈感。熟悉Docker都知道,Docker容器中使用的資源是固定的,包括磁盤空間、CPU以及內(nèi)存等,不能超過(guò)容器在初始時(shí)分配的大小。那么,Docker是如何實(shí)現(xiàn)這個(gè)功能的呢?
這就涉及到CGroup技術(shù),也就是Linux內(nèi)核提供的控制組(Control Group)技術(shù)。CGroup技術(shù)主要用于限制和隔離進(jìn)程組應(yīng)用的物理資源,簡(jiǎn)單來(lái)說(shuō),可以通過(guò)CGroup技術(shù)將硬件資源切分成很多塊,并對(duì)每一塊資源設(shè)定使用限制,進(jìn)程和其產(chǎn)生的子進(jìn)程都不能超過(guò)這個(gè)限制。
通過(guò)CGroup技術(shù),限制進(jìn)程的堆外內(nèi)存使用和CPU使用,保證它們都在一個(gè)合理的范圍之內(nèi)。
2.1.6 優(yōu)化效果
CGroup進(jìn)行資源限制后,系統(tǒng)的效率得到了顯著提升。Root失敗率從原來(lái)的80%降低到了20%,優(yōu)化效果十分明顯。
2.2 高并發(fā)下Kafka集群傳輸優(yōu)化
在解決了日志收集問(wèn)題,資源使用得到了限制之后,大量的日志被發(fā)送到了Kafka集群,然后Kafka集群再將日志傳輸給Flink任務(wù)進(jìn)行處理。這就引出了新的問(wèn)題:如何保證Kafka集群能夠高效穩(wěn)定地傳輸日志?
2.2.1 問(wèn)題表現(xiàn)
隨著日志收集客戶端在全公司范圍內(nèi)的推廣,大約有1萬(wàn)多個(gè)實(shí)例部署,Kafka集群開(kāi)始出現(xiàn)了不穩(wěn)定的情況。Kafka集群會(huì)出現(xiàn)大量的連接失敗,整個(gè)的數(shù)據(jù)接收量和發(fā)送量都會(huì)急劇下降。在這期間并沒(méi)有對(duì)集群做任何改動(dòng),收集組件也沒(méi)有做任何改動(dòng),但是卻頻繁出現(xiàn)這種不穩(wěn)定問(wèn)題。
2.2.2 問(wèn)題分析
通過(guò)查看了Kafka集群的監(jiān)控,發(fā)現(xiàn)網(wǎng)絡(luò)空閑連接和線程數(shù)急劇下降。這可能是導(dǎo)致Kafka集群連接失敗,數(shù)據(jù)傳輸量下降的主要原因。
在Kafka的架構(gòu)中,客戶端首先與網(wǎng)絡(luò)接收線程組進(jìn)行連接,發(fā)送日志數(shù)據(jù)。網(wǎng)絡(luò)接收線程組在接收到數(shù)據(jù)后,將任務(wù)轉(zhuǎn)發(fā)給RequestQueue進(jìn)行處理。
Processor處理器的主要工作是將請(qǐng)求放入請(qǐng)求通道隊(duì)列(RequestChannel)。理論上,處理器的空閑量應(yīng)該較大,因?yàn)槠涔ぷ鞑⒉粡?fù)雜,僅僅是進(jìn)行內(nèi)存操作,將網(wǎng)絡(luò)接收的任務(wù)提交到隊(duì)列。然而,監(jiān)控?cái)?shù)據(jù)卻顯示處理器的空閑數(shù)急劇下降,變得非常繁忙,并沒(méi)有足夠的空閑鏈接去處理網(wǎng)絡(luò)請(qǐng)求。
進(jìn)一步分析,發(fā)現(xiàn)請(qǐng)求處理器(KafkaReuestHandler)從請(qǐng)求通道隊(duì)列中取出任務(wù)進(jìn)行處理,主要是將請(qǐng)求寫入磁盤。如果請(qǐng)求處理器處理不過(guò)來(lái),請(qǐng)求通道隊(duì)列的數(shù)據(jù)就會(huì)逐漸增多。當(dāng)隊(duì)列滿時(shí),新的請(qǐng)求無(wú)法進(jìn)入,導(dǎo)致網(wǎng)絡(luò)連接空閑數(shù)急劇下降。
綜合以上所述,問(wèn)題可能出在Kafka的請(qǐng)求處理器這一環(huán)節(jié)。主要可能是內(nèi)存不足或者刷盤速度不夠快。進(jìn)一步檢查后,發(fā)現(xiàn)確實(shí)有些機(jī)器的內(nèi)存不夠,有些機(jī)器的刷盤速度有問(wèn)題,甚至有些磁盤已經(jīng)損壞,導(dǎo)致部分機(jī)器的性能急劇下降。
2.2.3 優(yōu)化效果
將有問(wèn)題的機(jī)器從集群中移除,并增大了內(nèi)存。經(jīng)過(guò)這些優(yōu)化,整個(gè)Kafka集群恢復(fù)了正常狀態(tài)。
(正常狀態(tài)下的集群)
優(yōu)化后的效果明顯,Kafka集群的收發(fā)狀態(tài)保持在一個(gè)正常的水平。在約1分鐘的時(shí)間里,可以收發(fā)1.7億多條數(shù)據(jù)。而且,根據(jù)業(yè)務(wù)的波峰波谷,數(shù)據(jù)的收發(fā)呈現(xiàn)出穩(wěn)定的狀態(tài),不再出現(xiàn)以前的陡增陡降的情況。
2.3 百萬(wàn)級(jí)QPS數(shù)據(jù)處理任務(wù)優(yōu)化
在數(shù)據(jù)處理過(guò)程中,任務(wù)這一環(huán)節(jié)是最核心的部分。在對(duì)比了Spark和Flink的流式處理后,發(fā)現(xiàn)后者更適合Trace場(chǎng)景。Flink任務(wù)本身也比較復(fù)雜,如何能保證它的高可靠和高性能?
2.3.1 數(shù)據(jù)處理任務(wù)
數(shù)據(jù)存儲(chǔ)量的QPS400w左右,峰值1000w。數(shù)據(jù)進(jìn)入任務(wù)首先進(jìn)行反序列化,之后開(kāi)始實(shí)時(shí)計(jì)算業(yè)務(wù)線的拓?fù)?、異常Trace拓?fù)?、Metrics和Trace關(guān)聯(lián)關(guān)系等。
另一個(gè)重要的任務(wù)是存儲(chǔ)。每秒幾百GB的日志存儲(chǔ)到存儲(chǔ)介質(zhì)中,有HBase、ES、ClickHouse等存儲(chǔ)介質(zhì)。這些存儲(chǔ)還有一些關(guān)聯(lián)數(shù)據(jù),這些關(guān)聯(lián)數(shù)據(jù)需要拆分。例如,有很多Metrics和Trace的關(guān)聯(lián)數(shù)據(jù),需要先將它們解析出來(lái),然后做分布式的存儲(chǔ),將它們存入數(shù)據(jù)庫(kù)。這些計(jì)算都是在Flink的任務(wù)里面完成的。
2.3.2 Flink任務(wù)拆分
上圖是一個(gè)大任務(wù),整個(gè)數(shù)據(jù)打散后分給不同的子任務(wù)去處理。這種方式有一個(gè)問(wèn)題,如果某個(gè)子任務(wù)處理速度較慢,會(huì)產(chǎn)生一些背壓。背壓會(huì)繼續(xù)向上反映到總的任務(wù)分發(fā)環(huán)節(jié)。分發(fā)環(huán)節(jié)處理速度慢,所有任務(wù)的處理速度也會(huì)變慢。所以,一個(gè)小任務(wù)出問(wèn)題,就導(dǎo)致整個(gè)鏈路出問(wèn)題。
因此,將一些不關(guān)聯(lián)的Trace任務(wù)進(jìn)行拆分,而不是讓它們耦合在一起。這樣做可以大大降低問(wèn)題的發(fā)生概率。
2.3.3 背壓如何解決?
背壓(Back Pressure)是流控制中的一種策略,主要用于保護(hù)系統(tǒng)在高負(fù)載情況下的穩(wěn)定性。當(dāng)下游處理速度跟不上,上游數(shù)據(jù)輸入的速度時(shí),就會(huì)發(fā)生背壓,這就像水管出水口被堵住,壓力太大后就可能會(huì)導(dǎo)致水管崩裂。
解決背壓可以從以下幾個(gè)方面著手:
觀察Flink任務(wù)中子任務(wù)的消費(fèi)是否均勻。Flink任務(wù)會(huì)被分解為子任務(wù),子任務(wù)會(huì)被分配到不同的機(jī)器上執(zhí)行。如果某些高耗CPU或者高耗IO的任務(wù)集中在同一臺(tái)機(jī)器,會(huì)導(dǎo)致該機(jī)器的處理能力不足,從而影響整個(gè)任務(wù)的處理速度。因此,需要關(guān)注子任務(wù)的消費(fèi)均勻性,并嘗試調(diào)整資源的分配,使其更加均衡。 關(guān)注上下游算子的內(nèi)存是否充足。如果輸出算子的內(nèi)存不足,可能會(huì)導(dǎo)致輸入算子的數(shù)據(jù)無(wú)法正常傳遞。因此,需要通過(guò)內(nèi)存監(jiān)控,并合理設(shè)置不同算子的內(nèi)存大小。 盡量使用內(nèi)存的Map來(lái)替代Window。雖然Window可以保證數(shù)據(jù)的完整性,但在某些情況下,并不需要這么強(qiáng)的一致性,更多的時(shí)候只是對(duì)數(shù)據(jù)緩存,使用內(nèi)存的Map可以極大的節(jié)省內(nèi)存消耗。
善用Shared Group。Filter一定小心下游算子的擁堵導(dǎo)致全面的擁堵,Shared Group可以將頻繁進(jìn)行網(wǎng)絡(luò)傳輸?shù)乃阕臃诺揭粋€(gè)JVM內(nèi),這樣可以極大的節(jié)省網(wǎng)絡(luò)資源和計(jì)算資源。
2.3.4 優(yōu)化效果
通過(guò)優(yōu)化背壓?jiǎn)栴},平均寫入達(dá)到400萬(wàn)QPS,平均寫入耗時(shí)在600ms左右,這是一個(gè)非常不錯(cuò)的性能表現(xiàn)。
三、如何看到APM和Trace數(shù)據(jù)的價(jià)值?
3.1 APM系統(tǒng)有哪些作用?
當(dāng)系統(tǒng)經(jīng)過(guò)幾年的發(fā)展,可能會(huì)變得雜亂無(wú)章,各個(gè)系統(tǒng)之間的聯(lián)系混亂不堪。在這樣的情況下,可能對(duì)系統(tǒng)的運(yùn)行邏輯一頭霧水,更別說(shuō)從這個(gè)混亂的拓?fù)渲姓页鰡?wèn)題所在。而APM系統(tǒng)的作用就是幫助理清這些混亂的聯(lián)系,然后指出可能出現(xiàn)問(wèn)題的地方。與僅有監(jiān)控系統(tǒng)相比,APM系統(tǒng)可以更清晰地定位問(wèn)題所在,這是一個(gè)巨大的價(jià)值點(diǎn)。
(APM系統(tǒng)讓查問(wèn)題變得更簡(jiǎn)單)
3.2 Trace與Metrics怎么關(guān)聯(lián)
在業(yè)界很多并沒(méi)有關(guān)注Metrics和Trace的關(guān)聯(lián)關(guān)系,常見(jiàn)的做法是根據(jù)時(shí)間進(jìn)行隨機(jī)關(guān)聯(lián)。然而,這樣的關(guān)聯(lián)性并不強(qiáng)。因此,根據(jù)去哪兒的業(yè)務(wù)情況進(jìn)行了一些改進(jìn)。
針對(duì)三類指標(biāo)進(jìn)行分析:一類是Time類的指標(biāo),一類是Count類的指標(biāo),另一類是Rate類的指標(biāo)。
1、Time類指標(biāo):假如一種操作的耗時(shí)是最長(zhǎng)的,那么這種操作肯定是存在問(wèn)題的。所以這類指標(biāo)我們只取Top10即可。
2、Count類指標(biāo):處理方式會(huì)相對(duì)復(fù)雜一些,因?yàn)樗婕暗降臉I(yè)務(wù)概念較多。采用了隨機(jī)策略,比如在記錄某個(gè)指標(biāo)時(shí),無(wú)法將所有的Metrics與Trace的關(guān)聯(lián)關(guān)系全部記錄下來(lái),只需要隨機(jī)抽取一部分進(jìn)行記錄就可以了。另外一種策略是:報(bào)警策略,假如某個(gè)指標(biāo)出現(xiàn)報(bào)警,那么在這段時(shí)間內(nèi)這個(gè)指標(biāo)存在問(wèn)題的概率是非常大的,所以會(huì)提高采樣率,為了更可能命中存在問(wèn)題的Trace。還有一種策略是:關(guān)鍵詞策略,比如定義了一些業(yè)務(wù)異常,這種情況下,會(huì)進(jìn)行全采樣,因?yàn)檫@種Trace的價(jià)值非常大,例如ERRO FAILED EXCEPTION 等關(guān)鍵詞。
3、Rate類指標(biāo):處理起來(lái)會(huì)更為困難。因?yàn)镽ate類指標(biāo)往往是兩個(gè)數(shù)的比值,比如成功率和失敗率。這些指標(biāo)上升還好,但是如果下降,那么可能是因?yàn)闆](méi)有Trace關(guān)聯(lián)。所以對(duì)于Rate類指標(biāo),只能關(guān)注上升的情況。
在實(shí)際操作中,發(fā)現(xiàn)研發(fā)同學(xué)非常喜歡使用這個(gè)功能,因?yàn)榇蠹抑灰訄?bào)警就能找到問(wèn)題的Trace。以前要找這個(gè)問(wèn)題的Trace就需要在日志和代碼中反復(fù)查找,非常費(fèi)勁。而有了這個(gè)功能,他們只需要設(shè)置一個(gè)報(bào)警,只要出現(xiàn)問(wèn)題,他們就能找到對(duì)應(yīng)的Trace,這大大節(jié)省了排查問(wèn)題的時(shí)間。
3.3 Trace作為基礎(chǔ)底座如何應(yīng)用
作為一個(gè)基礎(chǔ)功能,Trace在很多公司都有廣泛的應(yīng)用,可以在其基礎(chǔ)上進(jìn)行許多工作?;赥race的高連通性,通過(guò)上下文傳遞來(lái)降低整個(gè)調(diào)用量。例如,在用戶中心的接口中,調(diào)用量通常非常大。如果不合理在上下層或同級(jí)之間進(jìn)行多次調(diào)用,用戶中心的調(diào)用量就會(huì)指數(shù)級(jí)增加。
如果能夠獲取Trace的上下文,那么在短時(shí)間內(nèi),一個(gè)Trace內(nèi)的用戶數(shù)據(jù)的變化可能非常小。絕大部分?jǐn)?shù)據(jù)是固定的,例如User ID。通過(guò)傳遞Trace的上下文,可以指數(shù)級(jí)別降低其調(diào)用量。在一個(gè)Trace內(nèi),調(diào)用次數(shù)可以被限制在幾百次以內(nèi)。如果通過(guò)上下文傳遞,只需要調(diào)用一次就夠了。這種優(yōu)化的方法在實(shí)際應(yīng)用中是可行的,還可以結(jié)合其他的技術(shù),比如將大量訪問(wèn)頻繁的數(shù)據(jù)存儲(chǔ)在緩存中,以降低信息在傳輸層的大小。
另外,Trace的高連通性對(duì)于混沌工程和全鏈路壓力測(cè)試非常重要。全鏈路壓力測(cè)試是基于Trace的連通性的。在進(jìn)行灰度環(huán)境的壓力測(cè)試時(shí),不允許將整個(gè)壓力施加到線上,以免造成故障。如何確保只在灰度鏈路內(nèi)進(jìn)行測(cè)試而不影響線上環(huán)境?這就是基于Trace的高連通性。高連通性意味著的鏈路拓?fù)鋺?yīng)該是一個(gè)全連通集的子集,不允許出現(xiàn)調(diào)用跳轉(zhuǎn)到線上的情況,如果出現(xiàn)則表明壓力測(cè)試的拓?fù)涫怯袉?wèn)題,需要終止。
此外,如果出現(xiàn)無(wú)法覆蓋整個(gè)Trace的情況,可以在網(wǎng)絡(luò)層面進(jìn)行攔截。在整個(gè)網(wǎng)絡(luò)拓?fù)渲?,不允許請(qǐng)求外部的線上機(jī)器或服務(wù)。如果有請(qǐng)求到線上機(jī)器或服務(wù)的情況,可以進(jìn)行攔截,終止壓力測(cè)試。
3.4 Trace數(shù)據(jù)有哪些價(jià)值
基于Trace的連通性,通過(guò)分析Trace數(shù)據(jù),可以了解整個(gè)鏈路的性能瓶頸和熱點(diǎn),從而給業(yè)務(wù)線提出優(yōu)化建議。
基于超時(shí)時(shí)間的鏈路拓?fù)浞治?,發(fā)現(xiàn)配置不合理的點(diǎn),是否有環(huán)裝調(diào)用 在分布式服務(wù)中,通常使用RPC框架(如Double或GRPC)進(jìn)行通信。在早期,這些框架需要手動(dòng)配置節(jié)點(diǎn)的超時(shí)時(shí)間。例如,上游的超時(shí)配置為1秒,下游的超時(shí)配置為3秒,這是一個(gè)不合理的配置,因?yàn)樯嫌我呀?jīng)在1秒之后超時(shí)了,下游的超時(shí)時(shí)間設(shè)置并沒(méi)有意義。這種不合理的配置可能出現(xiàn)在分布式系統(tǒng)中的許多節(jié)點(diǎn)中,難以尋找和識(shí)別。
通過(guò)分析每個(gè)請(qǐng)求的耗時(shí)數(shù)據(jù),可以將RPC框架的超時(shí)時(shí)間拿出來(lái),并對(duì)上下游配置進(jìn)行分析,從而發(fā)現(xiàn)不合理的配置。這樣,可以確定哪些超時(shí)配置是不合理的,以前很難解決的問(wèn)題現(xiàn)在可以通過(guò)鏈路分析發(fā)現(xiàn)。一旦我們找到這些點(diǎn),可以避免由于超時(shí)配置不合理導(dǎo)致的故障。
基于請(qǐng)求耗時(shí)占比,分析性能瓶頸 通常情況下,某個(gè)請(qǐng)求中會(huì)有一個(gè)或多個(gè)函數(shù)的耗時(shí)占比非常高。
通過(guò)觀察圖中的Span ID,某個(gè)請(qǐng)求的耗時(shí)占比超過(guò)了48%。如果某個(gè)函數(shù)的耗時(shí)占比過(guò)大,這可能是由于它本身的執(zhí)行速度較慢,或者它的實(shí)現(xiàn)方式存在問(wèn)題。這個(gè)函數(shù)可能成為整個(gè)鏈路的瓶頸,影響整體性能。在這種情況下,可以考慮將該函數(shù)改為異步操作,或者拆分為并行的請(qǐng)求,以幫助業(yè)務(wù)線提高性能。
基于同層并發(fā)請(qǐng)求重復(fù)次數(shù)占比,分析代碼不合理調(diào)用。 有時(shí)候我們會(huì)在同層中重復(fù)調(diào)用某個(gè)接口,例如在某個(gè)地方調(diào)用了應(yīng)用中心,又在另一個(gè)地方調(diào)用了應(yīng)用中心,然后在下一層又調(diào)用了應(yīng)用中心,這種重復(fù)調(diào)用是完全不合理的。
在同層的情況下,這樣的調(diào)用可能會(huì)達(dá)到幾十次甚至上百次,這顯然是沒(méi)有必要的??赡苡行┩瑢W(xué)會(huì)說(shuō),只是把編寫好的代碼復(fù)制粘貼過(guò)來(lái),沒(méi)有去分析它的邏輯,長(zhǎng)此以往,這些重復(fù)調(diào)用會(huì)導(dǎo)致系統(tǒng)性能下降。
這些是我簡(jiǎn)單列舉的一些Trace數(shù)據(jù)有價(jià)值的點(diǎn),在實(shí)際過(guò)程中,它的應(yīng)用價(jià)值遠(yuǎn)不止這些。也歡迎大家開(kāi)放探討和交流。
四、總結(jié)展望
在構(gòu)建整個(gè)APM體系過(guò)程中,三個(gè)主要組件:日志收集組件、傳輸鏈路治理以及Flink任務(wù)性能優(yōu)化。日志收集組件和傳輸鏈路治理主要解決日志大流量和并發(fā)的問(wèn)題。在日志組件中,關(guān)注內(nèi)部和外部?jī)?nèi)存的限制。在傳輸層,關(guān)注任務(wù)調(diào)度和集群性能優(yōu)化。
最后,分析了APM系統(tǒng)的價(jià)值和意義。每家企業(yè)都建設(shè)自己的APM系統(tǒng),同時(shí)更需要深入挖掘其價(jià)值。APM系統(tǒng)的真正意義在于能夠通過(guò)數(shù)據(jù)客觀深入了解系統(tǒng)的性能。通過(guò)APM系統(tǒng),可以優(yōu)化系統(tǒng)的性能、提高用戶體驗(yàn)、減少故障和降低潛在風(fēng)險(xiǎn)。
Q&A
1、直播遷移到Docker 和使用CGroup 技術(shù)的成本怎么評(píng)估的?
2、如何及時(shí)發(fā)現(xiàn)未被監(jiān)控的指標(biāo)項(xiàng),避免未被觀測(cè)的指標(biāo)突變引發(fā)故障?
3、接口偶發(fā)性超時(shí),調(diào)用鏈只能看到超時(shí)接口名稱,看不到內(nèi)部方法,無(wú)法定位根因,也難以復(fù)現(xiàn),怎么辦?
以上問(wèn)題答案,歡迎點(diǎn)擊“閱讀全文”,觀看完整版解答!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-743162.html
本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-743162.html
到了這里,關(guān)于APM建設(shè)踩了哪些坑?去哪兒旅行分布式鏈路追蹤系統(tǒng)實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!