網站首頁 編程語言 正文
使用復雜度高的命令
如果在使用Redis時,發現訪問延遲突然增大,如何進行排查?
首先,第一步,建議你去查看一下Redis的慢日志。Redis提供了慢日志命令的統計功能,我們通過以下設置,就可以查看有哪些命令在執行時延遲比較大。
首先設置Redis的慢日志閾值,只有超過閾值的命令才會被記錄,這里的單位是微妙,例如設置慢日志的閾值為5毫秒,同時設置只保留最近1000條慢日志記錄:
# 命令執行超過5毫秒記錄慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近1000條慢日志
CONFIG SET slowlog-max-len 1000
設置完成之后,所有執行的命令如果延遲大于5毫秒,都會被Redis記錄下來,我們執行SLOWLOG get 5查詢最近5條慢日志:
127.0.0.1:6379> SLOWLOG get 5
1) 1) (integer) 32693 # 慢日志ID
2) (integer) 1593763337 # 執行時間
3) (integer) 5299 # 執行耗時(微妙)
4) 1) "LRANGE" # 具體執行的命令和參數
2) "user_list_2000"
3) "0"
4) "-1"
2) 1) (integer) 32692
2) (integer) 1593763337
3) (integer) 5044
4) 1) "GET"
2) "book_price_1000"
...
通過查看慢日志記錄,我們就可以知道在什么時間執行哪些命令比較耗時,如果你的業務經常使用O(N)以上復雜度的命令,例如sort、sunion、zunionstore、keys、scan,或者在執行O(N)命令時操作的數據量比較大,這些情況下Redis處理數據時就會很耗時。
如果你的服務請求量并不大,但Redis實例的CPU使用率很高,很有可能是使用了復雜度高的命令導致的。
解決方案就是,不使用這些復雜度較高的命令,并且一次不要獲取太多的數據,每次盡量操作少量的數據,讓Redis可以及時處理返回。
存儲bigkey
如果查詢慢日志發現,并不是復雜度較高的命令導致的,例如都是SET、DELETE操作出現在慢日志記錄中,那么你就要懷疑是否存在Redis寫入了bigkey的情況。
Redis在寫入數據時,需要為新的數據分配內存,當從Redis中刪除數據時,它會釋放對應的內存空間。
如果一個key寫入的數據非常大,Redis在分配內存時也會比較耗時。同樣的,當刪除這個key的數據時,釋放內存也會耗時比較久。
你需要檢查你的業務代碼,是否存在寫入bigkey的情況,需要評估寫入數據量的大小,業務層應該避免一個key存入過大的數據量。
針對bigkey的問題,Redis官方在4.0版本推出了lazy-free的機制,用于異步釋放bigkey的內存,降低對Redis性能的影響。即使這樣,我們也不建議使用bigkey,bigkey在集群的遷移過程中,也會影響到遷移的性能,這個后面在介紹集群相關的文章時,會再詳細介紹到。
集中過期
有時你會發現,平時在使用Redis時沒有延時比較大的情況,但在某個時間點突然出現一波延時,而且報慢的時間點很有規律,例如某個整點,或者間隔多久就會發生一次。
如果出現這種情況,就需要考慮是否存在大量key集中過期的情況。
如果有大量的key在某個固定時間點集中過期,在這個時間點訪問Redis時,就有可能導致延遲增加。
Redis的過期策略采用定期刪除+惰性刪除兩種策略;
注意,Redis的定期刪除的定時任務,也是在Redis主線程中執行的,也就是說如果在執行主動過期的過程中,出現了需要大量刪除過期key的情況,那么在業務訪問時,必須等這個過期任務執行結束,才可以處理業務請求。此時就會出現,業務訪問延時增大的問題,最大延遲為25毫秒。
而且這個訪問延遲的情況,不會記錄在慢日志里。慢日志中只記錄真正執行某個命令的耗時,Redis主動過期策略執行在操作命令之前,如果操作命令耗時達不到慢日志閾值,它是不會計算在慢日志統計中的,但我們的業務卻感到了延遲增大。
解決方案是,在集中過期時增加一個隨機時間,把這些需要過期的key的時間打散即可。
實例內存達到上限
有時我們把Redis當做純緩存使用,就會給實例設置一個內存上限maxmemory,然后開啟LRU淘汰策略。
當實例的內存達到了maxmemory后,你會發現之后的每次寫入新的數據,有可能變慢了。
導致變慢的原因是,當Redis內存達到maxmemory后,每次寫入新的數據之前,必須先踢出一部分數據,讓內存維持在maxmemory之下。
這個踢出舊數據的邏輯也是需要消耗時間的,而具體耗時的長短,要取決于配置的淘汰策略
fork耗時嚴重
如果你的Redis開啟了自動生成RDB和AOF重寫功能,那么有可能在后臺生成RDB和AOF重寫時導致Redis的訪問延遲增大,而等這些任務執行完畢后,延遲情況消失。
遇到這種情況,一般就是執行生成RDB和AOF重寫任務導致的。
生成RDB和AOF都需要父進程fork出一個子進程進行數據的持久化,在fork執行過程中,父進程需要拷貝內存頁表給子進程,如果整個實例內存占用很大,那么需要拷貝的內存頁表會比較耗時,此過程會消耗大量的CPU資源,在完成fork之前,整個實例會被阻塞住,無法處理任何請求,如果此時CPU資源緊張,那么fork的時間會更長,甚至達到秒級。這會嚴重影響Redis的性能。
綁定CPU
很多時候,我們在部署服務時,為了提高性能,降低程序在使用多個CPU時上下文切換的性能損耗,一般會采用進程綁定CPU的操作。
但在使用Redis時,我們不建議這么干,原因如下。
綁定CPU的Redis,在進行數據持久化時,fork出的子進程,子進程會繼承父進程的CPU使用偏好,而此時子進程會消耗大量的CPU資源進行數據持久化,子進程會與主進程發生CPU爭搶,這也會導致主進程的CPU資源不足訪問延遲增大。
所以在部署Redis進程時,如果需要開啟RDB和AOF重寫機制,一定不能進行CPU綁定操作
使用Swap
如果你發現Redis突然變得非常慢,每次訪問的耗時都達到了幾百毫秒甚至秒級,那此時就檢查Redis是否使用到了Swap,這種情況下Redis基本上已經無法提供高性能的服務。
我們知道,操作系統提供了Swap機制,目的是為了當內存不足時,可以把一部分內存中的數據換到磁盤上,以達到對內存使用的緩沖。
但當內存中的數據被換到磁盤上后,訪問這些數據就需要從磁盤中讀取,這個速度要比內存慢太多!
尤其是針對Redis這種高性能的內存數據庫來說,如果Redis中的內存被換到磁盤上,對于Redis這種性能極其敏感的數據庫,這個操作時間是無法接受的。可以臨時關閉操作系統Swap
網卡負載過高
特點就是從某個時間點之后就開始變慢,并且一直持續。這時你需要檢查一下機器的網卡流量,是否存在網卡流量被跑滿的情況。
網卡負載過高,在網絡層和TCP層就會出現數據發送延遲、數據丟包等情況。Redis的高性能除了內存之外,就在于網絡IO,請求量突增會導致網卡負載變高。
如果出現這種情況,你需要排查這個機器上的哪個Redis實例的流量過大占滿了網絡帶寬,然后確認流量突增是否屬于業務正常情況,如果屬于那就需要及時擴容或遷移實例,避免這個機器的其他實例受到影響。
原文鏈接:https://blog.csdn.net/weixin_35973945/article/details/124198769
相關推薦
- 2022-10-01 使用301永久重定向和302臨時重定向作用區別詳解_相關技巧
- 2021-12-02 golang配制高性能sql.DB的使用_Golang
- 2023-01-04 Android?Toolbar應用欄使用方法簡介_Android
- 2022-10-16 Python3列表刪除的三種方式實現_python
- 2023-02-26 pandas的apply函數用法詳解_python
- 2022-09-12 Windows系統下安裝tensorflow的配置步驟_python
- 2023-02-17 python?如何獲取文件夾中的全部文件_python
- 2023-07-04 SpringBoot 日志文件:日志的作用?為什么要寫日志?
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支