過載保護


緣起

某個線上系統平時非常穩定,當大量更新數據時,系統的服務就會嚴重超時。問題存在了一段時間,基本猜測系統超時和大量寫入數據有關,但卻無法給出確切的解釋。為此已經寫了2篇文章:

linux性能監控
linux的IO調度算法和回寫機制

問題解釋

問題的解釋很簡單:系統過載。由於系統定期更新大量數據,更新期間磁盤讀IO性能很差,導致每個服務的時延極大增加,整個系統的吞吐量大幅降低。該系統沒有采用合理的過載保護策略,導致后續的包全部超時!!!

什么情況會導致系統過載?系統處理能力 < 請求量 = 系統過載。設計系統時都需要系統的處理能力,比如每秒的處理能力、請求峰值、平均處理時延等。這3個指標可很好地估計系統最大處理能力、需要多少機器提供服務、是否需要擴容等。但評估容易只關注 請求量峰值,而忽略系統處理能力的變化。從公式上看,系統處理能力降低同樣會造成過載。

過載成因基本就2種:超過硬件系統極限能力、超出軟件系統的極限能力。超出硬件能力比較少見,重點關注軟件系統:操作系統和應用軟件。操作系統負責統一調配和管理硬件資源,應用系統通過系統調用使用機器的硬件資源,當對資源的使用超過操作系統所能承受的上限,將導致整體處理能力急劇下降。應用系統一般包括下列四種類型的瓶頸,某些應用系統可能同時包含2個及2個以上的瓶頸因素:

CPU(計算密集型)
MEMORY(內存消耗型)
LOAD(大並發型)
IO(包括兩類,磁盤IO密集型如DISK、DB;網絡IO密集型:流量、連接數等)

系統瓶頸理論上是系統中最慢的系統資源,比如上述諸多資源中的一種,在突破瓶頸閥值時系統出現拐點,性能會急劇下降(底層原因比如進程調度頻繁、網絡擁塞、隨機磁盤IO導致文件系統cache命中率下降及磁盤物理IO頻繁---機械臂移動、SWAP換入換出頻繁等等),因此識別系統各環節處理能力及其瓶頸至關重要。

問題的解決

解決該問題大概有以下幾種思路:

1)分散寫;
2)寫時不提供服務;
3)過載保護:丟棄超時的請求。

一種簡單的過載保護

linux的網絡包帶有時間戳,可通過ioctl獲取網絡包的時間戳。該時間戳表示網絡包接收時的時間戳(本機)。因此比較當前時間和網絡包的時間戳即可判斷請求是否超時,若超時,直接丟棄。這個辦法可快速清空超時的請求,避免由於處理超時請求,導致后續的請求無法被正常響應。

 示例代碼:

int GetPkgTime(int sockfd, struct timeval *pkgTv)
{
    struct timeval tv;
    int iRet;
    
    iRet = ioctl(sockfd, SIOCGSTAMP, &tv);
    if(iRet < 0)
    {
        return -1;
    }   
    
    *pkgTv = tv;

    return 0;
}

int IsPkgTimeout(int sockfd, int ms )
{
    struct timeval tv;
    if( GetPkgTime( sockfd, &tv) != 0){
        return -1;
    }

    long pastTime = PostTime(&tv);
    if( pastTime >= ms * 1000){
        return 1;
    }

    return 0;
}

相關文章

如何定位系統性能瓶頸和調優,參考: 性能調優攻略

更多的過載保護,參考:淺談過載保護


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM