目錄
strace -f -T -tt -p pid:用來監控某程序産生的系統調用.
lsof -p pid:輸出某程序打開的所有檔案.
1.排查wait态cpu使用率高的原因:
1.檢視是否是I/O負載高引起:iostat -d x 3
2.排查IO請求的原因:pidstat -d 3
3.定位到可能的問題:redis寫資料造成iowait
4.分析問題原因:strace -f -T -tt -p 4728,發現redis在不斷的向檔案寫資料.
5.輸出redis程序打開的所有檔案:lsof -p 4782
6.7w-->/data/appendonly.aof檔案分析顯示redis在頻繁寫檔案:
7.檢視redis的fsync配置:docker exec -it redis reidis-cli config get 'append*'
8.分析read調用,代碼中可能存在一個SADD方法:
9.分析代碼:确認猜想
2.問題總結:
1.Redis配置的"appendfsync"值為"always",導緻Redis每次的寫操作,都會觸發fdatasync系統調用将資料持久化落入磁盤.
2.應用代碼中調用了Redis的sadd指令,這也可能造成緩存使用不合理的問題.
3.解決方案:
1.将Redis配置的"appendfsync"值改為"everysec".
docker exec -it redis redis-cli config set appendfsync everysec
修改後回歸,發現iowait降低,響應時間大幅度減少,TPS随之升高.
2.讓研發優化代碼.
在性能測試過程中,碰到的瓶頸并不一定都是cpu,mem造成,還有可能是系統架構設計不合理,代碼算法性能差引起的.
strace -f -T -tt -p pid:用來監控某程序産生的系統調用.
lsof -p pid:輸出某程序打開的所有檔案.
安裝strace:yum install -y strace
Redis性能瓶頸分析:
性能測試時,發現tps低,響應時間很高,但是檢視系統負載,cpu和mem都處于可控範圍,排查壓力機的負載和網絡連通性,均正常,唯一異常的是wait态的cpu較高.
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI2EzX4xSZz91ZsAzNfRHLGZkRGZkRfJ3bs92YsAjMfVmepNHL5Z1RkpnVHRmZ1cVWwJlbiFDaykVQClGVF5UMR9Fd4VGdsATNfd3bkFGazxycykFaKdkYzZUbapXNXlleSdVY2pESa9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLxYmZ1czYxImZmF2N5AjY5Y2YwQDZxkTZwYjM0MjNwczLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1.排查wait态cpu使用率高的原因:
1.檢視是否是I/O負載高引起:iostat -d x 3
發現,I/O無性能瓶頸,但是壓測的接口是一個讀資料接口,此處io資訊顯示,在壓測過程中,對磁盤有寫的操作,需要排查是什麼在壓測過程中不斷的寫資料.
2.排查IO請求的原因:pidstat -d 3
顯示redis-server這個程序在不斷的寫資料.但是redis一般被用來作為緩存中間件,提高查詢時的傳回速度,一般都隻做讀操作,是以需要排查為何redis在不斷的寫資料.
3.定位到可能的問題:redis寫資料造成iowait
4.分析問題原因:strace -f -T -tt -p 4728,發現redis在不斷的向檔案寫資料.
發現redis有read,write,epoll_pwait,fdatasync等系統調用,且調用頻繁,且write.fdatasync表示在不斷地向檔案寫資料.
5.輸出redis程序打開的所有檔案:lsof -p 4782
lsof即可顯示系統打開的檔案,因為 lsof 需要通路核心記憶體和各種檔案,是以必須以 root 使用者的身份運作它才能夠充分地發揮其功能。
FD列描述:(linux萬物皆檔案)
3r:一個pipe管道; 5u:eventpoll; 6u:一個tcp socket; 7w:一個普通檔案
6.7w-->/data/appendonly.aof檔案分析顯示redis在頻繁寫檔案:
redis資料持久化2種方式:
1.快照方式:redis會按照指定的時間間隔生成資料的快照,然後儲存在磁盤檔案中,為了避免阻塞主程序,redis還會fork一個子程序,負責快照的儲存,這種方式在備份和恢複,好于檔案追加方式. 缺點:資料量大時,消耗記憶體,而且耗時.如果發生故障,會丢失數分鐘的資料.
2.追加檔案:redis使用在檔案末尾追加記錄的方式,實作redis依次寫入資料到磁盤,檔案追加的方式使資料更安全. 追加檔案的方式還提供了"appendfsync"選項設定fsync,來確定寫入磁盤的資料的頻率,選項包括:
"always":每個操作都會執行一次fsync,最安全.
"everysec":每秒執行一次fsync,就算資料丢失,也隻丢失1s的資料.
"no":交給作業系統處理.
缺點:若選項使用"always"頻繁的寫入磁盤,會造成io負載高.
7.檢視redis的fsync配置:docker exec -it redis reidis-cli config get 'append*'
發現redis的appendfsync設定的是"always",造成了壓測時每次寫redis操作都會調用fsync寫磁盤.這就造成了磁盤IO壓力
8.分析read調用,代碼中可能存在一個SADD方法:
而redis的SADD方法是一個寫操作,是以猜測redis會把它寫入到用于持久化的appendonly.aof檔案中,找到了redis寫磁盤的可能原因:代碼中調用了redis的sadd方法.
9.分析代碼:确認猜想
代碼中确實存在調用redis的sadd方法.