這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了關於Redis變慢的原因及排查方法的相關問題,下面一起來看一下,希望對大家有幫助。
推薦學習:Redis影片教學
排查想法
如果你的Redis 實例設定了記憶體上限maxmemory,那麼也有可能導致Redis 變慢。
當我們把 Redis 當做純快取使用時,通常會為這個實例設定一個記憶體上限 maxmemory,然後設定一個資料淘汰策略。而當實例的記憶體達到了 maxmemory 後,你可能會發現,在此之後每次寫入新數據,操作延遲變大了。
導致變慢的原因
當Redis 記憶體達到maxmemory 後,每次寫入新的資料之前,Redis 必須先從實例中踢出一部分數據,讓整個實例的記憶體維持在maxmemory 之下,然後才能把新資料寫進來。
這個踢出舊資料的邏輯也是需要消耗時間的,而具體耗時的長短,要取決於你配置的淘汰策略:
具體使用哪種策略,我們需要根據特定的業務場景來配置。一般最常使用的是allkeys-lru / volatile-lru 淘汰策略,它們的處理邏輯是,每次從實例中隨機取出一批key(這個數量可配置),然後淘汰一個最少訪問的key,之後把剩下的key 暫存到一個池子中,繼續隨機取一批key,並與先前池子中的key 比較,再淘汰一個最少訪問的key。以此往復,直到實例記憶體降到 maxmemory 之下。
需要注意的是,Redis 的淘汰資料的邏輯與刪除過期key 的一樣,也是在命令真正執行之前執行的,也就是說它也會增加我們操作Redis 的延遲,而且,寫OPS越高,延遲也會越明顯。
另外,如果此時你的 Redis 實例中還儲存了 bigkey,那麼在淘汰刪除 bigkey 釋放記憶體時,也會耗時比較久。
看到了麼? bigkey 的危害到處都是,這也是前面我提醒你盡量不儲存 bigkey 的原因。
解決方案
#排查想法
導致變慢的原因
#解決方案
#關閉記憶體大頁機制。
首先,你需要查看Redis 機器是否開啟了記憶體大頁:
$ cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never
如果輸出選項是always,就表示目前開啟了記憶體大頁機制,我們需要關掉它:
$ echo never > /sys/kernel/mm/transparent_hugepage/enabled
其實,作業系統提供的記憶體大頁機制,其優點是,可以在一定程式上降低應用程式申請記憶體的次數。
但是對於 Redis 這種對效能和延遲極其敏感的資料庫來說,我們希望 Redis 在每次申請記憶體時,耗時盡量短,所以我不建議你在 Redis 機器上開啟這個機制。
檢查思路
#如果你發現Redis 突然變得非常慢,每次的操作耗時都達到了幾百毫秒甚至秒級,那此時你就需要檢查Redis 是否使用到了Swap,在這種情況下Redis 基本上已經無法提供高效能的服務了。
導致變慢的原因
什麼是 Swap?為什麼使用 Swap 會導致 Redis 的效能下降?
如果你對作業系統有些了解,就會知道作業系統為了緩解記憶體不足對應用程式的影響,允許把一部分記憶體中的資料換到磁碟上,以達到應用程式對記憶體使用的緩衝,這些記憶體資料換到磁碟上的區域,就是Swap。
問題就在於,當記憶體中的資料換到磁碟上後,Redis 再存取這些資料時,就需要從磁碟上讀取,存取磁碟的速度要比存取記憶體慢幾百倍!尤其是針對 Redis 這種對效能要求極高、效能極為敏感的資料庫來說,這個操作延遲是無法接受的。
此時,你需要檢查 Redis 機器的記憶體使用情況,確認是否存在使用了 Swap。你可以透過以下方式來查看 Redis 進程是否使用到了 Swap:
# 先找到 Redis 的进程 ID $ ps -aux | grep redis-server # 查看 Redis Swap 使用情况 $ cat /proc/$pid/smaps | egrep '^(Swap|Size)'
輸出結果如下
Size: 1256 kB Swap: 0 kB Size: 4 kB Swap: 0 kB Size: 132 kB Swap: 0 kB Size: 63488 kB Swap: 0 kB Size: 132 kB Swap: 0 kB Size: 65404 kB Swap: 0 kB Size: 1921024 kB Swap: 0 kB ...
這個結果會列出 Redis 流程的記憶體使用量。
每一行Size 表示Redis 所使用的一塊內存大小,Size 下面的Swap 就表示這塊Size 大小的內存,有多少資料已經被換到磁碟上了,如果這兩個值相等,說明這區塊記憶體的資料都已經完全被換到磁碟上了。
如果只是少量資料被換到磁碟上,例如每一塊 Swap 佔對應 Size 的比例很小,那麼影響並不是很大。如果是幾百兆甚至上 GB 的記憶體被換到了磁碟上,那麼你就需要警惕了,這種情況 Redis 的效能肯定會急劇下降。
解決方案
釋放Redis 的Swap 流程通常要重啟實例,為了避免重啟實例對業務的影響,一般會先進行主從切換,然後釋放舊主節點的Swap,重啟舊主節點實例,待從庫資料同步完成後,再進行主從切換即可。
可見,並在 Redis 使用到 Swap 後,此時的 Redis 性能基本上已達不到高績效的要求(你可以理解為武功被廢),所以你也需要提前預防這種情況。
預防的方法是,你需要對 Redis 機器的記憶體和 Swap 使用情況進行監控,在記憶體不足或使用到 Swap 時警出來,及時處理。
#檢查想法
如果以上產生效能問題的場景,你都規避掉了,而且Redis 也穩定運行了很長一段時間,但在某個時間點之後開始,操作Redis 突然開始變慢了,而且一直持續下去,這種情況又是什麼原因導致?
此時你需要排查 Redis 機器的網路頻寬是否過載,是否有某個執行個體把整台機器的網路頻寬佔滿的狀況。
導致變慢的原因
網路頻寬過載的情況下,伺服器在 TCP 層和網路層就會出現封包發送延遲、遺失封包等情況。
Redis 的高效能,除了操作記憶體之外,就在於網路 IO 了,如果網路 IO 有瓶頸,也會嚴重影響 Redis 的效能。
解決方案
##1) 頻繁短連結
你的業務應用,應該使用長連結操作Redis,避免頻繁的短連接。 頻繁的短連結會導致 Redis 大量時間耗費在連結的建立和釋放上,TCP 的三次握手和四次揮手同樣也會增加存取延遲。2) 操作監控
在前面也提到了,要先預知Redis 變慢的情況發生,不可或缺的就是做好完善的監控。 監控其實就是對採集 Redis 的各項執行時間指標,通常的做法是監控程式定時採集 Redis 的 INFO 訊息,然後根據 INFO 訊息中的狀態資料做資料展示與警報。 這裡我需要提醒你的是,在寫一些監控腳本,或使用開源的監控元件時,也不能掉以輕心。 在寫入監控腳本存取 Redis 時,盡量採用長連結的方式擷取狀態訊息,避免頻繁短連結。同時,你也要注意控制存取 Redis 的頻率,避免影響到業務請求。 在使用一些開源的監控元件時,最好了解這些元件的實作原理,以及正確配置這些元件,防止出現監控元件發生Bug,導致短時大量操作Redis,影響Redis 效能的狀況發生。 我們當時就發生過,DBA 在使用一些開源元件時,因為設定和使用問題,導致監控程式頻繁地與 Redis 建立和斷開連接,導致 Redis 反應變慢。3)其它程式爭搶資源
最後一個需要提醒你的是,你的Redis 機器最好專項專用,只用來部署Redis 實例,不要部署其他應用程序,盡量給Redis 一個相對「安靜」的環境,避免其它程式佔用CPU、記憶體、磁碟資源,導致分配給Redis 的資源不足而受到影響。 推薦學習:以上是一起聊聊Redis變慢的原因及檢驗方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!