时延敏感业务低概率超时问题分析
前言
作為阿里云底層提供的基礎(chǔ)設(shè)施,內(nèi)部的物理網(wǎng)絡(luò)和許多網(wǎng)絡(luò)產(chǎn)品在數(shù)據(jù)平面給客戶的可操作性并不高,從一定程度上來說是個黑盒。當(dāng)然,在傳統(tǒng)的IDC環(huán)境,業(yè)務(wù)和物理網(wǎng)絡(luò)之間也存在同樣的隔閡。所以在遇到業(yè)務(wù)卡頓、延遲、不通等問題的時候,很容易懷疑到網(wǎng)絡(luò)。因此如何抽絲撥繭,找到正確的方向?qū)ΠY下藥才能夠真正的解決問題。畢竟“真相只有一個”。
在進(jìn)行問題排查和處理的時候,難度最高的場景就是極度偶發(fā),復(fù)現(xiàn)頻率極低的問題。尤其在網(wǎng)絡(luò)排查的領(lǐng)域,通常為了性能和控制資源消耗,不會將每一個數(shù)據(jù)包的情況都一一記錄下來,對于一次偶發(fā)的應(yīng)用層記錄的超時,網(wǎng)絡(luò)層通常沒有明確的對應(yīng)此次應(yīng)用層調(diào)用的包交互記錄,因此排查起來非常困難。
在這次的案例中,我們通過一個客戶端查詢redis集群偶發(fā)超時的小案例,來說明一些診斷思路、排查手段,進(jìn)而引出一些在網(wǎng)絡(luò)方面提高業(yè)務(wù)穩(wěn)定性的最佳實(shí)踐。
問題環(huán)境
這次的問題是一個交互性web應(yīng)用中的一個子模塊,主要進(jìn)行redis查詢,可以簡單將其理解為視頻彈幕網(wǎng)站中“查詢彈幕”的小模塊。這個模塊的拓?fù)浞浅:唵?#xff1a;
在上面的拓?fù)渲?#xff0c;客戶使用ECS構(gòu)建了一個Redis集群,前面用Codis實(shí)現(xiàn)了一層Redis Proxy (為了通用性,后面均用Redis proxy來描述),并將這組Redis proxy掛載在一個SLB后,通過SLB的單一入口提供服務(wù)。
問題現(xiàn)象
客戶的主要問題是訪問其自建Redis系統(tǒng)的客戶端會不定期出現(xiàn)超時報錯,盡管總體概率不高,但是報錯概率高于其業(yè)務(wù)運(yùn)行在原有機(jī)房的水平。超時報錯主要有兩種情況:
診斷思路
作為問題排查的第一步,首先要了解到問題本身所處的上下文和環(huán)境。在平時診斷問題收集信息的時候,為了有條理的、全面的收集信息,筆者將需要收集的信息分為兩種類型:資源因素和環(huán)境因素。
- 資源因素:即發(fā)生問題的系統(tǒng)的拓?fù)洹1热缟婕暗母鞣N應(yīng)用程序、主機(jī)、轉(zhuǎn)發(fā)設(shè)備、鏈路資源等,并且要充分理解這些資源組建在拓?fù)渲衅鸬降淖饔谩?/li>
- 環(huán)境因素:即描述這個問題所需要的信息,比如報錯日志,問題發(fā)生時間、頻率,應(yīng)用層設(shè)置的超時時間等等。
了解資源因素和環(huán)境因素后,可以將問題的定義明確為:在哪些資源上發(fā)生了什么樣的問題,然后根據(jù)該定義收集與問題相關(guān)的信息,并在解讀和分析的時候通過數(shù)據(jù)排除所有的不可能,這樣才能進(jìn)行高效和準(zhǔn)確的問題排查。
在本案例中,資源因素已經(jīng)在上文的拓?fù)渲嘘U述,問題所涉及的環(huán)境因素包括:客戶設(shè)置的是50ms超時,在客戶端的報錯是read timeout(代表排除了tcp的三次握手超時),報錯頻率為非業(yè)務(wù)高峰期一個小時10個左右,業(yè)務(wù)高峰期1小時上百個。但是偶爾(一周內(nèi)偶爾發(fā)生一次到兩次)無論業(yè)務(wù)高峰還是非業(yè)務(wù)高峰都會有較多的,上百次的read timeout和connect timeout。客戶已經(jīng)排查過redis,其查詢時間每次耗時不超過10ms,而redis proxy沒有記錄轉(zhuǎn)發(fā)的日志。
排查方法
因?yàn)樗锌捎玫娜罩緝H能定位到這個系統(tǒng)的兩端(客戶端、Redis),需要收集進(jìn)一步的信息。面對這種超時類的問題,最直接、有效的辦法就是進(jìn)行抓包。而該問題發(fā)生的頻率不高,整個系統(tǒng)流量也比較大,一直開著抓包很容易將磁盤撐滿,因此需要使用循環(huán)抓包:
tcpdump -i <接口|any> -C <每文件大小> -W <文件個數(shù)> -w <保存文件名> 抓包過濾條件該命令的意思是針對某個接口,按照過濾條件進(jìn)行抓包,保存指定文件名前綴的文件下,最多占用每文件大小*文件個數(shù) 的磁盤空間并循環(huán)覆蓋。開啟循環(huán)抓包后,等待客戶端報錯再次出現(xiàn),即可抓到現(xiàn)場的包交互過程。
抓包的結(jié)果文件可以使用wireshark打開,但是使用循環(huán)抓包抓到的數(shù)據(jù)包文件較大、數(shù)量較多,可以使用下面的小技巧進(jìn)行快速的過濾:
//在安裝了wireshark的電腦上都會有capinfos和tshark兩個命令,以筆者使用的macOS為例 ~$ capinfos -a -e *cap //使用capinfos查看抓包文件的其實(shí)時間和結(jié)束時間,選取包含報錯時間+-超時時間的文件,其他文件就不需要了 File name: colasoft_packets.cap Packet size limit: inferred: 66 bytes - 1518 bytes (range) First packet time: 2019-06-12 09:00:00.005519934 Last packet time: 2019-06-12 09:59:59.998942048File name: colasoft_packets1.cap Packet size limit: inferred: 60 bytes - 1518 bytes (range) First packet time: 2019-06-12 09:00:00.003709451 Last packet time: 2019-06-12 09:59:59.983532957//如果依然有較多文件,則可以使用tshark命令進(jìn)行篩選。比如報錯中提到Redis查詢一個key超時,則可以用以下腳本找到這次查詢請求具體在哪個文件中: ~$ for f in ./*; do echo $f; tshark -r $f 'tcp.payload contains "keyname"'; done找到對應(yīng)的請求之后,再用wireshark打開該文件,找到對應(yīng)數(shù)據(jù)包,跟蹤對應(yīng)流來找到五元組和整個流的上下文交互。
在本案例中,通過對比客戶端、redis proxy和redis 三層的抓包,發(fā)現(xiàn)客戶端發(fā)出請求到收到響應(yīng)的時間的確在問題發(fā)生時話費(fèi)了100多ms,而這部分耗時主要發(fā)生在Redis將響應(yīng)返回給Redis proxy的丟包重傳導(dǎo)致。整體時序示意圖如下:
?
對于從抓包中觀察到的丟包現(xiàn)象,在通過阿里云內(nèi)部監(jiān)控確定了物理鏈路的確不存在丟包的情況下,我們發(fā)現(xiàn)Redis proxy所在的ECS上,虛擬化層面的后端驅(qū)動在向前端驅(qū)動送包的時候,前后端隊(duì)列的丟包計(jì)數(shù)的增長趨勢和業(yè)務(wù)超時的頻率有相同趨勢,進(jìn)一步排查發(fā)現(xiàn)客戶ECS操作系統(tǒng)內(nèi)的網(wǎng)卡多隊(duì)列沒有開啟,導(dǎo)致只有一個CPU處理網(wǎng)卡中斷,而當(dāng)流量有瞬間突增的時候,CPU來不及處理網(wǎng)卡中斷導(dǎo)致前后端隊(duì)列堆積,隊(duì)列溢出后導(dǎo)致丟包。
為了解決這個問題,我們建議客戶將網(wǎng)卡多隊(duì)列開啟,并將不同網(wǎng)卡隊(duì)列中斷的CPU親和性綁定在不同的CPU上。對于阿里云ECS,可以使用的網(wǎng)卡隊(duì)列是和實(shí)例規(guī)格綁定的,具體可以參考ECS實(shí)例規(guī)格文檔。簡單的開啟網(wǎng)卡隊(duì)列并使用irqbalance 自動調(diào)度網(wǎng)卡隊(duì)列中斷CPU親和性的方法可以參考阿里云官方文檔。
本案例中客戶開啟網(wǎng)卡多隊(duì)列并開啟irqbalance服務(wù)之后,每小時都出現(xiàn)的訪問超時問題已經(jīng)解決,但是還是會有每隔幾天會出現(xiàn)的突發(fā)性大量超時。經(jīng)過匯聚客戶的報錯信息和阿里云底層的網(wǎng)絡(luò)監(jiān)控,我們最終確認(rèn)這種每隔幾天就會出現(xiàn)的突發(fā)性大量超時是因?yàn)榘⒗镌频讓拥目缈捎脜^(qū)間鏈路抖動導(dǎo)致的。
阿里云的每一個可用區(qū)可以理解為是一個機(jī)房,而不同可用區(qū)之間可以互為同城災(zāi)備關(guān)系。為了確保可用區(qū)之間不會故障擴(kuò)散,不同可用區(qū)機(jī)房需要保持一定物理機(jī)距離,并通過同城傳輸光纜將所有可用區(qū)相互連接實(shí)現(xiàn)可用區(qū)之間的互訪。
連接可用區(qū)之間的同城傳輸光纜的可靠性遠(yuǎn)低于機(jī)房內(nèi)部跳纖,且經(jīng)常容易受到道路施工、質(zhì)量劣化的影響,導(dǎo)致鏈路中斷。為了保證業(yè)務(wù)連續(xù)性,阿里云提供了充足的冗余鏈路并使用傳輸?shù)箵Q、路由切換等技術(shù)確保部分跨可用區(qū)鏈路時故障可以自動收斂,但是在倒換過程中產(chǎn)生的丟包卻無法完全避免。根據(jù)阿里云底層監(jiān)控,當(dāng)一條跨可用區(qū)鏈路中斷時,通常會導(dǎo)致持續(xù)3-5秒的1%左右的丟包(具體需要看中斷鏈路數(shù)量占總鏈路數(shù)量的占比),而反映在業(yè)務(wù)上,則有可能造成時延敏感業(yè)務(wù)接近1分鐘的部分超時報錯。因此在本案例中造成了突增的超時報錯。
假如客戶使用資源時,可用區(qū)分布非常散亂,則會造成可用區(qū)間鏈路抖動對業(yè)務(wù)影響的頻率升高。比如客戶的客戶端ECS分布在多個可用區(qū)(A、B),SLB在可用區(qū)C ,Redis proxy和Redis在可用區(qū)D、E,則A到C、B到C、C到D、D到E的跨可用區(qū)鏈路抖動都會影響到整個系統(tǒng)。
最佳實(shí)踐
通過這個案例我們可以總結(jié)出關(guān)于主機(jī)網(wǎng)絡(luò)和網(wǎng)絡(luò)部署方面兩個最佳實(shí)踐:
- 主機(jī)網(wǎng)絡(luò)方面:打開網(wǎng)卡多隊(duì)列并將網(wǎng)卡軟中斷打散以獲取最佳的網(wǎng)絡(luò)性能。總體來講,為了獲得穩(wěn)定的網(wǎng)絡(luò)性能,有以下通用建議:
- 使用VPC實(shí)例:除了網(wǎng)絡(luò)租戶隔離、支持專線、VPN網(wǎng)關(guān)等好處外,VPC環(huán)境在底層轉(zhuǎn)發(fā)能力上也比經(jīng)典網(wǎng)絡(luò)實(shí)例有大幅提高,最新一代實(shí)例均基于VPC環(huán)境實(shí)現(xiàn),因此也提供了更強(qiáng)的網(wǎng)絡(luò)轉(zhuǎn)發(fā)性能。
- 使用獨(dú)享型實(shí)例:獨(dú)享型實(shí)例采用嚴(yán)格的資源隔離技術(shù),確保虛擬機(jī)不會收到“吵鬧的鄰居”影響。
- 打開網(wǎng)卡多隊(duì)列并綁定網(wǎng)卡軟中斷處理CPU親和性:對于不同網(wǎng)卡隊(duì)列使用不同CPU進(jìn)行處理,提高網(wǎng)絡(luò)處理性能
- 將網(wǎng)卡多個隊(duì)列分別綁定到某幾個專用CPU上,而其他進(jìn)程綁定到其他CPU上,讓網(wǎng)卡軟中斷處理使用專門的CPU:適用于純轉(zhuǎn)發(fā)類、對網(wǎng)絡(luò)性能要求極高的服務(wù)。
- 物理網(wǎng)絡(luò)方面:建議從業(yè)務(wù)容忍度和時延敏感度進(jìn)行權(quán)衡來選擇業(yè)務(wù)的部署。
- 從業(yè)務(wù)容忍度的角度來說,如果tcp協(xié)議中發(fā)生了丟包,那么最壞情況下需要等待RTO超時才能夠重傳(tail drop場景,其他場景有fast retrans機(jī)制),而RTO超時的最小取值在kernel中的定義為200HZ,即200ms。對于內(nèi)網(wǎng)互訪或者同城互訪這種時延較低的場景,可以理解為一次丟包的最壞情況就是200ms的重傳,因此對于關(guān)鍵業(yè)務(wù),至少將請求超時設(shè)置在200ms以上,讓tcp有一次重傳的機(jī)會。而對于非關(guān)鍵業(yè)務(wù),一次查詢是否返回?cái)?shù)據(jù)并不關(guān)鍵的,則可以將請求超時設(shè)置的更小以便保護(hù)整個系統(tǒng)。因此業(yè)務(wù)容忍有兩個方面:業(yè)務(wù)可以容忍錯誤,或者業(yè)務(wù)可以容忍重傳。
- 從時延敏感度的角度來說,為了確保時延敏感業(yè)務(wù)盡量少的受跨可用區(qū)鏈路影響,建議盡量將時延敏感業(yè)務(wù)的整個業(yè)務(wù)調(diào)用都在一個可用區(qū)內(nèi)完成。而不同的可用區(qū)之間盡管提供相同服務(wù),但是之間不會經(jīng)常跨可用區(qū)調(diào)用。比如web server層調(diào)用提供緩存服務(wù)的Redis在本可用區(qū)完成,只有緩存沒有命中的少量情況,才有可能跨可用區(qū)查詢數(shù)據(jù)庫,甚至使用只讀實(shí)例等其他技術(shù),將跨可用區(qū)鏈路抖動的影響降至最低。
結(jié)束語
通過上面的案例和最佳實(shí)踐的說明,可以看到“權(quán)衡”在業(yè)務(wù)系統(tǒng)架構(gòu)涉及和部署當(dāng)中是無處不在的。所謂優(yōu)化就是在給定的環(huán)境下,為了實(shí)現(xiàn)業(yè)務(wù)目標(biāo),將資源傾斜到最需要的地方。另一方面,對于許多客戶在上云前的系統(tǒng)架構(gòu)中,受限與機(jī)房成本、位置等原因,可能沒有使用過多機(jī)房的組網(wǎng)場景,而云計(jì)算對這些客戶帶來的除了基礎(chǔ)設(shè)施跨代升級的便利之外,還提供了天然的容災(zāi)能力,而業(yè)務(wù)系統(tǒng)的架構(gòu)和部署也需要增加因容災(zāi)所帶來的組網(wǎng)場景的復(fù)雜化。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的时延敏感业务低概率超时问题分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QPS 提升60%,揭秘阿里巴巴轻量级开
- 下一篇: 自动化日志收集及分析在支付宝 App 内