redis內存

1、內存消耗

    如何查看Redis中內存的消耗情況哪?可以通過 info命令,查看Redis內存消耗的相關指標,從而有助於更好的分析內存。執行命令之後有這麼幾個重要的指標:

屬性名 屬性說明
used_memory Redis分配器分配的內存總量,指Redis存儲的所有數據所佔的內存
used_memory_human 以可讀的形式返回user_memory
used_memory_rss Redis進程佔用的物理內存總量
used_memory_peak used_memory使用的峯值
used_memory_peak_human 可讀格式返回used_memory_peak
used_memory_lua Lua引擎消耗的內存大小
mem_fragmentation_ratio used_memory_rss/used_memory比值,內存碎片率
mem_allocator Redis所使用的內存分配器,默認jemalloc
used_memory:1038744104
used_memory_human:990.62M
used_memory_rss:5811122176
used_memory_peak:4563077088
used_memory_peak_human:4.25G
used_memory_lua:35840
mem_fragmentation_ratio:5.59
mem_allocator:libc

        重點需要關注下mem_fragmentation_ratio這個值:

    mem_fragmentation_ratio > 1 說明多出來的部分名沒有用於數據存儲,而是被內存碎片所消耗,相差越大,說明內存碎片率越嚴重。
    mem_fragmentation_ratio < 1 一般出現在Redis內存交換(Swap)到硬盤導致(used_memory > 可用最大內存時,Redis會把舊的和不適用的數據寫入到硬盤,這塊空間就叫Swap空間),出現這種情況需要格外關注,硬盤速度遠遠慢於內存,Redis性能就會變得很差,甚至僵死。

    1.1、內存消耗的劃分

        Redis的內存主要包括:對象內存+緩衝內存+自身內存+內存碎片。
    這裏寫圖片描述

    1、對象內存

        對象內存是Redis內存中佔用最大一塊,存儲着所有的用戶的數據。Redis所有的數據都採用的是key-value型數據類型,每次創建鍵值對的時候,都要創建兩個對象,key對象和value對象。key對象都是字符串,value對象的存儲方式,五種數據類型–String,List,Hash,Set,Zset。每種存儲方式在使用的時候長度、數據類型不同,則佔用的內存就不同。

    2、緩衝內存

        主要包括:客戶端緩衝、複製積壓緩衝區、AOF緩衝區
        客戶端緩衝:普通的客戶端的連接(大量連接),從客戶端(主要是複製的時候,異地跨機房,或者主節點下有多個從節點),訂閱客戶端(發佈訂閱功能,生產大於消費就會造成積壓)
        複製積壓緩衝:2.8版本之後提供的可重用的固定大小緩衝區用於實現部分複製功能,默認1MB,主要是在主從同步時用到。
        AOF緩衝區:持久化用的,會先寫入到緩衝區,然後根據響應的策略向磁盤進行同步,消耗的內存取決於寫入的命令量和重寫時間,通常很小。

    3、內存碎片

        目前可選的分配器有jemalloc、glibc、tcmalloc默認jemalloc
        出現高內存碎片問題的情況:大量的更新操作,比如append、setrange;大量的過期鍵刪除,釋放的空間無法得到有效利用
        解決辦法:數據對齊,安全重啓(高可用/主從切換)。

    4、自身內存

        主要指AOF/RDB重寫時Redis創建的子進程內存的消耗,Linux具有寫時複製技術(copy-on-write),父子進程會共享相同的物理內存頁,當父進程寫請求時會對需要修改的頁複製出一份副本來完成寫操作。
        

    2、管理內存

        設置上限
        
        Redis默認是無限使用內存。所以在使用的時候儘量的去配置maxmemory,給Redis設置內存使用上限,防止因Redis的無限使用造成系統內存耗盡。有一點需要注意的是maxmemory配置的是Redis實際使用的內存量,即used_memory,由於有內存碎片的存在,所以實際的內存使用比used_memory要大。
        Redis可以動態的執行內存的調整:

    config set maxmemory 6GB

          
          配置內存回收策略
          
          Redis的內存回收機制主要體現在兩個方面上:

      對過期數據的處理
      當內存使用情況達到maxmemory時觸發內存回收策略

          1. 過期鍵的刪除
          惰性刪除:什麼時候執行呢?就是在客戶端讀取帶有超時屬性的鍵時,如果已經超過鍵值設置的過期時間,則刪除並返回空。這樣做的目的主要是爲了節省CPU成本考慮,不需要單獨維護TTL鏈表來處理過期鍵的刪除。但是,如果單獨使用這種方式存在一個問題,如果當前的鍵值永遠不再被訪問呢?就不刪除了嗎?那肯定不行,這就會造成內存泄漏的問題。那Redis是怎麼解決的呢?Redis提供了一個定時任務的刪除機制來做補充。
          
          2. 定時任務刪除
          Redis內部維護了一個定時任務,默認是每秒運行十次。刪除的邏輯如下圖:
      這裏寫圖片描述
          
          內存溢出控制策略
          當Redis使用的內存達到上限maxmemory後,就會根據maxmemory-policy設置的相關策略進行對應的操作,Redis支持一下6中策略:

      策略 說明
      noeviction 默認策略,不會刪除任何數據,拒絕所有寫入操作並返回客戶端錯誤信息(error)OOM command not allowed when used memory
      volatile-lru 只對設置有超時屬性的Key根據LRU算法執行刪除操作,如果沒有可刪除的Key,則回退到noeviction策略
      allkeys-lru 針對所有的key,根據LRU算法執行刪除操作直到回收到足夠內存空間
      allkeys-random 隨機刪除所有的鍵,直到騰出足夠空間
      volatile-random 針對帶有過期屬性的鍵,進行刪除操作,直到騰出足夠空間
      volatile-ttl 根據鍵值對象的ttl屬性,刪除最近將要過期數據。如果沒有,則回退到noviction策略
      發表評論
      所有評論
      還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
      相關文章