阿里妹導(dǎo)讀:來(lái)自阿里云RDS團(tuán)隊(duì)的論文“TcpRT: Instrument and Diagnostic Analysis System for Service Quality of Cloud Databases at Massive Scale in Real-time” (TcpRT:面向大規(guī)模海量云數(shù)據(jù)庫(kù)的服務(wù)質(zhì)量實(shí)時(shí)采集與診斷系統(tǒng))被數(shù)據(jù)庫(kù)頂會(huì)SIGMOD 2018接收,會(huì)議將于6/10在美國(guó)休斯敦召開(kāi)。
TcpRT論文介紹了RDS天象系統(tǒng)在云數(shù)據(jù)庫(kù)SLA數(shù)據(jù)采集、服務(wù)質(zhì)量指標(biāo)計(jì)算、異常檢測(cè)、故障根因分析領(lǐng)域的創(chuàng)新工作,以及大規(guī)模部署自動(dòng)化的服務(wù)各類(lèi)云上客戶(hù)的實(shí)踐經(jīng)驗(yàn)。評(píng)委評(píng)價(jià)“I have plenty of experience with manual anomaly detection. That has wasted much time for me at work, so I liked what you described.”
簡(jiǎn)介
隨著企業(yè)上云趨勢(shì)的日益熱化,作為產(chǎn)業(yè)核心組件的數(shù)據(jù)庫(kù),已成為各大云計(jì)算公司增長(zhǎng)最快的在線(xiàn)服務(wù)業(yè)務(wù)。作為中國(guó)第一大云數(shù)據(jù)庫(kù)廠商,我們RDS團(tuán)隊(duì)致力于為用戶(hù)提供穩(wěn)定的云數(shù)據(jù)庫(kù)服務(wù)。從本質(zhì)上看,RDS是一個(gè)多租戶(hù)DBaaS平臺(tái),利用輕量級(jí)KVM、Docker鏡像等資源隔離技術(shù)將用戶(hù)所購(gòu)買(mǎi)的數(shù)據(jù)庫(kù)實(shí)例部署在物理機(jī)上,按需分配資源并進(jìn)行自動(dòng)升降級(jí),實(shí)現(xiàn)一套完全自動(dòng)化的智能運(yùn)維管理。
云數(shù)據(jù)庫(kù)對(duì)客戶(hù)業(yè)務(wù)的穩(wěn)定性至關(guān)重要,因此快速發(fā)現(xiàn)云數(shù)據(jù)庫(kù)性能出現(xiàn)異常,及時(shí)定位異常原因是云數(shù)據(jù)庫(kù)廠商的一個(gè)挑戰(zhàn)。TcpRT是阿里云數(shù)據(jù)庫(kù)用來(lái)監(jiān)控和診斷數(shù)據(jù)庫(kù)服務(wù)質(zhì)量的一個(gè)基礎(chǔ)設(shè)施。TcpRT從主機(jī)TCP/IP協(xié)議棧的壅塞控制采集trace數(shù)據(jù),計(jì)算數(shù)據(jù)庫(kù)延遲和網(wǎng)絡(luò)異常,在后臺(tái)流式計(jì)算平臺(tái)進(jìn)行大規(guī)模實(shí)時(shí)數(shù)據(jù)分析和聚合,通過(guò)統(tǒng)計(jì)指標(biāo)歷史數(shù)據(jù)的柯西分布發(fā)現(xiàn)異常點(diǎn),并通過(guò)同一臺(tái)主機(jī)、交換機(jī)、proxy下所有實(shí)例一致性趨勢(shì)的比例來(lái)計(jì)算不同組件發(fā)生異常的概率。
到目前為止,TcpRT以每秒采集2千萬(wàn)條原始trace數(shù)據(jù)、每天后臺(tái)處理百億吞吐數(shù)據(jù)、秒級(jí)檢測(cè)異常的卓越性能在阿里云持續(xù)穩(wěn)定運(yùn)行三年。
本文貢獻(xiàn):
提出了一種新的對(duì)數(shù)據(jù)庫(kù)服務(wù)質(zhì)量進(jìn)行采集的方法,基于內(nèi)核壅塞模塊實(shí)現(xiàn),可以非侵入性、低代價(jià)的采集基于停等協(xié)議的關(guān)系數(shù)據(jù)庫(kù)的per connection的延遲、帶寬,分析用戶(hù)使用數(shù)據(jù)庫(kù)的模型(短連接和長(zhǎng)連接),并且可以端到端的記錄和量化基礎(chǔ)網(wǎng)絡(luò)服務(wù)質(zhì)量對(duì)數(shù)據(jù)庫(kù)服務(wù)質(zhì)量的影響,包括丟包率、重傳率。
我們開(kāi)發(fā)了一套對(duì)采集的原始數(shù)據(jù)進(jìn)行數(shù)據(jù)清洗、過(guò)濾、聚合、分析的流式計(jì)算系統(tǒng),系統(tǒng)可以做到水平擴(kuò)展、容錯(cuò)性、實(shí)時(shí)性、Exactly Once,具有和其他大數(shù)據(jù)平臺(tái)例如EMR、MaxCompute進(jìn)行數(shù)據(jù)交換的能力。
我們提出了一個(gè)新的算法對(duì)TcpRT數(shù)據(jù)進(jìn)行分析,來(lái)發(fā)現(xiàn)數(shù)據(jù)庫(kù)的服務(wù)質(zhì)量有無(wú)異常,并且對(duì)異常事件的根因進(jìn)行定位。
問(wèn)題
從網(wǎng)絡(luò)架構(gòu)上看,RDS由控制層和數(shù)據(jù)鏈路層兩個(gè)部分組成,如上圖所示。其中,控制層包括一系列管理模塊,比如資源管理器,HA管理器,遷移管理器等。資源管理器負(fù)責(zé)將實(shí)例的不同副本分配在獨(dú)立的物理主機(jī)上。當(dāng)實(shí)例發(fā)生故障時(shí),HA管理器會(huì)探測(cè)到主實(shí)例的故障,并將服務(wù)連接切換到Standby節(jié)點(diǎn)上。而當(dāng)主機(jī)負(fù)載失衡時(shí),遷移管理器負(fù)責(zé)將數(shù)據(jù)庫(kù)實(shí)例進(jìn)行遷移,保障用戶(hù)服務(wù)質(zhì)量。
數(shù)據(jù)鏈路層主要負(fù)責(zé)數(shù)據(jù)的分發(fā)和路由。通常,云用戶(hù)通過(guò)ECS和RDS實(shí)現(xiàn)業(yè)務(wù)上云。他們將業(yè)務(wù)部署在ECS上,并通過(guò)VPC和RDS數(shù)據(jù)庫(kù)實(shí)例進(jìn)行交互。數(shù)據(jù)包通過(guò)駐留在用戶(hù)VPC網(wǎng)絡(luò)中的vSwitch進(jìn)行打包/解包并路由。而SLB負(fù)責(zé)將這些數(shù)據(jù)包進(jìn)行解析,并將DBaaS IP映射到真實(shí)服務(wù)器上。目前,SLB同時(shí)支持FNAT和DNAT兩種模式。由于出流量數(shù)據(jù)不經(jīng)過(guò)SLB, DNAT比FNAT呈現(xiàn)出更好的性能。除此之外,我們引入NGLB進(jìn)行優(yōu)化。在Proxy中,我們解析客戶(hù)端/服務(wù)端協(xié)議,并提取查詢(xún),將讀寫(xiě)進(jìn)行分離,同時(shí)支持橫向分區(qū)和連接池的功能。
作為客戶(hù)業(yè)務(wù)的核心組件,保障云數(shù)據(jù)庫(kù)7/24的穩(wěn)定至關(guān)重要。我們通過(guò)對(duì)用戶(hù)承諾數(shù)據(jù)庫(kù)SLA服務(wù)等級(jí)協(xié)議,來(lái)保障用戶(hù)的權(quán)益。然而,云數(shù)據(jù)庫(kù)的服務(wù)質(zhì)量受各種因素影響,例如突發(fā)性連接斷開(kāi)、數(shù)據(jù)庫(kù)延遲發(fā)生抖動(dòng)、吞吐驟然下降等,都有可能帶來(lái)用戶(hù)業(yè)務(wù)指標(biāo)的下降。因此,快速發(fā)現(xiàn)云數(shù)據(jù)庫(kù)性能異常,及時(shí)定位根因是云數(shù)據(jù)庫(kù)廠商的一個(gè)挑戰(zhàn)。
可能造成云數(shù)據(jù)庫(kù)的服務(wù)質(zhì)量下降的原因很多,例如網(wǎng)絡(luò)上的異常,比如DB主機(jī)的上聯(lián)交換機(jī)tor發(fā)生丟包,或者load balaner出現(xiàn)TCP incast問(wèn)題;或者用戶(hù)側(cè)的問(wèn)題,用戶(hù)端網(wǎng)絡(luò)異?;蛘邅G包;或者多租戶(hù)機(jī)制,DB主機(jī)內(nèi)核缺陷、硬件上SSD的硬件異常等等都會(huì)引起。在出現(xiàn)問(wèn)題時(shí),快速診斷定位解決問(wèn)題是關(guān)鍵的問(wèn)題。
傳統(tǒng)數(shù)據(jù)庫(kù)性能采集只需要采集DBMS內(nèi)部處理SQL請(qǐng)求的延遲就夠了,但云數(shù)據(jù)庫(kù)需要end-end數(shù)據(jù)。因?yàn)閷?duì)云上用戶(hù)而言,他看到的云數(shù)據(jù)庫(kù)的延遲是終端的延遲。真實(shí)的場(chǎng)景對(duì)trace工具提出這些需求,因此很關(guān)鍵的是要采集end-to-end數(shù)據(jù),以及鏈路每段的延遲,終端用戶(hù)感受到的延遲是所有路徑上每個(gè)節(jié)點(diǎn)處理延遲以及網(wǎng)絡(luò)上所有延遲的總和,不僅僅要采集DB上的延遲,還要采集proxy上看到的延遲。這需要在鏈路上引入trace。還要采集網(wǎng)絡(luò)上的數(shù)據(jù),主機(jī)上其實(shí)可以看到的上行亂序和下行的重傳,這個(gè)信息對(duì)推測(cè)網(wǎng)絡(luò)有無(wú)異常非常重要。發(fā)送和接收會(huì)走不同的網(wǎng)絡(luò)路徑。
傳統(tǒng)的trace手段需要入侵式地在業(yè)務(wù)代碼中添加埋點(diǎn)。第一,我們不能在客戶(hù)端埋點(diǎn),因?yàn)榭蛻?hù)基本上都使用標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)客戶(hù)端來(lái)訪問(wèn),沒(méi)有嵌入打點(diǎn)代碼,我們也不能期望客戶(hù)會(huì)修改自己的業(yè)務(wù)代碼,加入打點(diǎn)邏輯,并將打點(diǎn)數(shù)據(jù)采集交給我們。因此我們需要一種非侵入式的方法來(lái)獲取end-to-end性能數(shù)據(jù)。第二在服務(wù)器端埋點(diǎn)也有問(wèn)題,應(yīng)用層無(wú)法感知真正的數(shù)據(jù)接收和發(fā)送時(shí)間。應(yīng)用層記錄的時(shí)間是內(nèi)核把數(shù)據(jù)交付給應(yīng)用層和應(yīng)用層把數(shù)據(jù)交付給內(nèi)核的時(shí)間。在系統(tǒng)負(fù)載很高,應(yīng)用層進(jìn)程調(diào)度需要花費(fèi)大量時(shí)間的場(chǎng)景下,會(huì)導(dǎo)致請(qǐng)求的實(shí)際處理時(shí)間計(jì)算不準(zhǔn)確;應(yīng)用層無(wú)法感知到網(wǎng)絡(luò)鏈路質(zhì)量。在網(wǎng)絡(luò)出現(xiàn)擁塞,大量的重傳報(bào)文,導(dǎo)致數(shù)據(jù)發(fā)送和接收過(guò)程大大延長(zhǎng),無(wú)法區(qū)分出是對(duì)端響應(yīng)緩慢還是網(wǎng)絡(luò)鏈路質(zhì)量不佳。
在這種挑戰(zhàn)下,TcpRT——阿里云數(shù)據(jù)庫(kù)監(jiān)控和診斷服務(wù)質(zhì)量系統(tǒng),孕育而生。
TcpRT從主機(jī)TCP/IP協(xié)議棧的擁塞控制采集trace數(shù)據(jù),用于監(jiān)測(cè)數(shù)據(jù)庫(kù)延遲和網(wǎng)絡(luò)異常,并利用先進(jìn)的流技術(shù),在后臺(tái)實(shí)時(shí)計(jì)算平臺(tái)上進(jìn)行大規(guī)模在線(xiàn)數(shù)據(jù)分析,結(jié)合離線(xiàn)模型,通過(guò)實(shí)時(shí)異常事件判定,以及RDS網(wǎng)絡(luò)關(guān)系圖譜中的趨勢(shì)一致性概率探測(cè),快速診斷出性能異常并定位原因。
架構(gòu)
上圖是TcpRT的概要架構(gòu)圖,其中包含以下個(gè)組件:
內(nèi)核模塊——用于采集指標(biāo)trace數(shù)據(jù),包括查詢(xún)延遲、Proxy節(jié)點(diǎn)和DB節(jié)點(diǎn)的連接指標(biāo)等
本地聚合器——負(fù)責(zé)將內(nèi)核模塊采集的trace數(shù)據(jù)進(jìn)行本地聚合處理,推送至Kafka消息隊(duì)列
流式ETL——利用流技術(shù),在后臺(tái)流式計(jì)算平臺(tái)上將Kafka中的時(shí)序指標(biāo)數(shù)據(jù)進(jìn)行清洗、多粒度聚合及在線(xiàn)分析,利用冷熱技術(shù)將數(shù)據(jù)分離
在線(xiàn)異常監(jiān)測(cè)——根據(jù)時(shí)序指標(biāo)數(shù)據(jù),擬合異常模型,通過(guò)實(shí)時(shí)異常事件判定,以及RDS網(wǎng)絡(luò)關(guān)系圖譜中的趨勢(shì)一致性概率探測(cè),快速診斷出性能異常并定位原因
TcpRT內(nèi)核模塊
內(nèi)核模塊主要負(fù)責(zé)對(duì)網(wǎng)絡(luò)數(shù)據(jù)的傳輸進(jìn)行整個(gè)生命周期的監(jiān)控。在遵守停等協(xié)議的TCP通信機(jī)制下,服務(wù)端處理每個(gè)請(qǐng)求的過(guò)程分成3個(gè)階段,接收階段(Receive)、處理階段(Handle)和響應(yīng)階段(Response)。如下圖所示:
鑒于此,我們需要計(jì)算如下時(shí)間:
上行時(shí)間 = T1 - T0
處理時(shí)間 = T2 - T1
下行時(shí)間 = T3 - T2
查詢(xún)時(shí)間 = T3 - T0
RTT時(shí)間 = T2 - T2'
現(xiàn)有的監(jiān)控方案,通常在業(yè)務(wù)層面埋點(diǎn)進(jìn)行服務(wù)耗時(shí)監(jiān)控,但此方法既不能獲得真正的數(shù)據(jù)接收和發(fā)送時(shí)間、也無(wú)法感知到網(wǎng)絡(luò)鏈路的質(zhì)量,更需要在業(yè)務(wù)代碼中入侵式地添加埋點(diǎn)。因此,我們實(shí)現(xiàn)了一種通用、低開(kāi)銷(xiāo)的內(nèi)核模塊進(jìn)行trace監(jiān)控以得到上述時(shí)間。
首先,我們選擇修改Linux內(nèi)核的擁塞控制算法。此算法可以感知內(nèi)核發(fā)送報(bào)文的上下文,并且支持熱更新(只需增加一個(gè)驅(qū)動(dòng)模塊而無(wú)需更新線(xiàn)上內(nèi)核)。
此外,擁塞控制算法提供了以下機(jī)制:
1. 每個(gè)TCP通信是獨(dú)立的擁塞控制算法,不存在資源競(jìng)爭(zhēng)情況
2. 可以感知到收到的每個(gè)ACK報(bào)文的上下文
3. 在已經(jīng)發(fā)送的報(bào)文都已經(jīng)被ACK的情況下,可以感知到當(dāng)前發(fā)送的報(bào)文上下文
根據(jù)擁塞控制算法提供的事件回調(diào),我們可以獲取到每個(gè)TCP連接下述事件:
1. 客戶(hù)端發(fā)送給服務(wù)端ACK報(bào)文
2. 在所有已經(jīng)發(fā)出去的sequence都被確認(rèn)的情況下,服務(wù)端發(fā)送報(bào)文
3. TCP連接建立
4. TCP連接斷開(kāi)
內(nèi)核任何線(xiàn)程都可能調(diào)用到擁塞控制算法,因此為了性能,擁塞控制算法必須保證是沒(méi)有數(shù)據(jù)爭(zhēng)搶的。TcpRT內(nèi)核模塊保證了以下四點(diǎn):
1. TcpRT所有的數(shù)據(jù)保存在每個(gè)TCP連接對(duì)象上,所有的數(shù)據(jù)讀寫(xiě)都沒(méi)有跨TCP連接的共享;
2. TcpRT在每個(gè)CPU core都有獨(dú)立的寫(xiě)緩沖區(qū),防止了多個(gè)內(nèi)核線(xiàn)程爭(zhēng)搶寫(xiě)緩沖區(qū)加鎖;
3. 為了避免內(nèi)存開(kāi)銷(xiāo),又保證實(shí)時(shí)性,TcpRT的寫(xiě)緩沖區(qū)會(huì)在buffer滿(mǎn)或者時(shí)間到的情況下,刷新寫(xiě)緩沖區(qū)到debugfs,供應(yīng)用層采集端采集。由于寫(xiě)debugfs的頻率很低,debugfs的鎖爭(zhēng)搶幾乎不存在,最大限度保證了性能;
4. TcpRT回寫(xiě)的數(shù)據(jù),是binary格式的,對(duì)比需要format的字符格式,在實(shí)測(cè)場(chǎng)景可以提高20%的性能。
此外,通過(guò)給linux內(nèi)核添加setsockopt選項(xiàng),通知內(nèi)核一個(gè)不需要應(yīng)答的請(qǐng)求交互過(guò)程已經(jīng)結(jié)束,從而支持非停等協(xié)議。
針對(duì)TcpRT內(nèi)核模塊對(duì)用戶(hù)數(shù)據(jù)庫(kù)實(shí)例的性能影響,我們基于sysbench模擬了MySQL 400個(gè)客戶(hù)端連接進(jìn)行壓測(cè),結(jié)果如下圖所示,TcpRT內(nèi)核模塊對(duì)系統(tǒng)的負(fù)載影響不到1%。
TcpRT內(nèi)核模塊,利用debugfs和用戶(hù)態(tài)通信。每秒以千萬(wàn)的trace數(shù)據(jù)高速產(chǎn)出并吐入至debugfs中。為了減輕后臺(tái)在線(xiàn)分析任務(wù)的壓力,我們構(gòu)建本地TcpRT聚合器,實(shí)現(xiàn)本地trace秒級(jí)聚合,并將聚合結(jié)果輸出到/dev/shm中。Logagent從中讀取聚合數(shù)據(jù),發(fā)送至Kafka,并由后臺(tái)ETL接手,進(jìn)行實(shí)時(shí)數(shù)據(jù)分析,流程如下圖所示:
在本地聚合器中,聚合操作需要保證可交換且可結(jié)合,我們采用均值、最大值、請(qǐng)求個(gè)數(shù)的三元組聚合方法來(lái)保證延遲時(shí)間類(lèi)指標(biāo)滿(mǎn)足這一要求。此外,我們采用每秒同客戶(hù)端出現(xiàn)的不同端口數(shù)對(duì)活躍連接數(shù)進(jìn)行指標(biāo)特征提取。同時(shí),抽取請(qǐng)求數(shù)作為特征,建立用戶(hù)長(zhǎng)短連接的使用模型,進(jìn)而對(duì)用戶(hù)使用數(shù)據(jù)庫(kù)實(shí)例的負(fù)載模式進(jìn)行分析。根據(jù)歷史數(shù)據(jù),當(dāng)前仍有眾多用戶(hù)采用短連接模式,這對(duì)于諸如MySQL線(xiàn)程網(wǎng)絡(luò)模型的DB是非常不友好的,從而激發(fā)我們提供Proxy中間件將短連接轉(zhuǎn)換為長(zhǎng)連接服務(wù)。
為了最大化聚合效果,我們?cè)趦?nèi)存中維護(hù)最近5s的聚合結(jié)果,將5s前的數(shù)據(jù)輸出到/dev/shm的文件中。且為了提高查詢(xún)性能以及長(zhǎng)時(shí)間段的聚合操作,我們將三種粒度1s, 5s, 1m的聚合結(jié)果存入到庫(kù)中。
TcpRT ETL
下圖描繪了ETL任務(wù)的拓?fù)浣Y(jié)構(gòu):
在線(xiàn)ETL任務(wù)主要包括四個(gè)子任務(wù):
數(shù)據(jù)轉(zhuǎn)換
數(shù)據(jù)關(guān)聯(lián)與聚合
數(shù)據(jù)存儲(chǔ)
以及延遲和亂序處理
其中,延遲和亂序到達(dá)的處理是一個(gè)難點(diǎn)。TcpRT輸出的時(shí)序數(shù)據(jù)是以SQL執(zhí)行結(jié)束時(shí)間為時(shí)間戳,如何做到實(shí)時(shí)準(zhǔn)確地對(duì)窗口內(nèi)的時(shí)序數(shù)據(jù)進(jìn)行聚合并將結(jié)果刷出是一個(gè)兩難的問(wèn)題。我們采用了“盡力聚合”的方法,即對(duì)窗口設(shè)定等待時(shí)間,待時(shí)間結(jié)束后將實(shí)時(shí)聚合結(jié)果刷出,若此后,還有該窗口的時(shí)序數(shù)據(jù)到來(lái),則直接落入到數(shù)據(jù)庫(kù)中。如TcpRT聚合器中所述,所有聚合數(shù)據(jù)具有可再結(jié)合特性,這樣,我們可以對(duì)同時(shí)刻的聚合數(shù)據(jù)進(jìn)行二次聚合。
組件的異常往往伴隨著相關(guān)指標(biāo)的抖動(dòng)。比如主機(jī)發(fā)生IO Hang后,load、dirty、writeback、某些core的iowait、被阻塞的線(xiàn)程數(shù)等指標(biāo)會(huì)明顯升高,而各實(shí)例的write,CPU使用率會(huì)明顯變低,主機(jī)維度的PT指標(biāo)會(huì)明顯升高。在部分情況下,連接數(shù)會(huì)上升,長(zhǎng)連接請(qǐng)求數(shù)會(huì)下降,流量會(huì)下降等。在Proxy發(fā)生異常的時(shí)候,PT可能會(huì)升高、CPU、流量、連接數(shù)均可能會(huì)下降。
傳統(tǒng)方法下,我們通過(guò)設(shè)定閾值進(jìn)行指標(biāo)抖動(dòng)的檢測(cè)。然而閾值的設(shè)定強(qiáng)依賴(lài)于專(zhuān)家經(jīng)驗(yàn),維護(hù)成本高,且一刀切的設(shè)定常常會(huì)“誤傷”健康指標(biāo)。比如,有些數(shù)據(jù)庫(kù)實(shí)例是專(zhuān)門(mén)用于OLAP,它們的SQL請(qǐng)求處理時(shí)間往往都是秒級(jí)的,若采用常用的SQL請(qǐng)求處理時(shí)間作為異常判定閾值,此類(lèi)數(shù)據(jù)庫(kù)實(shí)例就會(huì)觸發(fā)報(bào)警。
鑒于此,我們需要一種通用且自適應(yīng)的智能模型來(lái)解決云數(shù)據(jù)庫(kù)的異常監(jiān)測(cè)。
為了避免人工設(shè)定閾值,我們一開(kāi)始嘗試?yán)胏ontrol charts來(lái)進(jìn)行判斷,根據(jù)樣本時(shí)間段的均值和標(biāo)準(zhǔn)差,預(yù)測(cè)未來(lái)時(shí)間段的置信區(qū)間。若實(shí)際值超出置信區(qū)間,則判定為異常。然而,若樣本本身為異常,則此時(shí)間段的參數(shù)均不可信。
如上圖,左上圖為(ins1,*,db1)的upsize指標(biāo)時(shí)序圖,可以看到(ins1,*,db1)的upsize指標(biāo)會(huì)有周期性的波動(dòng)。左下的兩張圖分別是歷史時(shí)間窗口設(shè)定值為30min的(ins1,*,db1)的upsize指標(biāo)mean&median時(shí)序圖和SD&MAD時(shí)序圖。可以清楚看到,當(dāng)upsize指標(biāo)發(fā)生波動(dòng)后,mean值和標(biāo)準(zhǔn)差SD值都會(huì)發(fā)生窗口時(shí)間長(zhǎng)度的跳變,但median和MAD卻幾乎不受指標(biāo)波動(dòng)的影響,顯得更平穩(wěn)、絲滑。
右上圖為(ins2,*,db2)的newConn指標(biāo)時(shí)序圖,可以看到在03:40~04:00期間,指標(biāo)發(fā)生異常,出現(xiàn)大量極端值,由于歷史的時(shí)間窗口設(shè)定值為30min,所以可以從左下的圖表中看到,很長(zhǎng)一段時(shí)間內(nèi)樣本的均值和標(biāo)準(zhǔn)差便會(huì)發(fā)生較大的波動(dòng),而中位數(shù)和MAD指標(biāo)卻顯得平滑,對(duì)極端值并不敏感,展出超強(qiáng)的魯棒性。由于依賴(lài)均值和標(biāo)準(zhǔn)差進(jìn)行預(yù)測(cè),control charts具有不穩(wěn)定性,易造成誤判。這啟發(fā)我們利用中位數(shù)和MAD替代均值和標(biāo)準(zhǔn)差作為預(yù)測(cè)模型參數(shù)。
如上圖所示,通過(guò)大量觀察,我們發(fā)現(xiàn),按(*,*,db) 和(*,*,proxy) 粒度聚合后的采樣點(diǎn)集合近似正態(tài)分布。但是,正態(tài)分布依賴(lài)平均值和標(biāo)準(zhǔn)差作為參數(shù),如上文所述,這兩個(gè)參數(shù)波動(dòng)大,會(huì)造成嚴(yán)重誤判。鑒于柯西分布與正態(tài)分布相似,且不依賴(lài)均值和標(biāo)準(zhǔn)差,可以使用中位數(shù)和MAD這種穩(wěn)定的統(tǒng)計(jì)指標(biāo)來(lái)進(jìn)行回歸。從上上圖可以看到當(dāng)歷史時(shí)間窗口長(zhǎng)度設(shè)定合適的時(shí)候,中位數(shù)和MAD在面對(duì)指標(biāo)波動(dòng)和異常的情況下,顯得平滑且穩(wěn)定,這樣回歸出的模型具有更強(qiáng)的穩(wěn)定性。于是,我們使用中位數(shù)和MAD作為參數(shù)的回歸柯西分布來(lái)擬合異常診斷模型。
為了獲取回歸需要的樣本集,我們通過(guò)對(duì)過(guò)去一段時(shí)間(比如:最近一個(gè)小時(shí))的每一個(gè)時(shí)間點(diǎn)做采樣,得到一段歷史窗口的數(shù)據(jù)點(diǎn)集合S{x0,x1,x2,……}。根據(jù)歷史窗口數(shù)據(jù)集,計(jì)算中位數(shù)M以及MAD,回歸出這個(gè)數(shù)據(jù)集的柯西概率分布D。
主機(jī)異常檢測(cè)
RDS主機(jī)上承載著眾多實(shí)例,各實(shí)例通常隸屬于不同用戶(hù)的不同業(yè)務(wù)。在主機(jī)正常工作時(shí),由于實(shí)例相互獨(dú)立、并且對(duì)應(yīng)的指標(biāo)波動(dòng)具有不確定性,所有實(shí)例呈現(xiàn)出一致性升高或降低的概率非常小。當(dāng)主機(jī)發(fā)生異常時(shí),由于該主機(jī)上的所有實(shí)例共享同一資源,某些關(guān)鍵指標(biāo)會(huì)呈現(xiàn)出一致性趨勢(shì)。當(dāng)一臺(tái)主機(jī)發(fā)生了IO Hang,主機(jī)上大部分實(shí)例的SQL處理延遲都呈現(xiàn)出升高的趨勢(shì),各實(shí)例的數(shù)據(jù)寫(xiě)入量呈現(xiàn)出下降的趨勢(shì)。這啟發(fā)我們利用實(shí)例趨勢(shì)一致性概率來(lái)判斷主機(jī)的異常。
首先,設(shè)定函數(shù)H(curentVal, prevMideanVal,metricType)作為判斷指標(biāo)metric1是否異常的函數(shù),取值只能是-1,0,+1。currentVal代表這一刻該指標(biāo)的值,prevMideanVal代表過(guò)去一段時(shí)間(比如:1小時(shí))采樣點(diǎn)集合的中位數(shù),metricType代表該指標(biāo)的類(lèi)型(比如:rt,rtt,qps,流量等)。取值為-1代表這個(gè)指標(biāo)在跟過(guò)去一段時(shí)間指標(biāo)做對(duì)比的時(shí)候呈現(xiàn)出明顯下降的趨勢(shì),0代表這個(gè)指標(biāo)沒(méi)有明顯波動(dòng),+1代表這個(gè)指標(biāo)與過(guò)去一段時(shí)間相比明顯上升。
我們可以利用上文的算法來(lái)實(shí)現(xiàn)函數(shù)H,這樣我們能算出(ins,*,dstIp,metricType)級(jí)別數(shù)據(jù)的函數(shù)H值,然后在按(ins,*,dstIp,metricType)->(*,*, dstIp,metricType)做map-reduce(agg類(lèi)型為sum)。算出的值s反映了這個(gè)指標(biāo)在這臺(tái)主機(jī)上的突升,突降的趨勢(shì),用求和值s除以這個(gè)主機(jī)上的活躍實(shí)例數(shù)t得出突升/突降實(shí)例比例r,當(dāng)r大于0是,總體趨勢(shì)上升,當(dāng)r小于0是,總體趨勢(shì)下降,且絕對(duì)值越大概率越大。
那么我們?nèi)绾卫胷值來(lái)判斷主機(jī)異常呢?如果機(jī)器突然由正常變?yōu)楫惓r(shí),各實(shí)例由于都依賴(lài)這臺(tái)機(jī)器的資源進(jìn)行工作,或多或少要受其影響,因此相關(guān)指標(biāo)發(fā)生突變的實(shí)例比例將會(huì)發(fā)生突變,比如主機(jī)上cpu資源突然不足,大部分實(shí)例都會(huì)受影響,他們的處理時(shí)間會(huì)突升,流量突降,請(qǐng)求數(shù)突降,因此可以通過(guò)判斷r值是否突變來(lái)判斷主機(jī)異常。
我們可以利用上文的算法來(lái)對(duì)r值的突變進(jìn)行判斷,對(duì)過(guò)去一段時(shí)間的每一個(gè)時(shí)間點(diǎn)都做這樣的計(jì)算,我們可以得到一段歷史窗口的突升/突降實(shí)例比例r行程的數(shù)據(jù)點(diǎn)集合S{R0,R1,R2,…}。根據(jù)歷史窗口數(shù)據(jù)集,我們算出數(shù)據(jù)集的中位數(shù)M,以及MAD值,回歸出這個(gè)數(shù)據(jù)集的柯西概率分布D。
因?yàn)楸壤齬的取值是-1~1,而柯西概率分布D的自變量x范圍是負(fù)無(wú)窮到正無(wú)窮。我們需要對(duì)原來(lái)的比率r做轉(zhuǎn)化讓他的范圍擴(kuò)充到正負(fù)無(wú)窮。通過(guò)定義的映射函數(shù)求出這一時(shí)刻下該指標(biāo)的柯西概率分布的CDF(),如果CDF()非常小,比如小于0.1%,主機(jī)hostA的指標(biāo)metric1呈現(xiàn)總體下降趨勢(shì),或者非常大比如99.8%, 主機(jī)hostA的指標(biāo)metric1呈現(xiàn)總體上升趨勢(shì)。 但是這樣做判斷,只是判斷出了r值的突升和突降,為了減少誤判,我們還要判斷出r值的突升和突降需要落到警戒范圍。因此需要一個(gè)必要條件:r值的絕對(duì)值至少為20%。
另外,當(dāng)r值足夠高時(shí),無(wú)論r值是否突升還是突降,都應(yīng)該認(rèn)為是異常,因此還需要一個(gè)充分條件:r值的絕對(duì)值大于AlarmRatio(主機(jī)上的活躍實(shí)例t),那么認(rèn)為是異常。根據(jù)我們自己的實(shí)際情況,AlarmRatio(t)=0.8*Pow(0.987, t) + 0.2. 曲線(xiàn)如圖,當(dāng)主機(jī)上的活躍實(shí)例比較少時(shí),AlarmRatio值比較高,這樣為了保證判斷出異常的主機(jī)上異常的實(shí)例足夠多,這樣才有較高的說(shuō)服力,而隨著主機(jī)上活躍實(shí)例數(shù)變多,AlarmRatio值會(huì)相應(yīng)得變小最后收斂到0.2,這樣為了不漏掉r比較少但是異常實(shí)例數(shù)足夠多的情況。
當(dāng)r=-1時(shí),這臺(tái)機(jī)器hostA上所有的實(shí)例的指標(biāo)metric1都出現(xiàn)了下降趨勢(shì),當(dāng)r=1時(shí),hostA上所有實(shí)例的指標(biāo)metric1都出現(xiàn)了上升趨勢(shì)。除了獨(dú)占實(shí)例,一臺(tái)主機(jī)上有數(shù)十甚至上百的實(shí)例,他們分屬不同的用戶(hù),運(yùn)行著不同的業(yè)務(wù),呈現(xiàn)出一致的趨勢(shì)概率很小,因此在正常的時(shí)候r值往往穩(wěn)定在一個(gè)較低的范圍內(nèi),當(dāng)r值很高的時(shí)候,極有可能主機(jī)問(wèn)題了。
但是這樣的判斷還不夠,因?yàn)檫€存在這兩種情況:1. 實(shí)例之間公用的某個(gè)組件出現(xiàn)了異常。比如網(wǎng)絡(luò)中間件引起的異常,路由器的異常等等。也會(huì)引起r值變高;2.有的主機(jī)上因?yàn)閷?shí)例數(shù)比較少(比如:小于3)時(shí),單純根據(jù)比例判斷還分辨不出是否是主機(jī)的問(wèn)題,因?yàn)闃颖緮?shù)太少,不具有說(shuō)服力。針對(duì)這兩種情況,我們還用了多種方法來(lái)提高準(zhǔn)確率,比如:
1.結(jié)合物理機(jī)的資源指標(biāo)(load,iowait,dirty,writeback等)的加權(quán)和來(lái)協(xié)助判斷。2.如果存在上游節(jié)點(diǎn)(比如:proxy),并且上游節(jié)點(diǎn)存在異常,則優(yōu)先報(bào)上游節(jié)點(diǎn)的異常。因?yàn)樯嫌喂?jié)點(diǎn)往往還連接多個(gè)下游節(jié)點(diǎn),如果是某個(gè)單獨(dú)的下游節(jié)點(diǎn)出現(xiàn)了異常,一般上游節(jié)點(diǎn)是不會(huì)出現(xiàn)異常的,因?yàn)樯嫌喂?jié)點(diǎn)上連接的下游節(jié)點(diǎn)很多,這一個(gè)點(diǎn)并不會(huì)明顯改變整體的指標(biāo)趨勢(shì)變化,而某個(gè)節(jié)點(diǎn)的多個(gè)下游節(jié)點(diǎn)都出了問(wèn)題,他們的上游節(jié)點(diǎn)出問(wèn)題的概率更大一些。假設(shè)上游節(jié)點(diǎn)完全正常,下游節(jié)點(diǎn)近似相互獨(dú)立,一個(gè)節(jié)點(diǎn)出問(wèn)題的概率為p,K各節(jié)點(diǎn)同時(shí)出問(wèn)題的概率就是p^K,所以問(wèn)題的原因很可能是概率更大的上游節(jié)點(diǎn)。
Proxy異常檢測(cè)
我們的大部分實(shí)例在訪問(wèn)db前要經(jīng)過(guò)proxy的轉(zhuǎn)發(fā),proxy可以幫用戶(hù)做短鏈接優(yōu)化,負(fù)載均衡,連接審計(jì),注入檢測(cè)等。proxy是我們生產(chǎn)集群非常重要的組件,一個(gè)proxy節(jié)點(diǎn)最多會(huì)有上千個(gè)實(shí)例的請(qǐng)求(requests of thousands of instances)經(jīng)過(guò)。也就是說(shuō),如果一個(gè)proxy節(jié)點(diǎn)發(fā)生了故障,將會(huì)影響到上千個(gè)實(shí)例,這樣的故障我們需要快速準(zhǔn)確地發(fā)現(xiàn)并定位出來(lái),否則后果不敢想象。
我們一開(kāi)始對(duì)proxy的qps,連接數(shù)等設(shè)定閾值的方式來(lái)進(jìn)行報(bào)警,但是由于不同分組的proxy業(yè)務(wù)量大小不一樣,因此我們需要對(duì)不同分組設(shè)定不同的閾值,而且我們的業(yè)務(wù)增長(zhǎng)迅速,proxy會(huì)經(jīng)常進(jìn)行擴(kuò)容,這樣閾值又要重新調(diào)整,維護(hù)起來(lái)費(fèi)時(shí)費(fèi)力。
我們雖然可以利用上邊所講的判斷db主機(jī)異常一樣的算法來(lái)判斷proxy異常,但是由于proxy的處理時(shí)間包含了db本地的處理時(shí)間,應(yīng)用這種方式我們是無(wú)法評(píng)估出請(qǐng)求在單純?cè)趐roxy中停留的時(shí)間。對(duì)于使用了proxy鏈路的用戶(hù),由于在網(wǎng)絡(luò)中多了proxy轉(zhuǎn)發(fā)的代價(jià),所以SQL請(qǐng)求的延時(shí)會(huì)稍微比不用proxy鏈路的請(qǐng)求要慢。因此為了不影響用戶(hù)的體驗(yàn),我們希望SQL請(qǐng)求在proxy節(jié)點(diǎn)中停留的時(shí)間越短越好。因此我們以SQL請(qǐng)求在proxy節(jié)點(diǎn)中停留和proxy與db之間的傳輸總時(shí)間prT(proxy relay time)作為衡量proxy服務(wù)質(zhì)量的重要指標(biāo)。如果實(shí)例ins1的請(qǐng)求在proxy節(jié)點(diǎn)的prT>=ProxyRelayTimeLimit,對(duì)于該請(qǐng)求,proxy代價(jià)時(shí)間過(guò)長(zhǎng)。
由于有現(xiàn)成的生產(chǎn)集群上proxy節(jié)點(diǎn)和db節(jié)點(diǎn)都安裝了tcprt內(nèi)核驅(qū)動(dòng),我們打算proxy節(jié)點(diǎn)和db節(jié)點(diǎn)的tcprt數(shù)據(jù)來(lái)做類(lèi)似的工作。
如圖是ins1,ins2的SQL請(qǐng)求在proxy節(jié)點(diǎn)和db節(jié)點(diǎn)上的鏈路活動(dòng)圖。 ins1實(shí)例的一次請(qǐng)求時(shí)間rt1= t0+ t1 + t2 + t3 + t4 + t5 + t6, 其中t0是SQL請(qǐng)求從client端到proxy端傳輸?shù)臅r(shí)間, t1是接收client端發(fā)的請(qǐng)求到向db端發(fā)送所需的時(shí)間,t2是proxy1到db1的網(wǎng)絡(luò)鏈路時(shí)間,t3是db1的本地處理時(shí)間,t4是db1到proxy1的網(wǎng)絡(luò)鏈路時(shí)間,t5是接受到db1端發(fā)的SQL應(yīng)答到向client端發(fā)送的時(shí)間,t6是應(yīng)答從proxy端到client端的傳輸時(shí)間。而(ins1, *, proxy1)的tcprt處理時(shí)間proxyInTime1=t1+t2+t3+t4+t5, (ins1, proxy1, *)的tcprt處理時(shí)間proxyOutTime1=t3,通過(guò)計(jì)算diff1 = proxyInTime1-proxyOutTime1 = t1+t2+t3+t5, 可以算出SQL請(qǐng)求在proxy節(jié)點(diǎn)中停留和proxy與db之間網(wǎng)絡(luò)傳輸?shù)目倳r(shí)間prT。
由于網(wǎng)絡(luò)延遲正常情況下在內(nèi)部網(wǎng)絡(luò)中比較穩(wěn)定的,如果diff1值變大了,多出的部分,往往是proxy節(jié)點(diǎn)貢獻(xiàn)的,因此我們可以大致通過(guò)diff1估計(jì)實(shí)例ins1在proxy1停留的的大致時(shí)間。對(duì)于經(jīng)過(guò)proxy的每個(gè)實(shí)例,如果prT>=ProxyRelayTimeLimit,則認(rèn)為prT過(guò)大。我們算出proxy1上的各個(gè)實(shí)例的prT值,得到prT值過(guò)長(zhǎng)的實(shí)例數(shù)量占proxy1上活躍實(shí)例數(shù)的比例r。我們可以根據(jù)r的突升和范圍來(lái)判斷proxy及下游網(wǎng)絡(luò)鏈路是否對(duì)用戶(hù)形成影響。 為了判斷r的突升,首先,利用上面判斷db主機(jī)異常的方法,回歸出這個(gè)數(shù)據(jù)集的柯西概率分布D。
因?yàn)楸壤齬的取值是0~1,而柯西概率分布D的自變量x范圍是負(fù)無(wú)窮到正無(wú)窮。我們需要對(duì)原來(lái)的比率r做轉(zhuǎn)化讓他的范圍擴(kuò)充到正負(fù)無(wú)窮。通過(guò)映射函數(shù),我們求出這一時(shí)刻下該指標(biāo)的柯西概率分布的CDF(x’),由于r越小表明proxy越健康,所以只有當(dāng)r>M是才會(huì)進(jìn)一步判斷proxy是否異常,如果CDF(x’)非常大比如:大于99.8%, 說(shuō)明比率r突然明顯上升,需要引起注意。為了減少誤判,我們還要判斷出r值的突升和突降需要落到警戒范圍。因此需要一個(gè)必要條件:r值的絕對(duì)值至少為20%。
不過(guò)如果r本身就很大的話(huà)比如:由于proxy升級(jí)到了一個(gè)有bug的版本上,所有的實(shí)例從新版本上線(xiàn)后就一直慢,由于數(shù)據(jù)集的中位數(shù)變成了100%,上面的方法就無(wú)法判斷了。我們還要再加個(gè)異常的充分條件,那就是:如果r>MaxRatio(比如:80%),就判斷為異常。使用回歸分布的方法適合當(dāng)r發(fā)生巨變時(shí)來(lái)判斷異常,主要是為了找到proxy的急性?。欢蠹拥呐袛喈惓5某浞謼l件適用于當(dāng)r從一開(kāi)始就不正常,或者r緩慢變成不正常的情況,是為了找到proxy的慢性病。
網(wǎng)絡(luò)異常檢測(cè)
為了容忍交換機(jī)單點(diǎn)故障,每個(gè)節(jié)點(diǎn)(代理節(jié)點(diǎn)和數(shù)據(jù)庫(kù)節(jié)點(diǎn))會(huì)上聯(lián)到一對(duì)TOR交換機(jī)上。TOR中的高丟包率會(huì)導(dǎo)致大量TCP數(shù)據(jù)包重新傳輸,并導(dǎo)致查詢(xún)延遲變高、失敗連接增加,從而導(dǎo)致用戶(hù)數(shù)據(jù)庫(kù)性能下降。因此,在短時(shí)間內(nèi),識(shí)別網(wǎng)絡(luò)故障并定位異常網(wǎng)絡(luò)設(shè)備,通過(guò)修復(fù)或者更換的方式去解決網(wǎng)絡(luò)異常是至關(guān)重要的。 通過(guò)TcpRT采集的TCP連接上亂序數(shù)據(jù)包,重傳數(shù)據(jù)包,RTT抖動(dòng)和RST數(shù)據(jù)包的數(shù)量,可用于網(wǎng)絡(luò)故障排查。
如上圖所示,在分布式體系結(jié)構(gòu)中,每個(gè)節(jié)點(diǎn)相互通信,比如,Proxy節(jié)點(diǎn)到數(shù)據(jù)庫(kù)節(jié)點(diǎn)的請(qǐng)求重定向。我們繪制一個(gè)二分圖來(lái)表示節(jié)點(diǎn)之間的關(guān)系,頂點(diǎn)是Proxy節(jié)點(diǎn)和正在通信的數(shù)據(jù)庫(kù)節(jié)點(diǎn),如果兩個(gè)節(jié)點(diǎn)存在相互通信,那么這兩個(gè)節(jié)點(diǎn)存在一條鏈接邊。用虛線(xiàn)標(biāo)記的鏈接表示在兩個(gè)節(jié)點(diǎn)之間觀察到大量網(wǎng)絡(luò)異常事件(無(wú)序,重傳等),否則我們使用實(shí)線(xiàn)代替。
根據(jù)主機(jī)到TOR交換機(jī)對(duì)的連接信息,通過(guò)把主機(jī)節(jié)點(diǎn)替換成相應(yīng)的TOR交換機(jī)對(duì),我們將上圖b轉(zhuǎn)換成上圖c。直觀上,相連虛線(xiàn)數(shù)越多的頂點(diǎn)異??赡苄栽礁?。因此,我們定義公式count^1.5/total來(lái)衡量TOR交換機(jī)對(duì)發(fā)生異常的概率,其中count表示虛線(xiàn)數(shù),total表示線(xiàn)(虛+實(shí))數(shù)。count^1.5/total值越大,該TOR交換機(jī)對(duì)越有可能是異常。
小結(jié)
到目前為止,TcpRT以每秒采集2千萬(wàn)條原始trace數(shù)據(jù)、每天后臺(tái)處理百億吞吐數(shù)據(jù)、秒級(jí)檢測(cè)異常的卓越性能在阿里云持續(xù)穩(wěn)定運(yùn)行三年。今年TcpRT的監(jiān)控能力將包裝成云產(chǎn)品開(kāi)放給RDS客戶(hù),給客戶(hù)提供更好的數(shù)據(jù)庫(kù)與應(yīng)用診斷能力。在技術(shù)上,我們也在基于TcpRT開(kāi)發(fā)更多的算法,發(fā)掘更多的異常行為。
論文作者:鳴嵩,劍川,冰豹,仲舉,淺清,望瀾,明書(shū)
聯(lián)系客服