來源:https://blog.csdn.net/francis123580/article/details/82500700
Redis是單線程架構,在高並發的場景下,如果出現阻塞,會有嚴重后果,以下就是對阻塞問題的分析排查和解決
內在原因
API 或 數據結構 使用不合理
排查:
- 發現慢查詢:執行
slowlog get {n}
- 發現大對象:執行
redis-cli -h {ip} -p {port} --bigkeys
解決:
- 解決慢查詢:調整命令為低算法度命令
- 調整大對象:把大對象拆分為多個小對象,防止一次命令操作過多數據
CPU飽和
排查
- 查看CPU使用率:執行
top
命令 - 查詢Redis並發量:執行
redis-cli -h {ip} -p {port} --stat
命令
解決:
- 集群化水平拓展分攤OPS壓力
- 檢查是否有過度的內存優化
持久化阻塞
排查
- 檢查最近fork操作耗時:執行
info status
獲取到 latest_fork_usec 指標 - 檢查AOF刷盤最近成功時間:查看日志
解決:
- 若fork操作耗時超過1秒,避免使用過大的內存實例和規避fork緩慢的操作系統
- 若AOF刷盤fsync成功操作超過2秒,降低其他進程對硬盤的壓力
外在原因
CPU競爭
排查:執行 top
或 sar
命令
解決:
- 不建議和其他多核CPU密集型服務部署在一起,會影響Redis吞吐量
- 把Redis進程綁定到CPU上,可降低CPU上下文切換開銷
- 開啟了持久化或參與復制的主節點不建議綁定CPU,因為子進程會占用90%競爭
內存交換
排查:
- 查詢Redis進程號:執行
redis-cli -p 6383 info server | grep process_id
命令 - 根據進程號查詢內存交換信息:執行
cat /proc/process_id/smaps | grep Swap
解決:
- 保證機器充足的可用內存
- 確保所有Redis實例設置最大可用內存,防止Redis不可控增長
- 降低系統使用swap優先級
網絡問題
排查:
- 網絡閃斷:通過
sar -n DEV
查看本機歷史流量是否正常 - Redis連接拒絕:執行
redis-cli -p 6384 info stats | grep rejected_connections
查看所有被拒絕的連接數量 - 連接溢出:執行
ulimit -n
命令,檢查操作系統對進程使用資源的限制;執行netstat -s | grep overflowed
命令,檢查是否有持續增長的連接拒絕 - 網絡延遲:執行
redis-cli -h {host} -p {port} --latency
命令,測量機器之間的網絡延遲
解決:
- 避免客戶端與Redis之間異地跨機房調用
- 客戶端訪問Redis時盡量采用NIO長連接或者連接池的方式
- 對於支撐大量連接的Redis需要增大 ulimit 值,修改系統backlog值
- 調整網絡拓撲結構,同物理機>同機架>跨機架>同機房>同城機房>異地機房