redis是一個單線程的架構,所有的操作全部都在一個主線程中完成。所以一旦Redis發生阻塞,那將是一場噩夢。接下來,我們就來看下對于Redis發生阻塞問題。如何排查以及解決。
Redis數據結構或API使用不合理
存在大對象且對大對象進行復雜的較高的命令
1、對一個有千萬個元素的hash執行hgetall操作, 或del操作.類似的這種操作都會造成Redis阻塞
2、對于這種大對象可以采用redis-cli -h {host} -p {port} bigkeys 來查看。但是該命令只能查詢某類型中的其中最大的一個key。如果你想查詢多個。可以采用修改redis-cli源代碼的方式(Redis的源代碼是C)。如果不想修 改源代碼的話也可以使用scan來完成。
對于Scan命令需要注意。該命令只能掃描單臺Redis上的數據。如果你是一個集群,需要每臺機器執行一遍。但是如果你使用開源的客戶端的話(比如:JAVA的Lettuce客戶端)就已經幫你把scan命令實現為可以掃描整個集群了。
3、然后對大對象進行拆分。具體拆分要視業務而定了。
Redis的CPU使用率接近100%
1、從機同步主機數據。從機接受到rdb文件后從磁盤加載數據
2、主從持久化數據。
3、將cpu使用率達到100%,有可能是真實業務訪問量確實很大。單臺Redis達到每秒處理6萬+的請求。這個時候就只能做水平擴展了
4、如果Redis每秒操作數只有幾百,或者幾千,且cpu還是很高的話就有可能使用了高算法復雜度的命令。例如hgetall。還有一種可能是內存的過度優化導致。這種情況目前暫時沒有遇到,但也納入考慮范圍。
Cpu競爭
1、Redis是一個CPU密集型的應用,不適合和其他CPU密集的服務部署在一起。
2、在生產環境中,我們一臺服務器的配置是32核邏輯cpu, 256GB內存。每臺機器如果只部署一臺Redis比較浪費。所以可能會一臺機器部署多個Redis。通常會將Redis進程綁定到CPU上。但是在生成RDB文件或者AOF持久話時,就會產生子進程。這樣子進程與父進程會產生CPU競爭。所以當開啟持久化或者主節點。不建議綁定CPU
內存交換
Redis是一個內存型數據庫,所有數據全部放在內存中。所以強烈建議不開啟內存交換
網絡問題
主從同步網絡延遲較大的話,導致從機經常斷線重連。如果斷線時間久了。導致從機再次連接上主機時會全量同步,這時主機,從機都會收到影響