記一次redis連接建立超時的問題解決


背景:

1.系統由多個進程組成,幾乎每個進程都需要訪問redis。

2.所有進程都部署在一台機器,包括redis/mysql。

3.redis驅動程序使用的是jedis 2.8。

4.每個進程配置的redis連接池數量都較大,最大大概幾百個連接。

5.現場人員報告,頁面某功能偶現不可用的情況,經查相關進程日志,是由於redis連接建立失敗導致的。

排查過程:

1.搭建壓力測試環境,模擬現網壓力,同樣出現了redis建立連接失敗,異常顯示socket connection timeout。

2.嘗試修改連接池配置,將idl調成和total一致,均為200,問題並未解決。

3.嘗試加大連接池數量,問題並未解決。

4.后來想到,redis服務器是單線程的,即同一時刻,僅處理一個連接發出的指令,那么連接池中的多個連接,雖然將指令發送至redis,但redis並未立即處理,而是在排隊。那么,與其將指令發送給redis,在redis端排隊,不如在本進程內排隊,暫不將指令發送至redis,即將redis連接池idl/total均設為1,僅維持一條與redis的連接,如果業務量過大,本進程內排隊超時,也就是等待從連接池獲取連接超時,那么可以通過加大連接池的maxwait值來解決。想到此點之后,將連接池idl/total調整為1,開始壓力測試,未再出現連接建立超時。

5.問題解決。

經驗:redis服務器是單線程模型,加大連接池,只是加大排隊的隊列數,但是,redis是多進程共用,壓力較大,在處理大量的redis指令的同時,還要維護大量的連接,是很耗資源的。所以,每個進程僅維持一條與redis的連接,通過加大maxwait,來控制在本進程內排隊,可以降低redis的壓力。redis和mysql等不同,mysql是可以多個連接的指令並行執行的,所以連接池設置過大沒有意義。


免責聲明!

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



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