您的位置:首頁 > 教程 > Redis > 淺談Redis變慢的原因及排查方法

淺談Redis變慢的原因及排查方法

2022-06-17 11:12:19 來源:易采站長站 作者:

淺談Redis變慢的原因及排查方法

目錄
原因1:實例內存達到上限原因2:開啟內存大頁原因3:使用Swap原因4:網絡帶寬過載 原因5:其他原因

H3D站長之家-易采站長站-Easck.Com

原因1:實例內存達到上限

排查思路H3D站長之家-易采站長站-Easck.Com

如果你的>

當我們把 Redis 當做純緩存使用時,通常會給這個實例設置一個內存上限 maxmemory,然后設置一個數據淘汰策略。而當實例的內存達到了 maxmemory 后,你可能會發現,在此之后每次寫入新數據,操作延遲變大了。H3D站長之家-易采站長站-Easck.Com

導致變慢的原因H3D站長之家-易采站長站-Easck.Com

當 Redis 內存達到 maxmemory 后,每次寫入新的數據之前,Redis 必須先從實例中踢出一部分數據,讓整個實例的內存維持在 maxmemory 之下,然后才能把新數據寫進來。H3D站長之家-易采站長站-Easck.Com

這個踢出舊數據的邏輯也是需要消耗時間的,而具體耗時的長短,要取決于你配置的淘汰策略:H3D站長之家-易采站長站-Easck.Com

    allkeys-lru:不管 key 是否設置了過期,淘汰最近最少訪問的 keyvolatile-lru:只淘汰最近最少訪問、并設置了過期時間的 keyallkeys-random:不管 key 是否設置了過期,隨機淘汰 keyvolatile-random:只隨機淘汰設置了過期時間的 keyallkeys-ttl:不管 key 是否設置了過期,淘汰即將過期的 keynoeviction:不淘汰任何 key,實例內存達到 maxmeory 后,再寫入新數據直接返回錯誤allkeys-lfu:不管 key 是否設置了過期,淘汰訪問頻率最低的 key(4.0+版本支持)volatile-lfu:只淘汰訪問頻率最低、并設置了過期時間 key(4.0+版本支持)

            具體使用哪種策略,我們需要根據具體的業務場景來配置。一般最常使用的是 allkeys-lru / volatile-lru 淘汰策略,它們的處理邏輯是,每次從實例中隨機取出一批 key(這個數量可配置),然后淘汰一個最少訪問的 key,之后把剩下的 key 暫存到一個池子中,繼續隨機取一批 key,并與之前池子中的 key 比較,再淘汰一個最少訪問的 key。以此往復,直到實例內存降到 maxmemory 之下。H3D站長之家-易采站長站-Easck.Com

            需要注意的是,Redis 的淘汰數據的邏輯與刪除過期 key 的一樣,也是在命令真正執行之前執行的,也就是說它也會增加我們操作 Redis 的延遲,而且,寫 OPS 越高,延遲也會越明顯。H3D站長之家-易采站長站-Easck.Com

    H3D站長之家-易采站長站-Easck.Com

    另外,如果此時你的 Redis 實例中還存儲了 bigkey,那么在淘汰刪除 bigkey 釋放內存時,也會耗時比較久。H3D站長之家-易采站長站-Easck.Com

    看到了么?bigkey 的危害到處都是,這也是前面我提醒你盡量不存儲 bigkey 的原因。H3D站長之家-易采站長站-Easck.Com

    解決方案H3D站長之家-易采站長站-Easck.Com

      避免存儲 bigkey,降低釋放內存的耗時淘汰策略改為隨機淘汰,隨機淘汰比 LRU 要快很多(視業務情況調整)拆分實例,把淘汰 key 的壓力分攤到多個實例上如果使用的是 Redis 4.0 以上版本,開啟 layz-free 機制,把淘汰 key 釋放內存的操作放到后臺線程中執行(配置 lazyfree-lazy-eviction = yes)

      H3D站長之家-易采站長站-Easck.Com

      原因2:開啟內存大頁

      排查思路H3D站長之家-易采站長站-Easck.Com

        我們都知道,應用程序向操作系統申請內存時,是按內存頁進行申請的,而常規的內存頁大小是>linux 內核從 2.6.38 開始,支持了內存大頁機制,該機制允許應用程序以 2MB 大小為單位,向操作系統申請內存。應用程序每次向操作系統申請的內存單位變大了,但這也意味著申請內存的耗時變長。

        導致變慢的原因H3D站長之家-易采站長站-Easck.Com

          當 Redis 在執行后臺 RDB 和 AOF rewrite 時,采用 fork 子進程的方式來處理。但主進程 fork 子進程后,此時的主進程依舊是可以接收寫請求的,而進來的寫請求,會采用 Copy On Write(寫時復制)的方式操作內存數據。也就是說,主進程一旦有數據需要修改,Redis 并不會直接修改現有內存中的數據,而是先將這塊內存數據拷貝出來,再修改這塊新內存的數據,這就是所謂的「寫時復制」。寫時復制你也可以理解成,誰需要發生寫操作,誰就需要先拷貝,再修改。這樣做的好處是,父進程有任何寫操作,并不會影響子進程的數據持久化(子進程只持久化 fork 這一瞬間整個實例中的所有數據即可,不關心新的數據變更,因為子進程只需要一份內存快照,然后持久化到磁盤上)。但是請注意,主進程在拷貝內存數據時,這個階段就涉及到新內存的申請,如果此時操作系統開啟了內存大頁,那么在此期間,客戶端即便只修改 10B 的數據,Redis 在申請內存時也會以 2MB 為單位向操作系統申請,申請內存的耗時變長,進而導致每個寫請求的延遲增加,影響到 Redis 性能。同樣地,如果這個寫請求操作的是一個 bigkey,那主進程在拷貝這個 bigkey 內存塊時,一次申請的內存會更大,時間也會更久??梢?,bigkey 在這里又一次影響到了性能。

          H3D站長之家-易采站長站-Easck.Com

          解決方案H3D站長之家-易采站長站-Easck.Com

          關閉內存大頁機制。H3D站長之家-易采站長站-Easck.Com

          首先,你需要查看 Redis 機器是否開啟了內存大頁:H3D站長之家-易采站長站-Easck.Com

          $ cat /sys/kernel/mm/transparent_hugepage/enabled
          [always] madvise never

          如果輸出選項是 always,就表示目前開啟了內存大頁機制,我們需要關掉它:H3D站長之家-易采站長站-Easck.Com

          $ echo never > /sys/kernel/mm/transparent_hugepage/enabled

          其實,操作系統提供的內存大頁機制,其優勢是,可以在一定程序上降低應用程序申請內存的次數。H3D站長之家-易采站長站-Easck.Com

          但是對于 Redis 這種對性能和延遲極其敏感的數據庫來說,我們希望 Redis 在每次申請內存時,耗時盡量短,所以我不建議你在 Redis 機器上開啟這個機制。H3D站長之家-易采站長站-Easck.Com

          H3D站長之家-易采站長站-Easck.Com

          原因3:使用Swap

          排查思路H3D站長之家-易采站長站-Easck.Com

          如果你發現>

          導致變慢的原因H3D站長之家-易采站長站-Easck.Com

          什么是 Swap?為什么使用 Swap 會導致 Redis 的性能下降?H3D站長之家-易采站長站-Easck.Com

          如果你對操作系統有些了解,就會知道操作系統為了緩解內存不足對應用程序的影響,允許把一部分內存中的數據換到磁盤上,以達到應用程序對內存使用的緩沖,這些內存數據被換到磁盤上的區域,就是 Swap。H3D站長之家-易采站長站-Easck.Com

          問題就在于,當內存中的數據被換到磁盤上后,Redis 再訪問這些數據時,就需要從磁盤上讀取,訪問磁盤的速度要比訪問內存慢幾百倍!尤其是針對 Redis 這種對性能要求極高、性能極其敏感的數據庫來說,這個操作延時是無法接受的。H3D站長之家-易采站長站-Easck.Com

          此時,你需要檢查 Redis 機器的內存使用情況,確認是否存在使用了 Swap。你可以通過以下方式來查看 Redis 進程是否使用到了 Swap:H3D站長之家-易采站長站-Easck.Com

          # 先找到 Redis 的進程 ID
          $ ps -aux | grep redis-server
           
          # 查看 Redis Swap 使用情況
          $ cat /proc/$pid/smaps | egrep '^(Swap|Size)'

          輸出結果如下H3D站長之家-易采站長站-Easck.Com

          Size:               1256 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          Size:                  4 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          Size:                132 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          Size:              63488 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          Size:                132 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          Size:              65404 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          Size:            1921024 kBH3D站長之家-易采站長站-Easck.Com
          Swap:                  0 kBH3D站長之家-易采站長站-Easck.Com
          ...H3D站長之家-易采站長站-Easck.Com

          這個結果會列出 Redis 進程的內存使用情況。H3D站長之家-易采站長站-Easck.Com

          每一行 Size 表示 Redis 所用的一塊內存大小,Size 下面的 Swap 就表示這塊 Size 大小的內存,有多少數據已經被換到磁盤上了,如果這兩個值相等,說明這塊內存的數據都已經完全被換到磁盤上了。H3D站長之家-易采站長站-Easck.Com

          如果只是少量數據被換到磁盤上,例如每一塊 Swap 占對應 Size 的比例很小,那影響并不是很大。如果是幾百兆甚至上 GB 的內存被換到了磁盤上,那么你就需要警惕了,這種情況 Redis 的性能肯定會急劇下降。H3D站長之家-易采站長站-Easck.Com

          解決方案H3D站長之家-易采站長站-Easck.Com

            增加機器的內存,讓 Redis 有足夠的內存可以使用整理內存空間,釋放出足夠的內存供 Redis 使用,然后釋放 Redis 的 Swap,讓 Redis 重新使用內存

            釋放 Redis 的 Swap 過程通常要重啟實例,為了避免重啟實例對業務的影響,一般會先進行主從切換,然后釋放舊主節點的 Swap,重啟舊主節點實例,待從庫數據同步完成后,再進行主從切換即可。H3D站長之家-易采站長站-Easck.Com

            可見,當 Redis 使用到 Swap 后,此時的 Redis 性能基本已達不到高性能的要求(你可以理解為武功被廢),所以你也需要提前預防這種情況。H3D站長之家-易采站長站-Easck.Com

            預防的辦法就是,你需要對 Redis 機器的內存和 Swap 使用情況進行監控,在內存不足或使用到 Swap 時報警出來,及時處理。H3D站長之家-易采站長站-Easck.Com

            H3D站長之家-易采站長站-Easck.Com

            原因4:網絡帶寬過載 

            排查思路H3D站長之家-易采站長站-Easck.Com

            如果以上產生性能問題的場景,你都規避掉了,而且>

            此時你需要排查一下 Redis 機器的網絡帶寬是否過載,是否存在某個實例把整個機器的網路帶寬占滿的情況。H3D站長之家-易采站長站-Easck.Com

            導致變慢的原因H3D站長之家-易采站長站-Easck.Com

            網絡帶寬過載的情況下,服務器在 TCP 層和網絡層就會出現數據包發送延遲、丟包等情況。H3D站長之家-易采站長站-Easck.Com

            Redis 的高性能,除了操作內存之外,就在于網絡 IO 了,如果網絡 IO 存在瓶頸,那么也會嚴重影響 Redis 的性能。H3D站長之家-易采站長站-Easck.Com

            解決方案H3D站長之家-易采站長站-Easck.Com

              及時確認占滿網絡帶寬 Redis 實例,如果屬于正常的業務訪問,那就需要及時擴容或遷移實例了,避免因為這個實例流量過大,影響這個機器的其他實例。運維層面,你需要對 Redis 機器的各項指標增加監控,包括網絡流量,在網絡流量達到一定閾值時提前報警,及時確認和擴容。

              H3D站長之家-易采站長站-Easck.Com

              原因5:其他原因

              1)>

              你的業務應用,應該使用長連接操作 Redis,避免頻繁的短連接。H3D站長之家-易采站長站-Easck.Com

              頻繁的短連接會導致 Redis 大量時間耗費在連接的建立和釋放上,TCP 的三次握手和四次揮手同樣也會增加訪問延遲。H3D站長之家-易采站長站-Easck.Com

              2) 運維監控H3D站長之家-易采站長站-Easck.Com

              前面我也提到了,要想提前預知 Redis 變慢的情況發生,必不可少的就是做好完善的監控。H3D站長之家-易采站長站-Easck.Com

              監控其實就是對采集 Redis 的各項運行時指標,通常的做法是監控程序定時采集 Redis 的 INFO 信息,然后根據 INFO 信息中的狀態數據做數據展示和報警。H3D站長之家-易采站長站-Easck.Com

              這里我需要提醒你的是,在寫一些監控腳本,或使用開源的監控組件時,也不能掉以輕心。H3D站長之家-易采站長站-Easck.Com

              在寫監控腳本訪問 Redis 時,盡量采用長連接的方式采集狀態信息,避免頻繁短連接。同時,你還要注意控制訪問 Redis 的頻率,避免影響到業務請求。H3D站長之家-易采站長站-Easck.Com

              在使用一些開源的監控組件時,最好了解一下這些組件的實現原理,以及正確配置這些組件,防止出現監控組件發生 Bug,導致短時大量操作 Redis,影響 Redis 性能的情況發生。H3D站長之家-易采站長站-Easck.Com

              我們當時就發生過,DBA 在使用一些開源組件時,因為配置和使用問題,導致監控程序頻繁地與 Redis 建立和斷開連接,導致 Redis 響應變慢。H3D站長之家-易采站長站-Easck.Com

              3)其它程序爭搶資源H3D站長之家-易采站長站-Easck.Com

              最后需要提醒你的是,你的 Redis 機器最好專項專用,只用來部署 Redis 實例,不要部署其他應用程序,盡量給 Redis 提供一個相對「安靜」的環境,避免其它程序占用 CPU、內存、磁盤資源,導致分配給 Redis 的資源不足而受到影響。H3D站長之家-易采站長站-Easck.Com

              到此這篇關于淺談Redis變慢的原因及排查方法的文章就介紹到這了,更多相關Redis變慢內容請搜索易采站長站以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持易采站長站!H3D站長之家-易采站長站-Easck.Com

              如有侵權,請聯系QQ:279390809 電話:15144810328

相關文章

  • redis 數據刪除策略和逐出算法的問題小結

    redis 數據刪除策略和逐出算法的問題小結

    數據存儲和有效期 在 redis 工作流程中,過期的數據并不需要馬上就要執行刪除操作。因為這些刪不刪除只是一種狀態表示,可以 異步 的去處理,在不忙的時候去把這些不緊急的刪除操
    2020-06-12
  • Redis的持久化方案詳解

    Redis的持久化方案詳解

    Redis支持RDB與AOF兩種持久化機制,持久化可以避免因進程異常退出或down機導致的數據丟失問題,在下次重啟時能利用之前的持久化文件實現數據恢復。 RDB持久化 RDB持久化即通過創建快
    2020-03-18
  • redis操作學習記錄

    redis操作學習記錄

    本文實例總結了redis操作。,具體如下: 相關內容: 雖然有參考文檔,而且記憶太多也是耗腦,但學習的時候還是想要有個系統劃分開知識點的文檔,即使不要求去細致記憶,但劃分開
    2020-04-28
  • mac下redis安裝、設置、啟動停止方法詳解

    mac下redis安裝、設置、啟動停止方法詳解

    需要下載release版本,下載地址: http://download.redis.io/releases/ 我這里下載的是: http://download.redis.io/releases/redis-3.2.5.tar.gz 解壓到/usr/local/redis目錄中,然后依次執行以下命令: cd /usr/loca
    2020-02-07
  • Spring boot+redis實現消息發布與訂閱的代碼

    Spring boot+redis實現消息發布與訂閱的代碼

    一.創建spring boot項目 dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId
    2020-04-28
  • 使用Redis實現微信步數排行榜功能

    使用Redis實現微信步數排行榜功能

    1. 前言 之前寫過一篇博客,講解的是Redis的5種數據結構及其常用命令,當時有讀者評論,說希望了解下這5種數據結構各自的使用場景,不過一直也沒來得及寫。 碰巧,在3月份找工作面
    2020-06-04
  • 使用SpringBoot?+?Redis?實現接口限流的方式

    使用SpringBoot?+?Redis?實現接口限流的方式

    目錄配置限流注解定制 RedisTemplateLua 腳本注解解析接口測試全局異常處理Redis 除了做緩存,還能干很多很多事情:分布式鎖、限流、處理請求接口冪等性。。。太多太多了配置首先我們創建一個> org.springframework.boot spring-boot-starter-dat
    2022-05-28
  • Redis實現分布式Session管理的機制詳解

    Redis實現分布式Session管理的機制詳解

    一. Redis實現分布式Session管理1. Memcached管理機制2. Redis管理機制1.redis的session管理是利用spring提供的session管理解決方案,將一個應用session交給Redis存儲,整個應用中所有session的請求都會去redis中獲取對應的session數據。二. SpringBoot項目開發Session管理1. 引入依賴pop.xml
    2022-05-28
色七七影院_香港三级台湾三级在线播放_男人放进女人阳道猛进猛出