欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis內存空間效率問題的深入探究

 更新時間:2021年05月16日 09:23:41   作者:CB  
redis緩存固然高效,可是它會占用我們系統(tǒng)中寶貴的內存資源,那該如何解決呢?這篇文章主要給大家介紹了關于redis內存空間效率問題的相關資料,需要的朋友可以參考下

前言

在使用redis時,我們會遇到一個問題,數據刪除后,數據量已經不大了,但是使用top命令查看,還會發(fā)現(xiàn)redis占用了很對內存。實際上,因為數據刪除后,redis釋放內存由內存分配器管理,不會立刻返回給操作系統(tǒng)。所以,操作系統(tǒng)仍然記錄著給redis分配了大量的內存

這往往會伴隨一個潛在的風險點:Redis 釋放的內存空間可能并不是連續(xù)的,那么,這些不連續(xù)的內存空間很有可能處于一種閑置的狀態(tài)。這就會導致一個問題:雖然有空閑空間,Redis 卻無法用來保存數據,不僅會減少 Redis 能夠實際保存的數據量,還會降低 Redis 運行機器的成本回報率。

什么是內存碎片

通常情況下,內存空間利用率低,往往是因為操作系統(tǒng)發(fā)生了比較嚴重的內存碎片,那么什么是內存碎片呢?可以將內存看成是高鐵上的作為,連續(xù)的空間相當于連座,內存碎片可以看成一個個零散的作為,如果你是3個人出行,火車上沒有三個座位連著的,那么你就沒法買到合適的作為,可能需要換一輛車

內存類似,如果需要申請一個N字節(jié)的連續(xù)空間,但是沒有這么大的連續(xù)空間,那么,這些剩余空間就是內存碎片,redis內存碎片是什么原因導致的呢,了解了原因才有可能比較好的解決

內存碎片形成的原因

一般來說內存碎片形成的原因有兩個,內因是操作系統(tǒng)的內存分配機制,外因是redis的負載特征

內因:內存分配器策略

內存分配器的分配策略就決定了操作系統(tǒng)無法做到“按需分配”。這是因為,內存分配器一般是按固定大小來分配內存,而不是完全按照應用程序申請的內存空間大小給程序分配。

Redis 可以使用 libc、jemalloc、tcmalloc 多種內存分配器來分配內存,默認使用 jemalloc。接下來,我就以 jemalloc 為例,來具體解釋一下。其他分配器也存在類似的問題。

jemalloc 的分配策略之一,是按照一系列固定的大小劃分內存空間,例如 8 字節(jié)、16 字節(jié)、32 字節(jié)、48 字節(jié),…, 2KB、4KB、8KB 等。當程序申請的內存最接近某個固定值時,jemalloc 會給它分配相應大小的空間。

外因:鍵值對大小不一樣和刪改操作

redis通常作為公共緩存和鍵值數據庫對外提供服務,所以對于不同大小的數據,redis申請內存空間大小不一,這是一個外因。

因為內存分配是按照固定大小分配,所以內存空間一般都會比申請的空間大一些,所以本身就會有一些內存碎片,降低內存空間存儲效率。

第二個外因是,這些數據會被刪除和修改,會導致空間空間擴充和釋放,具體來說,一方面,如果修改后的鍵值對變大或變小了,就需要占用額外的空間或者釋放不用的空間。另一方面,刪除的鍵值對就不再需要內存空間了,此時,就會把空間釋放出來,形成空閑空間

一開始,應用 A、B、C、D 分別保存了 3、1、2、4 字節(jié)的數據,并占據了相應的內存空間。然后,應用 D 刪除了 1 個字節(jié),這個 1 字節(jié)的內存空間就空出來了。緊接著,應用 A 修改了數據,從 3 字節(jié)變成了 4 字節(jié)。為了保持 A 數據的空間連續(xù)性,操作系統(tǒng)就需要把 B 的數據拷貝到別的空間,比如拷貝到 D 剛剛釋放的空間中。此時,應用 C 和 D 也分別刪除了 2 字節(jié)和 1 字節(jié)的數據,整個內存空間上就分別出現(xiàn)了 2 字節(jié)和 1 字節(jié)的空閑碎片。如果應用 E 想要一個 3 字節(jié)的連續(xù)空間,顯然是不能得到滿足的。因為,雖然空間總量夠,但卻是碎片空間,并不是連續(xù)的。

好了,到這里,我們就知道了造成內存碎片的內外因素,其中,內存分配器策略是內因,而 Redis 的負載屬于外因,包括了大小不一的鍵值對和鍵值對修改刪除帶來的內存空間變化。

如何判斷是否有內存碎片

Redis 是內存數據庫,內存利用率的高低直接關系到 Redis 運行效率的高低。為了讓用戶能監(jiān)控到實時的內存使用情況,Redis 自身提供了 INFO 命令,可以用來查詢內存使用的詳細信息,命令如下:

INFO memory
# Memory
used_memory:1073741736
used_memory_human:1024.00M
used_memory_rss:1997159792
used_memory_rss_human:1.86G
…
mem_fragmentation_ratio:1.86O memory

INFO memory
# Memory
used_memory:1073741736
used_memory_human:1024.00M
used_memory_rss:1997159792
used_memory_rss_human:1.86G
…
mem_fragmentation_ratio:1.86

這里有一個 mem_fragmentation_ratio 的指標,它表示的就是 Redis 當前的內存碎片率。那么,這個碎片率是怎么計算的呢?其實,就是上面的命令中的兩個指標 used_memory_rss 和 used_memory 相除的結果。

mem_fragmentation_ratio = used_memory_rss/ used_memory

used_memory_rss 是操作系統(tǒng)實際分配給 Redis 的物理內存空間,里面就包含了碎片;而 used_memory 是 Redis 為了保存數據實際申請使用的空間。

我簡單舉個例子。例如,Redis 申請使用了 100 字節(jié)(used_memory),操作系統(tǒng)實際分配了 128 字節(jié)(used_memory_rss),此時,mem_fragmentation_ratio 就是 1.28。

那么,知道了這個指標,我們該如何使用呢?在這兒,我提供一些經驗閾值:

  • mem_fragmentation_ratio大于1小于1.5。這種情況是合理的。這是因為,剛才我介紹的那些因素是難以避免的。畢竟,內因的內存分配器是一定要使用的,分配策略都是通用的,不會輕易修改;而外因由 Redis 負載決定,也無法限制。所以,存在內存碎片也是正常的。
  • mem_fragmentation_ratio大于1.5。 這表明內存碎片率已經超過了 50%。一般情況下,這個時候,我們就需要采取一些措施來降低內存碎片率了。

如何清理內存碎片

當 Redis 發(fā)生內存碎片后,一個“簡單粗暴”的方法就是重啟redis實例,當然這并不是一個優(yōu)雅的方法,重啟會帶來一些問題

  • 如果數據沒有持久化,那么數據會丟失
  • 如果數據持久化了,我們需要通過AOF或RDB進行恢復,恢復時長取決于AOF或RDB的大小,如果只有一個實例,在恢復階段無法提供服務。

幸運的是,從 4.0-RC3 版本以后,Redis 自身提供了一種內存碎片自動清理的方法,我們先來看這個方法的基本機制。還是通過一張圖來看下

在進行碎片清理前,這段 10 字節(jié)的空間中分別有 1 個 2 字節(jié)和 1 個 1 字節(jié)的空閑空間,只是這兩個空間并不連續(xù)。操作系統(tǒng)在清理碎片時,會先把應用 D 的數據拷貝到 2 字節(jié)的空閑空間中,并釋放 D 原先所占的空間。然后,再把 B 的數據拷貝到 D 原來的空間中。這樣一來,這段 10 字節(jié)空間的最后三個字節(jié)就是一塊連續(xù)空間了。到這里,碎片清理結束。

需要注意:碎片清理事由代價的,操作系統(tǒng)需要把多份數據拷貝到新位置,把原有空間釋放出來,這會帶來時間開銷。因為 Redis 是單線程,在數據拷貝時,Redis 只能等著,這就導致 Redis 無法及時處理請求,性能就會降低。而且,有的時候,數據拷貝還需要注意順序,就像剛剛說的清理內存碎片的例子,操作系統(tǒng)需要先拷貝 D,并釋放 D 的空間后,才能拷貝 B。這種對順序性的要求,會進一步增加 Redis 的等待時間,導致性能降低。

那么,有什么辦法可以盡量緩解這個問題嗎?這就要提到,Redis 專門為自動內存碎片清理功機制設置的參數了。我們可以通過設置參數,來控制碎片清理的開始和結束時機,以及占用的 CPU 比例,從而減少碎片清理對 Redis 本身請求處理的性能影響。

首先,Redis 需要啟用自動內存碎片清理,可以把 activedefrag 配置項設置為 yes,命令如下:

config set activedefrag yes

這個命令只是啟用了自動清理功能,但是,具體什么時候清理,會受到下面這兩個參數的控制。這兩個參數分別設置了觸發(fā)內存清理的一個條件,如果同時滿足這兩個條件,就開始清理。在清理的過程中,只要有一個條件不滿足了,就停止自動清理。

  • active-defrag-ignore-bytes 100mb:表示內存碎片數量達到100MB時,開始清理
  • active-defrag-threshold-lower 10:表示內存碎片空間占操作系統(tǒng)給redis分配空間的10%時開始清理

為了盡可能減少碎片清理對 Redis 正常請求處理的影響,自動內存碎片清理功能在執(zhí)行時,還會監(jiān)控清理操作占用的 CPU 時間,而且還設置了兩個參數,分別用于控制清理操作占用的 CPU 時間比例的上、下限,既保證清理工作能正常進行,又避免了降低 Redis 性能。這兩個參數具體如下:

  • active-defrag-cycle-min 25:表示自動清理過程cpu時間筆記不低于25%,保證清理能正常開展
  • active-defrag-cycle-max 75:表示自動清理過程所用 CPU 時間的比例不高于 75%,一旦超過,就停止清理,從而避免在清理時,大量的內存拷貝阻塞 Redis,導致響應延遲升高。

自動內存碎片清理機制在控制碎片清理啟停的時機上,既考慮了碎片的空間占比、對 Redis 內存使用效率的影響,還考慮了清理機制本身的 CPU 時間占比、對 Redis 性能的影響。而且,清理機制還提供了 4 個參數,讓我們可以根據實際應用中的數據量需求和性能要求靈活使用,建議你在實踐中好好地把這個機制用起來。

總結

到此這篇關于redis內存空間效率問題的文章就介紹到這了,更多相關redis內存空間效率內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用高斯Redis實現(xiàn)二級索引的方法

    使用高斯Redis實現(xiàn)二級索引的方法

    本文介紹了如何通過高斯Redis搭建二級索引,二級索引在電商、圖(hexastore)、游戲等領域具有廣泛的應用場景,高斯redis現(xiàn)網亦有很多類似應用,需要的朋友跟隨小編一起看看吧
    2022-07-07
  • Linux安裝單機版Redis的完整步驟

    Linux安裝單機版Redis的完整步驟

    這篇文章主要給大家介紹了關于Linux安裝單機版Redis的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-09-09
  • Redis實現(xiàn)分布式鎖的幾種方法總結

    Redis實現(xiàn)分布式鎖的幾種方法總結

    這篇文章主要介紹了Redis實現(xiàn)分布式鎖的幾種方法總結的相關資料, Redis實現(xiàn)與Zookeeper實現(xiàn)和數據庫實現(xiàn),需要的朋友可以參考下
    2017-07-07
  • redis?手機驗證碼實現(xiàn)示例

    redis?手機驗證碼實現(xiàn)示例

    本文主要介紹了redis?手機驗證碼實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • redis實現(xiàn)sentinel哨兵架構的方法

    redis實現(xiàn)sentinel哨兵架構的方法

    哨兵是一個分布式系統(tǒng),可以在一個架構中運行多個哨兵(sentinel) 進程,這些進程使用流言協(xié)議(gossip protocols)來接收關于Master主服務器是否下線的信息,這篇文章主要介紹了redis實現(xiàn)sentinel哨兵架構,需要的朋友可以參考下
    2022-11-11
  • 淺談Redis常見延遲問題定位與分析

    淺談Redis常見延遲問題定位與分析

    大部分時候,redis延遲很低,但是在某些時刻,有些redis實例會出現(xiàn)很高的響應延時,本文主要介紹了淺談Redis常見延遲問題定位與分析,具有一定的參考價值,感興趣的可以了解一下
    2022-06-06
  • 簡單粗暴的Redis數據備份和恢復方法

    簡單粗暴的Redis數據備份和恢復方法

    這里我們來講解一個簡單粗暴的Redis數據備份和恢復方法,有一個在不同主機上遷移Redis數據的示例,還有一個備份腳本實現(xiàn)的關鍵點提示,一起來看一下:
    2016-06-06
  • 如何使用Redis實現(xiàn)電商系統(tǒng)的庫存扣減

    如何使用Redis實現(xiàn)電商系統(tǒng)的庫存扣減

    在日常開發(fā)中有很多地方都有類似扣減庫存的操作,本文主要介紹了如何使用Redis實現(xiàn)電商系統(tǒng)的庫存扣減,具有一定的參考價值,感興趣的可以了解一下
    2022-01-01
  • Mac中Redis服務啟動時錯誤信息:NOAUTH Authentication required

    Mac中Redis服務啟動時錯誤信息:NOAUTH Authentication required

    這篇文章主要介紹了Mac中使用Redis服務啟動時錯誤信息:"NOAUTH Authentication required"問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Redis不同數據類型使用場景代碼實例

    Redis不同數據類型使用場景代碼實例

    這篇文章主要介紹了Redis不同數據類型使用場景代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12

最新評論