成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入分析Redis內存碎片

數據庫 Redis
如果發現Redis存儲數據占用的內存比操作系統分配給Redis的內存小很多,但是數據無法保存,那么可能是內存碎片很多。使用info memory?命令查看內存碎片mem_fragmentation_ratio指標是否正常。

?前言

我們先來看一個問題, 假設Redis實例保存了5GB的數據,現在刪除了2GB的數據,那么Redis進程占用的內存會不會減少呢?

答案是:它可能仍然占用大約5GB內存,即使Redis數據只占用大約3GB。

如果maxmemory不設置該參數,Redis不會觸發內存淘汰策略刪除數據。

Redis會繼續為新寫入的數據分配內存。分配失敗會導致應用程序報錯,當然不會導致宕機。

注:設置maxmemory?參數,執行命令CONFIG SET maxmemory 100mb?,或在redis.conf 配置文件中設置maxmemory 100mb。

使用top命令查看數據是否已經刪除,為什么它仍然占用這么多內存?

釋放的內存去了哪里?

當我們使用top命令查看系統使用情況時,會發現內存依然很高,Redis并沒有真正釋放內存。那么內存都去哪兒了?這時候我們就需要使用info memory命令獲取Redis內存相關的指標。

127.0.0.1:6379> info memory
# Memory
used_memory:1132832 // Redis Amount of memory used to store data
used_memory_human:1.08M // Returns the total amount of memory in human readable form
used_memory_rss:2977792 // From the perspective of the operating system, the total physical memory occupied by the process
used_memory_rss_human:2.84M // used_memory_rss Readability mode display
used_memory_peak:1183808 // The maximum value of memory used, representing the peak value of used_memory

used_memory_peak_human:1.13M // Returns the value of used_memory_peak in a human readable format
used_memory_lua:37888 // Lua The amount of memory consumed by the engine。
used_memory_lua_human:37.00K
maxmemory:2147483648 // The maximum memory value that can be used, in bytes.
maxmemory_human:2.00G // readable form
maxmemory_policy:noeviction // Memory Retirement Policy

mem_fragmentation_ratio:2.79 // The ratio of used_memory_rss & used_memory represents the memory fragmentation rate

Redis進程內存消耗主要由以下幾部分組成:

  • 內存被Redis自己啟動占用
  • 存儲對象數據內存
  • 緩沖區內存:主要由client-output-buffer-limit客戶端輸出緩沖區、copy backlog緩沖區、AOF緩沖區組成
  • 內存碎片

圖片

Redis自身的空進程占用的內存很小,可以忽略不計,而對象內存是最大的,里面存放了所有的數據。

需要注意, 如果緩沖區有大流量的場景很容易失控,導致Redis內存不穩定。

內存碎片過多導致有可用空間不足,無法存儲數據。內存碎片Fragmentation? = used_memory_rss? 實際使用的物理內存(RSS 值)除以 used_memory 實際存儲的數據內存。

什么是內存碎片?

內存碎片會導致內存空間空閑,但無法存儲數據。比如你和女朋友去電影院看電影,你們肯定是要在一起的。

假設現在有 8 個座位,已售出 4 張票,還有 4 張可供購買。不過巧合的是,買票的人很奇怪,都是隔一個座位買票。即使還有4個座位,也不能買順序連接兩個座位的票。

圖片

什么導致內存碎片?

主要有兩個原因:

  • 內存分配器的分配策略
  • 鍵值對的大小不同,刪除操作

下面我們就實際發生的原因進行探討。

1. 內存分配器的分配策略

Redis 默認的內存分配器使用jemalloc?,可選的分配器有:glibc,tcmalloc。

內存分配器不能按需分配,而是使用固定范圍的內存塊進行分配。

比如8字節、16字節……、2KB、4KB,當申請內存最接近固定值時,jemalloc會分配最接近固定值的空間。這樣就會出現內存碎片。

比如程序只需要1.5KB,而內存分配器會分配2KB的空間,那么這0.5KB就是碎片。這樣做的目的是減少內存分配的次數。比如你申請22個字節的空間來存放數據,jemalloc就會分配32個字節。如果后面需要寫入10個字節,則不需要向操作系統申請空間。您可以使用之前請求的 32 個字節。

當一個鍵被刪除時,Redis 不會立即將內存歸還給操作系統。發生這種情況是因為底層內存分配器的管理。例如,大多數已刪除的鍵仍與其他有效鍵分配在同一內存頁中。

此外,為了重用空閑內存塊,分配器刪除了原始 5 GB 數據中的 2 GB。再次向實例添加數據時,Redis的RSS會保持穩定,不會增加太多。因為內存分配器基本上重新使用了之前刪除釋放的2GB內存。

2.鍵值對大小不同,刪除操作

由于內存分配器是按照固定的大小分配內存,因此分配的內存空間通常會大于實際數據占用的大小,這會造成碎片,降低內存的存儲效率。

另外,鍵值對的頻繁修改和刪除導致內存空間的擴大和釋放。例如,如果原來占用32個字節的字符串現在修改為占用20個字節的字符串,那么釋放的12個字節就是空閑空間。

如果下一次數據存儲請求需要申請一個13字節的字符串,剛剛釋放的12字節空間就不能使用,造成碎片。

分片最大的問題:空間總量足夠大,但是這些內存并不連續,可能存不下數據。

mem_fragmentation_ratio = used_memory_rss/ used_memory

如何解決?

首先要判斷是否發生了內存碎片,重點看info memory?命令執行后的mem_fragmentation_ratio指標,表示內存碎片率。

如果1 < mem_fragmentation_ratio < 1.5,可以認為是合理的,如果大于1.5,說明碎片已經超過了50%,我們需要采取一些措施來解決碎片過多的問題。

1. 重啟

最簡單的方法是重新啟動。如果未啟用持久性,數據將丟失。

如果開啟持久化,需要使用RDB或者AOF來恢復數據。如果只有一個實例,數據量大會導致恢復階段長時間無法提供服務,高可用性會大大降低。

2.自動清理內存碎片

Redis在4.0版本之后,提供了內存碎片清理機制。

對于Redis來說,當連續的內存空間被分割成若干個不連續的空間時,操作系統首先將數據移動拼接在一起,釋放掉原來數據占用的空間,形成一個連續的空閑內存空間。

圖片

圖片由作者提供

自動清理雖然好,但也不要亂來。操作系統需要消耗資源將數據移動到新的位置,然后釋放原來的空間。

Redis 操作數據的指令是單線程的,所以在數據復制和移動時,只有清理碎片后才能處理請求,會造成性能損失。

那么問題來了,如何減少對性能的影響來實現自動清理碎片?

問得好,用下面兩個參數來控制內存碎片清理和結束的時機,避免占用過多CPU,減少清理碎片對Redis處理請求的性能影響。

啟用自動內存碎片整理:

CONFIG SET activedefrag yes

這只是為了啟用自動清潔。當清理需要同時滿足以下兩個條件時,就會出發清理操作。

  • 清理條件

active-defrag-ignore-bytes 200mb:內存碎片占用內存達到200MB,開始清理;

active-defrag-threshold-lower 20: 內存碎片空間超過系統分配給Redis空間的20%,開始清理。

  • 避免性能影響

清理時間是有的,需要控制清理對性能的影響。一二設置先分配清理碎片占用的CPU資源,保證碎片可以正常清理,避免對Redis處理請求造成性能影響。

active-defrag-cycle-min 20:自動碎片整理過程中占用CPU時間比例不低于20%,以保證清理任務正常進行。

active-defrag-cycle-max 50:自動清理進程占用CPU時間比例不能高于50%。如果超過,會立即停止清理,避免阻塞 Redis 造成高延遲。

總結

如果發現Redis存儲數據占用的內存比操作系統分配給Redis的內存小很多,但是數據無法保存,那么可能是內存碎片很多。使用info memory?命令查看內存碎片mem_fragmentation_ratio指標是否正常。

然后我們啟用自動清理并合理設置清理時間和CPU資源占用。該機制涉及內存復制,這對 Redis 性能構成潛在風險。如果Redis性能變慢,檢查是否是清理碎片導致的。如果是這樣,減小配置active-defrag-cycle-max的值。

責任編輯:武曉燕 來源: JAVA旭陽
相關推薦

2018-10-25 15:24:10

ThreadLocal內存泄漏Java

2020-12-07 06:23:48

Java內存

2011-03-23 11:01:55

LAMP 架構

2010-09-07 14:21:22

PPPoE協議

2022-04-12 08:30:45

TomcatWeb 應用Servlet

2009-12-16 16:39:01

Visual Stud

2009-06-10 18:12:38

Equinox動態化OSGi動態化

2022-08-30 07:00:18

執行引擎Hotspot虛擬機

2009-12-14 14:50:46

Ruby傳參數

2021-10-29 16:36:53

AMSAndroidActivityMan

2011-09-01 13:51:52

JavaScript

2010-03-08 14:53:48

Linux分區

2009-07-03 11:14:57

2011-06-28 14:11:33

JavaScript

2014-10-30 15:08:21

快速排序編程算法

2009-04-13 16:37:33

JSPWeb標簽

2015-08-03 09:54:26

Java線程Java

2018-12-18 10:11:37

軟件復雜度軟件系統軟件開發

2021-04-13 12:55:06

SpringMVC解析器接口

2023-08-07 07:44:44

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品自产拍在线观看蜜 | 影音先锋欧美资源 | 久久久国产视频 | 色综合99 | 久久国产精品久久久久久 | 国产精品亚洲片在线播放 | 亚洲精品国产一区 | 国产精品一区二区视频 | 雨宫琴音一区二区在线 | 日韩av免费在线观看 | 精品久久久久久红码专区 | 一区二区精品 | 亚洲国产精品成人综合久久久 | 国产一区二区在线免费观看 | 日韩a v在线免费观看 | 伊人精品久久久久77777 | 中文字幕二区 | 欧美精品久久久 | 精品国产91 | 日韩欧美一区二区三区免费观看 | 亚洲国产精品一区 | 成人免费视频7777777 | 91色在线| 在线观看亚洲专区 | 91精品国产综合久久久久久丝袜 | 中文亚洲字幕 | 国产免费一区二区三区 | 久久久久久久久久毛片 | 欧美视频二区 | 人人爽人人爽人人片av | 中文字幕在线播放不卡 | 国产精品久久久久久久久久 | 久久国产精品偷 | 一区二区日韩 | 欧美日韩久久精品 | 一区二区国产精品 | 国产精品免费观看 | 天堂资源 | 福利视频一区 | 亚洲欧美成人影院 | av三级在线观看 |