Redis cpu100%的探索


最近網站在高流量時段總“掛”,CPU達到100%導致的,原因是redis CPU使用過大。

公司的Terry解決並復現了這個問題。那么今天就借用Terry文檔咱們整理下做個分享,這個分享主要想講述的是在開發或運維中遇見這種不能直接定位的“災難”,我們要有的分析問題思路。

首先說下環境:redis服務器為單核,nginx負載均衡6台,worker_processes 2,PHP 靜態CGI進程 220。

先分析下達到這種情況的場景:

1.長鏈接導致僵屍進程

2.在鏈接數過多后,val過大導致慢插入

3.存入磁盤快照過大,頻次過高

4.主從存在頻繁全量量同步

5.⽹絡問題

6.慢查詢

我們要了解redis中連接的定義,connect腳本結束后被釋放,pconnect進程結束后被釋放。

PHP中redis->close() 。

1)當使用connect 當執⾏close(),會向redis發送quit指令,直接斷開連接。不執close命令則php腳本運行完后會自動斷開連接 。

2)當使⽤pconnect,連接會被重用,連接的生命周期是fpm進程的生命周期,而非一次php的執行。

3)當使用pconnect,close的作用僅使當前php腳本不能再進行redis請求,但無法真正關閉redis長連接,連接在后續使用同一個fpm進程時仍然會被重用,直至fpm進程生命周期結束或被殺死。

參考鏈接:https://www.cnblogs.com/huanxiyun/articles/6554670.html

php-fpm的生命周期:進程管理理⼀一共有三種模式,ondemand(按需)、static(靜態)、dynamic(動態)-默認。

ondemand:在php-fpm啟動的時候,不會給這個pool啟動任何一個worker,是按需啟動,當有連接過來才會啟動。

static:php-fpm啟動采用固定數量的worker,在運行期間也不會擴容,雖然也有1秒的定時器,僅限於統計一些狀態信息,例例如空閑worker個數,活動worker個數,⽹網絡連接隊列長度等信息。

dynamic:在php-fpm啟動時,會初始啟動⼀一些worker,在運行過程中動態調整worker數量,worker的數量受限於pm.max_children配置,同時受限全局配置process.max

我們的redis和PHP-FPM配置是pconnect,startic。

 

這個測試中本是要觀察長鏈接是否跟fpm進程同一個生命周期,剛開始以為自己的理解有問題,后來才發現redis設置了心跳,有這個設置后連接在60秒內沒有動作就會被殺死。

 

關閉心跳后測試按照預期,證明了redis的鏈接跟fpm進程間的關系。

redis-benchmark壓力測試工具是一個測試連接非常好用的工具,這里不多做介紹有興趣請點擊連接 http://www.redis.cn/topics/benchmarks.html

redis-benchmark -h 111.111.111.111 -p 6380 -c 9990 -n 1000 -q 9990的並發訪問1000次發現在高並發的狀態下CPU確實上升了2%但達到100%還差的很遠。

所以連接數過多的猜想是不對的。

單純的連接數過多是達不到我們想要的效果的,那么在這里做一個延伸就是在連接數過多的情況下插入大的val。

在這個測試中CPU在多連接數的基礎上再次提升了3%,也不是我們想要的結果。

這里我們看下寫入磁盤快照

配置:save 900 1,save 300 10,save 60 10000,rdbcompression yes。這段配置意思是說每15分鍾至少有1次key的改變觸發1次持久化,每5分鍾至少10次key改變觸發1次持久化,每60秒10000個key改變觸發1次持久化,rdbcomprssion的意思是說是否壓縮存儲。

看了下持久化日志。

RDB:75MB of memory used by copy-on-write

可以看出我的存儲數據為75MB,接下來我把持久化數據存儲到268MB,CPU的攀升比之前的幅度大很多但也只達到了35%。可見也不是這個原因。

主從同步我們服務器沒有做,網絡原因也不過多考慮。

我們看下慢查詢。

是否因為val值過大導致慢查詢。這個時候我們觀察到我們代碼中session是存儲在redis當中的,會有一些空值存在即:有key但里面沒有val。經過測試我們得出在配置session存入redis時只要執行session_start()函數那么redis就會出現一條空值數據。

這時我們觀察了下keys發現有460W,經過測試果然是這個問題,在代碼中有很多keys()查詢,這會導致redis查詢沒一個key,當在本地復現這個問題時在key達到200W時CPU就已經“掛”掉了。

查下redis的文檔發現了一個很有趣的現象,文檔中說keys 返回所有匹配的鍵(說白了就是全表查詢)在入門級筆記本中100W個key的查詢時間是40毫秒。好吧他沒說100W+之后的查詢效率,這就告訴你在key達到100W+后keys查詢會大大降低查詢速度。


免責聲明!

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



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