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