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

Redis關(guān)于內(nèi)存碎片的解決方法

 更新時(shí)間:2024年07月19日 09:37:33   作者:矩陣科學(xué)  
今天生產(chǎn)機(jī)報(bào)內(nèi)存爆滿(mǎn)異常被叫過(guò)去查看問(wèn)題,通過(guò)各種排除最終定位到了Redis的內(nèi)存碎片的問(wèn)題,這篇博客將詳細(xì)介紹Redis內(nèi)存碎片問(wèn)題并給出最佳實(shí)踐解決此問(wèn)題,需要的朋友可以參考下

Redis的內(nèi)存碎片原理

先引用Redis官方的原話(huà):

當(dāng)鍵被刪除時(shí),Redis 并不總是會(huì)釋放(歸還)內(nèi)存給操作系統(tǒng)。這不是 Redis 的特別之處,但這是大多數(shù) malloc() 實(shí)現(xiàn)的工作方式。例如,如果您用 5GB 的數(shù)據(jù)填充一個(gè)實(shí)例,然后刪除相當(dāng)于 2GB 的數(shù)據(jù),則駐留集大?。ㄒ卜Q(chēng)為 RSS,即進(jìn)程消耗的內(nèi)存頁(yè)數(shù))可能仍約為 5GB,即使 Redis 聲稱(chēng)用戶(hù)內(nèi)存約為 3GB。發(fā)生這種情況的原因是底層分配器無(wú)法輕松釋放內(nèi)存。例如,通常大多數(shù)被刪除的鍵都分配在與仍然存在的其他鍵相同的頁(yè)面上。

內(nèi)部碎片

首先介紹一下Redis內(nèi)存管理原理,操作系統(tǒng)內(nèi)存管理思想一致是按照固定大小內(nèi)存單位來(lái)分配而非按需分配,為了減少頻繁分配內(nèi)存,Linux下默認(rèn)一次分配內(nèi)存單位是4KB,Redis的內(nèi)存也是按照單位進(jìn)行分配的,例如范圍有 8、16、32、64、128、256、512 字節(jié)為單位的大小,也有大的內(nèi)存單位如2KB、4KB等。例如存儲(chǔ)一個(gè)鍵值對(duì)大小為29字節(jié),則會(huì)分配一個(gè)32字節(jié)的連續(xù)內(nèi)存。那么就會(huì)造成3個(gè)字節(jié)的內(nèi)存碎片,這3個(gè)字節(jié)就不會(huì)被分配給其他鍵值對(duì)。這個(gè)是內(nèi)在的原因,稱(chēng)為內(nèi)部碎片。

在這里插入圖片描述

在這里插入圖片描述

外部碎片

Redis分配內(nèi)存時(shí),會(huì)根據(jù)需要申請(qǐng)一段連續(xù)的內(nèi)存空間。但當(dāng)Redis刪除或修改數(shù)據(jù)時(shí),釋放的內(nèi)存空間并不一定能被立即重新利用,尤其是當(dāng)這些空閑內(nèi)存空間大小不一致時(shí),就可能導(dǎo)致內(nèi)存碎片的出現(xiàn)。Redis釋放的內(nèi)存有可能是不連續(xù)的,這種不連續(xù)的內(nèi)存很可能無(wú)法再次使用,最終造成了內(nèi)存的浪費(fèi),這種空閑但是無(wú)法使用的內(nèi)存便是內(nèi)存碎片。比如說(shuō)現(xiàn)在客戶(hù)端存了100個(gè)鍵值對(duì)(每個(gè)鍵值對(duì)大小53字節(jié)),占用了一片連續(xù)的存儲(chǔ)空間,分配內(nèi)存單位為32字節(jié),一共用了640個(gè)字節(jié),如果這個(gè)時(shí)候刪除了中間的1個(gè)鍵值對(duì),那么中間將空出64個(gè)字節(jié),這64個(gè)字節(jié)可能對(duì)于大于32字節(jié)的鍵值對(duì)無(wú)法有效使用(小于32字節(jié)的內(nèi)存申請(qǐng)可能可以重新分配,但是概率較?。蜁?huì)造成內(nèi)存碎片。這些碎片稱(chēng)為外部碎片

在這里插入圖片描述

總結(jié):使用大白話(huà)說(shuō)就是固定的內(nèi)存分配單位就像一個(gè)個(gè)標(biāo)準(zhǔn)化的箱子,箱子有8、16、32、64等規(guī)格的,而你的物品假設(shè)為33規(guī)格的那么就需要連續(xù)的33內(nèi)存存放,因此申請(qǐng)內(nèi)存的時(shí)候可以分配連續(xù)的32+8的內(nèi)存,但是如果中間只有32的內(nèi)存,另外的8是不連續(xù)的,那么是無(wú)法分配這32內(nèi)存,只能空著。除非剛好有一個(gè)小于32的對(duì)象,就可以被分配給到。

為了提高內(nèi)存使用的效率,Redis內(nèi)部使用內(nèi)存分配器來(lái)對(duì)內(nèi)存的申請(qǐng)和釋放進(jìn)行管理。Redis使用的內(nèi)存分配器默認(rèn)是jemalloc。

會(huì)導(dǎo)致的問(wèn)題

一般而言,存取較小的鍵值對(duì)不太會(huì)導(dǎo)致內(nèi)存碎片的問(wèn)題,但是如果存儲(chǔ)非常大的復(fù)合數(shù)據(jù)結(jié)構(gòu)(Hash、Set、List),并且對(duì)這些對(duì)象頻繁的修改、刪除等操作,那么可能這個(gè)對(duì)象的實(shí)際大小假設(shè)為1.5GB,但是存儲(chǔ)系統(tǒng)分配給Redis用來(lái)存儲(chǔ)這個(gè)對(duì)象的實(shí)際內(nèi)存為8個(gè)GB。這就會(huì)導(dǎo)致內(nèi)存爆滿(mǎn)的問(wèn)題,而多出的這6.5GB其實(shí)就是內(nèi)存碎片導(dǎo)致的。

查看內(nèi)存碎片

登錄到Redis客戶(hù)端,輸入命令info或者info memory就可以查看到內(nèi)存信息,如下:

127.0.0.1:7001> info

# Server
redis_version:7.2.5
...
# Memory
used_memory:1853040
used_memory_human:1.77M
used_memory_rss:9101312
used_memory_rss_human:8.68M
used_memory_peak:1902032
used_memory_peak_human:1.81M
used_memory_peak_perc:97.42%
used_memory_overhead:1632076
used_memory_startup:1596680
used_memory_dataset:220964
used_memory_dataset_perc:86.19%
allocator_allocated:2207416
allocator_active:2572288
allocator_resident:4976640
total_system_memory:1019793408
total_system_memory_human:972.55M
used_memory_lua:31744
used_memory_vm_eval:31744
used_memory_lua_human:31.00K
used_memory_scripts_eval:0
number_of_cached_scripts:0
number_of_functions:0
number_of_libraries:0
used_memory_vm_functions:32768
used_memory_vm_total:64512
used_memory_vm_total_human:63.00K
used_memory_functions:184
used_memory_scripts:184
used_memory_scripts_human:184B
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.17
allocator_frag_bytes:364872
allocator_rss_ratio:1.93
allocator_rss_bytes:2404352
rss_overhead_ratio:1.83
rss_overhead_bytes:4124672
mem_fragmentation_ratio:4.97
mem_fragmentation_bytes:7271160
mem_not_counted_for_evict:0
mem_replication_backlog:20508
mem_total_replication_buffers:20504
mem_clients_slaves:0
mem_clients_normal:3856
mem_cluster_links:10720
mem_aof_buffer:0
mem_allocator:jemalloc-5.3.0
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0

對(duì)上面字段解釋如下:

內(nèi)存使用概述
used_memory: Redis 分配的內(nèi)存總量(字節(jié))。
used_memory_human: 以人類(lèi)可讀格式表示的 used_memory(例如:1.77M)。
used_memory_rss: 從操作系統(tǒng)角度來(lái)看,Redis 使用的實(shí)際內(nèi)存(駐留集大?。?
used_memory_rss_human: 以人類(lèi)可讀格式表示的 used_memory_rss(例如:8.68M)。
內(nèi)存峰值
used_memory_peak: Redis 歷史上使用的最大內(nèi)存量。
used_memory_peak_human: 以人類(lèi)可讀格式表示的 used_memory_peak。
used_memory_peak_perc: 當(dāng)前內(nèi)存使用量相對(duì)于歷史峰值的百分比。
內(nèi)存開(kāi)銷(xiāo)
used_memory_overhead: Redis 的內(nèi)存開(kāi)銷(xiāo),包括數(shù)據(jù)結(jié)構(gòu)、客戶(hù)端連接、備份等的內(nèi)存。
used_memory_startup: Redis 啟動(dòng)時(shí)消耗的初始內(nèi)存。
used_memory_dataset: 實(shí)際存儲(chǔ)數(shù)據(jù)所使用的內(nèi)存。
used_memory_dataset_perc: 數(shù)據(jù)集占用的內(nèi)存相對(duì)于總內(nèi)存使用量的百分比。
內(nèi)存分配器
allocator_allocated: 通過(guò)內(nèi)存分配器 jemalloc 分配的內(nèi)存。
allocator_active: 內(nèi)存分配器 jemalloc 實(shí)際使用的內(nèi)存。
allocator_resident: jemalloc 分配的駐留內(nèi)存。
系統(tǒng)內(nèi)存
total_system_memory: 系統(tǒng)總內(nèi)存。
total_system_memory_human: 以人類(lèi)可讀格式表示的系統(tǒng)總內(nèi)存。
Lua 腳本
used_memory_lua: Lua 腳本使用的內(nèi)存。
used_memory_vm_eval: Lua 腳本虛擬機(jī)使用的內(nèi)存(評(píng)估腳本時(shí))。
used_memory_lua_human: 以人類(lèi)可讀格式表示的 used_memory_lua。
used_memory_scripts_eval: 用于腳本評(píng)估的內(nèi)存。
緩存的腳本
number_of_cached_scripts: 緩存的腳本數(shù)量。
number_of_functions: 注冊(cè)的函數(shù)數(shù)量。
number_of_libraries: 加載的庫(kù)數(shù)量。
虛擬內(nèi)存
used_memory_vm_functions: 虛擬內(nèi)存中函數(shù)使用的內(nèi)存。
used_memory_vm_total: 虛擬內(nèi)存總使用量。
used_memory_vm_total_human: 以人類(lèi)可讀格式表示的 used_memory_vm_total。
腳本和函數(shù)
used_memory_functions: 函數(shù)使用的內(nèi)存。
used_memory_scripts: 腳本使用的內(nèi)存。
used_memory_scripts_human: 以人類(lèi)可讀格式表示的 used_memory_scripts。
最大內(nèi)存設(shè)置
maxmemory: Redis 配置的最大可用內(nèi)存。
maxmemory_human: 以人類(lèi)可讀格式表示的 maxmemory。
maxmemory_policy: 內(nèi)存超過(guò)最大值時(shí)的處理策略(例如:noeviction 表示不驅(qū)逐)。
內(nèi)存碎片率
allocator_frag_ratio: 內(nèi)存分配器碎片率(分配的內(nèi)存與實(shí)際使用的內(nèi)存之比)。
allocator_frag_bytes: 內(nèi)存分配器碎片字節(jié)數(shù)。
allocator_rss_ratio: 分配器駐留集大小比率(分配的內(nèi)存與駐留內(nèi)存之比)。
allocator_rss_bytes: 分配器駐留內(nèi)存字節(jié)數(shù)。
rss_overhead_ratio: RSS 的開(kāi)銷(xiāo)比率。
rss_overhead_bytes: RSS 的開(kāi)銷(xiāo)字節(jié)數(shù)。
mem_fragmentation_ratio: 內(nèi)存碎片總比率。
mem_fragmentation_bytes: 內(nèi)存碎片字節(jié)數(shù)。
其他內(nèi)存統(tǒng)計(jì)
mem_not_counted_for_evict: 不計(jì)入驅(qū)逐的內(nèi)存。
mem_replication_backlog: 復(fù)制日志的內(nèi)存。
mem_total_replication_buffers: 總復(fù)制緩沖區(qū)的內(nèi)存。
mem_clients_slaves: 從客戶(hù)端使用的內(nèi)存。
mem_clients_normal: 正常客戶(hù)端使用的內(nèi)存。
mem_cluster_links: 集群鏈接使用的內(nèi)存。
mem_aof_buffer: AOF(追加文件)緩沖區(qū)的內(nèi)存。
mem_allocator: 使用的內(nèi)存分配器(如 jemalloc-5.3.0)。
active_defrag_running: 活動(dòng)的碎片整理狀態(tài)(是否正在運(yùn)行)。
lazyfree_pending_objects: 懶惰釋放待處理對(duì)象的數(shù)量。
lazyfreed_objects: 懶惰釋放的對(duì)象數(shù)量。

最重要的是找到如下幾個(gè)字段:

INFO memory
# Memory
used_memory:1074741736
used_memory_human:1024.30M
used_memory_rss:1997159792
used_memory_rss_human:1.86G
…
mem_fragmentation_ratio:1.86

這里有一個(gè)mem_fragmentation_ratio指標(biāo)非常重要,它表示的就是Redis當(dāng)前的內(nèi)存碎片率。它是used_memory_rssused_memory相除的結(jié)果:mem_fragmentation_ratio = used_memory_rss/ used_memoryused_memory_rss 等于碎片內(nèi)存+時(shí)間數(shù)據(jù)使用內(nèi)存,也就是操作系統(tǒng)分給Redis的實(shí)際內(nèi)存。used_memory是Redis存儲(chǔ)數(shù)據(jù)實(shí)際使用的內(nèi)存??梢园l(fā)現(xiàn)如果不存在碎片內(nèi)存,那么mem_fragmentation_ratio=1,但是這是最理想的情況,一般而言這個(gè)值為1.2較為健康,范圍如下:

  • 1.5 > mem_fragmentation_ratio > 1:內(nèi)存碎片在合理范圍內(nèi)。
  • mem_fragmentation_ratio > 1.5:需要考慮降低內(nèi)存碎片率。
  • mem_fragmentation_ratio < 1:Redis沒(méi)有足夠的內(nèi)存可以使用了,會(huì)導(dǎo)致redis一部分的內(nèi)存數(shù)據(jù)會(huì)被換到swap中(硬盤(pán)中),之后redis訪問(wèn)swap中的數(shù)據(jù)延遲會(huì)變大,性能下降。

解決方法

重啟Redis

低于4.0-RC3版本的Redis 并沒(méi)有內(nèi)置的內(nèi)存碎片整理工具。如果想要清理內(nèi)存碎片,可以通過(guò)重啟的方式。當(dāng)Redis重新啟動(dòng)時(shí),它會(huì)通過(guò)RDB持久化功能將數(shù)據(jù)存儲(chǔ)到磁盤(pán),然后再?gòu)拇疟P(pán)加載數(shù)據(jù)到內(nèi)存,這個(gè)過(guò)程可以有效地清理內(nèi)存碎片。但這種方法會(huì)導(dǎo)致服務(wù)的臨時(shí)中斷。因此非常不推薦!

配置 active-defrag

Active-defrag(主動(dòng)碎片整理)是 Redis 的一個(gè)功能,用于在后臺(tái)自動(dòng)整理內(nèi)存碎片,提升內(nèi)存利用率和性能。內(nèi)存碎片是指內(nèi)存塊之間存在空隙,導(dǎo)致內(nèi)存使用效率下降。通過(guò)主動(dòng)碎片整理,Redis 可以減少這些空隙,提高內(nèi)存的有效利用。

從4.0-RC3版本開(kāi)始引入了active-defrag 特性。可以在不重啟的情況下,自動(dòng)進(jìn)行碎片清理。開(kāi)啟配置如下,此選項(xiàng)的默認(rèn)值是關(guān)閉的,激活碎片整理可能會(huì)占據(jù)一些 CPU 時(shí)間。手動(dòng)開(kāi)啟如下:

redis> config set activedefrag yes 

注意:自動(dòng)清理內(nèi)存碎片的功能需要該Redis的內(nèi)存分配器是jemalloc時(shí)才能啟用。啟用后需要同時(shí)滿(mǎn)足下面2個(gè)參數(shù)的設(shè)置條件時(shí)才會(huì)觸發(fā)自動(dòng)清理。如果使用手動(dòng)開(kāi)啟而redis.conf文件中沒(méi)有配置,那么會(huì)使用默認(rèn)值進(jìn)行碎片整理。

active-defrag-ignore-bytes 100mb    # 默認(rèn)100MB,表示內(nèi)存碎片空間達(dá)到100MB時(shí)才會(huì)整理碎片
active-defrag-threshold-lower 10    # 默認(rèn)10,表示內(nèi)存碎片空間占OS分配給redis的物理內(nèi)存空間的比例達(dá)到10%時(shí),即碎片率為1.1才整理

注意:配置碎片自動(dòng)整理會(huì)占用主線(xiàn)程,如果配置不合理會(huì)導(dǎo)致主線(xiàn)程阻塞,因此下面配置很關(guān)鍵。

active-defrag-cycle-min 1  # 默認(rèn)1,表示自動(dòng)清理過(guò)程所用 CPU 時(shí)間的比例不低于1%,保證清理能正常開(kāi)展;
active-defrag-cycle-max 25 # 默認(rèn)25,表示自動(dòng)清理過(guò)程所用 CPU 時(shí)間的比例不高于 25%,一旦超過(guò),就停止清理,從而避免在清理時(shí),大量的內(nèi)存拷貝阻塞 Redis,導(dǎo)致響應(yīng)延遲升高。

另外,一開(kāi)始也可以在配置文件中啟用和配置主動(dòng)碎片整理,可以在 Redis 配置文件(redis.conf)中設(shè)置以下選項(xiàng),下面的都是Redis7.0配置文件的默認(rèn)值:

active-defrag yes #啟用或禁用主動(dòng)碎片整理。
active-defrag-ignore-bytes 100mb #小于此值的內(nèi)存片段將被忽略,不進(jìn)行碎片整理。
active-defrag-threshold-lower 10 # 低于此碎片率百分比時(shí)不進(jìn)行碎片整理。(碎片率1.1)
active-defrag-threshold-upper 100 # 超過(guò)此碎片率百分比時(shí)最大限度進(jìn)行碎片整理。(碎片率2)
active-defrag-cycle-min 1 # 最小碎片整理周期百分比,控制最小CPU資源用于碎片整理。
active-defrag-cycle-max 25 #最大碎片整理周期百分比,控制最大CPU資源用于碎片整理。
active-defrag-max-scan-fields 1000 #一次最大掃描字段個(gè)數(shù)

其他關(guān)于內(nèi)存的命令如下:

在Redis客戶(hù)端可以通過(guò)下面命令查看更加具體的內(nèi)存情況:

> MEMORY HELP
MEMORY DOCTOR                        - 輸出內(nèi)存問(wèn)題報(bào)告
MEMORY USAGE <key> [SAMPLES <count>] - 估計(jì)key的內(nèi)存使用情況
MEMORY STATS                         - 顯示內(nèi)存使用情況詳細(xì)信息
MEMORY PURGE                         - 要求分配器釋放內(nèi)存,主線(xiàn)程阻塞式執(zhí)行
MEMORY MALLOC-STATS                  - 顯示分配器內(nèi)部統(tǒng)計(jì)信息

查看一個(gè)bigkey的內(nèi)存占用:

> memory usage mybigkey51344216

查看 內(nèi)存詳細(xì)情況

> memory stats
peak.allocated #redis啟動(dòng)以來(lái),allocator分配的內(nèi)存峰值,單位字節(jié);同INFO的used_memory_peak
2604763296
total.allocated #allocator 當(dāng)前分配的內(nèi)存總字節(jié)數(shù);同 INFO命令used_memeory
595052416
startup.allocated #Redis啟動(dòng)完成消耗的內(nèi)存字節(jié)數(shù);同INFO的used_memory_startup
11403768
replication.backlog #Redis復(fù)制積壓緩存區(qū)內(nèi)存字節(jié)數(shù);同INFO的repl_backlog_size
0
clients.slaves #所有副本節(jié)點(diǎn)內(nèi)存消耗總字節(jié)數(shù)(查詢(xún)輸出緩沖區(qū),連接內(nèi)存消耗)
0
clients.normal #Redis所有常規(guī)客戶(hù)端內(nèi)存消耗總字節(jié)數(shù)(查詢(xún)輸出緩沖區(qū),連接內(nèi)存消耗)
207724178
aof.buffer #當(dāng)前和重寫(xiě)AOF緩沖區(qū)內(nèi)存消耗總字節(jié)數(shù);同 INFO命令aof_buffer_length和aof_rewrite_buffer_length之和
0
lua.caches
30536
db.0
overhead.hashtable.main #每個(gè)數(shù)據(jù)庫(kù)中元數(shù)據(jù)占用的額外內(nèi)存字節(jié)數(shù)。(redis的db就是一張hash表,首先就是這張hash表使用的內(nèi)存,每一個(gè)key-value對(duì)都有一個(gè)dictEntry來(lái)記錄他們的關(guān)系,元信息便包含該db中所有dictEntry使用的內(nèi)存, redis使用redisObject來(lái)描述value所對(duì)應(yīng)的不同數(shù)據(jù)類(lèi)型(string、list、hash、set、zset),那么redisObject占用的空間也計(jì)算在元信息中。
10823332
overhead.hashtable.expires #用于存儲(chǔ)key的過(guò)期時(shí)間耗費(fèi)的內(nèi)存資源。
865120
db.1
overhead.hashtable.main
275384
overhead.hashtable.expires
77552
....
overhead.total #Redis 額外內(nèi)存消耗總字節(jié)數(shù),例如:startup.allocated, replication.backlog, clients.slaves, clients.normal, aof.buffer 以及管理keyspace使用的內(nèi)部數(shù)據(jù)接口消耗的內(nèi)存字節(jié)數(shù) 同INFO的used_memory_overhead
233196498
keys.count #整個(gè)redis實(shí)例key的個(gè)數(shù)
183900
keys.bytes-per-key #每個(gè)key平均字節(jié)數(shù)
3173
dataset.bytes #Redis 實(shí)例中數(shù)據(jù)占用的總字節(jié)數(shù),計(jì)算方法total.allocated減去overhead.total
361855918
dataset.percentage #Redis 數(shù)據(jù)消耗內(nèi)存占總內(nèi)存的百分比
61.998931884765625
peak.percentage #當(dāng)前內(nèi)存消耗占峰值內(nèi)存消耗的百分比
22.844778060913086
fragmentation #同 INFO的 mem_fragmentation_ratio
0.96442300081253052

注意:以上命令是使用了內(nèi)存分配器 jemalloc的情況下才能使用!Redis默認(rèn)使用的是jemalloc分配器。 Redis 使用 jemalloc 作為默認(rèn)的內(nèi)存分配器。jemalloc 會(huì)將內(nèi)存劃分為不同大小的塊,并在需要時(shí)分配和釋放這些內(nèi)存塊。然而,在某些情況下,jemalloc 可能不會(huì)立即將未使用的內(nèi)存返回給操作系統(tǒng),這可能會(huì)導(dǎo)致內(nèi)存看起來(lái)被占用而實(shí)際并未被使用。通過(guò) MEMORY PURGE命令,可以強(qiáng)制 jemalloc 進(jìn)行內(nèi)存清理,將不再使用的內(nèi)存返回給操作系統(tǒng)。但這個(gè)命令是主線(xiàn)程執(zhí)行的,會(huì)阻塞其他命令。

最后注意在線(xiàn)上生產(chǎn)機(jī)上排查BigKey時(shí)最后把RDB文件拉取下來(lái)分析,禁止在生產(chǎn)機(jī)Master上使用如下命令尋找BigKey(主線(xiàn)程執(zhí)行,阻塞其他命令,非要用可以在Slave節(jié)點(diǎn)操作):

redis-cli -p 9001 -a 12345678 --bigkeys

最佳實(shí)踐

看了這么多,有沒(méi)有想一個(gè)問(wèn)題——為什么Redis官方默認(rèn)配置設(shè)置activfrag = no ?。原因就是Redis內(nèi)置了jemalloc這樣的內(nèi)存分配神器,它能夠?qū)σ颜加玫目臻e內(nèi)存碎片利用到極致,Redis官方建議我們采用“鴕鳥(niǎo)算法”,即啥都不用做,只需要設(shè)置合適的maxmemory即可,即使碎片率非常大,后續(xù)的內(nèi)存也是安全的,因?yàn)閖emalloc會(huì)自己去利用碎片。這里的邏輯就是:Redis在刪除鍵值的時(shí)候,會(huì)將內(nèi)存還給jemalloc而不是操作系統(tǒng)。這部分內(nèi)存可能是碎片,也可能不是,如果Redis需要申請(qǐng)內(nèi)存則先看內(nèi)存分配器是否有足夠的可分配內(nèi)存。額外的碎片過(guò)多是因?yàn)?,Reids釋放了大量?jī)?nèi)存,但jemalloc手中的大量的內(nèi)存沒(méi)有及時(shí)返回給操作系統(tǒng),這可能是是因?yàn)闆](méi)有設(shè)置合適的maxmemory原因。這個(gè)時(shí)候,其實(shí)Redis繼續(xù)存入鍵值對(duì)并不會(huì)向操作系統(tǒng)申請(qǐng)內(nèi)存而是向jemalloc申請(qǐng)。因此,如果不設(shè)置maxmemory,那么Redis可能無(wú)限地向操作系統(tǒng)申請(qǐng)內(nèi)存,而不是jemalloc中的碎片內(nèi)存。下面給出Redis官方原話(huà)(結(jié)合前面最開(kāi)始的Redis原話(huà)閱讀?。?/p>

但是jemalloc分配器非常智能,能夠重用空閑的內(nèi)存塊,因此在您釋放5GB數(shù)據(jù)集中的2GB后,當(dāng)您再次開(kāi)始添加更多鍵時(shí),您會(huì)看到RSS(駐留集大?。┍3址€(wěn)定,不會(huì)隨著您添加多達(dá)2GB的額外鍵而進(jìn)一步增長(zhǎng)。分配器基本上是試圖重用先前(邏輯上)釋放的 2GB 內(nèi)存。正因?yàn)槿绱?,?dāng)內(nèi)存使用量在峰值時(shí)遠(yuǎn)大于當(dāng)前使用的內(nèi)存時(shí),碎片率并不可靠。碎片率的計(jì)算方法是實(shí)際使用的物理內(nèi)存(RSS值)除以當(dāng)前使用的內(nèi)存量(Redis執(zhí)行的所有分配的總和)。
由于RSS 反映的是峰值內(nèi)存,因此當(dāng)(虛擬)使用的內(nèi)存較低(因?yàn)獒尫帕舜罅挎I/值)但RSS較高時(shí),該比率將非常高RSS / mem_used。如果maxmemory沒(méi)有設(shè)置,Redis會(huì)繼續(xù)按其認(rèn)為合適的方式分配內(nèi)存,因此它會(huì)(逐漸)耗盡所有可用內(nèi)存。因此,通常建議配置一些限制。

最佳實(shí)踐就是設(shè)置 maxmemory = 0.8*系統(tǒng)內(nèi)存,并且設(shè)置數(shù)據(jù)淘汰策略LRU算法來(lái)刪除部分key,釋放空間。最后,如果使用碎片整理,activefrag = yes CPU需要做出一定的讓步。慎重使用!

以上就是Redis關(guān)于內(nèi)存碎片的解決方法的詳細(xì)內(nèi)容,更多關(guān)于Redis內(nèi)存碎片解決的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Redis實(shí)現(xiàn)消息的發(fā)布訂閱原理分析

    Redis實(shí)現(xiàn)消息的發(fā)布訂閱原理分析

    本文主要介紹了Redis實(shí)現(xiàn)消息的發(fā)布訂閱原理分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Redis持久化深入詳解

    Redis持久化深入詳解

    這篇文章主要介紹了Redis持久化深入詳解,講解的還是比較詳細(xì)的,有感興趣的同學(xué)可以學(xué)習(xí)下
    2021-03-03
  • 基于Redis實(shí)現(xiàn)分布式單號(hào)及分布式ID(自定義規(guī)則生成)

    基于Redis實(shí)現(xiàn)分布式單號(hào)及分布式ID(自定義規(guī)則生成)

    一些業(yè)務(wù)背景下,業(yè)務(wù)要求單號(hào)需要有區(qū)分不同的前綴,那么在分布式的架構(gòu)下如何自定義單號(hào)而且還能保證唯一呢?本文就來(lái)詳細(xì)的介紹一下
    2021-09-09
  • redis實(shí)現(xiàn)好友關(guān)注&消息推送的方法示例

    redis實(shí)現(xiàn)好友關(guān)注&消息推送的方法示例

    Redis作為一款開(kāi)源的內(nèi)存數(shù)據(jù)庫(kù),具有可靠性、速度快、易用性等優(yōu)點(diǎn),已經(jīng)被廣泛應(yīng)用于開(kāi)發(fā)實(shí)際項(xiàng)目中,本文主要介紹了redis實(shí)現(xiàn)好友關(guān)注&消息推送的方法示例,感興趣的可以了解一下
    2023-10-10
  • Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列使用小結(jié)

    Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列使用小結(jié)

    這篇文章主要介紹了Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列使用總結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Redis高級(jí)玩法之利用SortedSet實(shí)現(xiàn)多維度排序的方法

    Redis高級(jí)玩法之利用SortedSet實(shí)現(xiàn)多維度排序的方法

    Redis的SortedSet是可以根據(jù)score進(jìn)行排序的,以手機(jī)應(yīng)用商店的熱門(mén)榜單排序?yàn)槔?,根?jù)下載量倒序排列。接下來(lái)通過(guò)本文給大家分享Redis高級(jí)玩法之利用SortedSet實(shí)現(xiàn)多維度排序的方法,一起看看吧
    2019-07-07
  • Redis分布式鎖升級(jí)版RedLock及SpringBoot實(shí)現(xiàn)方法

    Redis分布式鎖升級(jí)版RedLock及SpringBoot實(shí)現(xiàn)方法

    這篇文章主要介紹了Redis分布式鎖升級(jí)版RedLock及SpringBoot實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Redis隊(duì)列和阻塞隊(duì)列的實(shí)現(xiàn)

    Redis隊(duì)列和阻塞隊(duì)列的實(shí)現(xiàn)

    本文主要介紹了Redis隊(duì)列和阻塞隊(duì)列的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • Centos7 Redis主從搭建配置的實(shí)現(xiàn)

    Centos7 Redis主從搭建配置的實(shí)現(xiàn)

    這篇文章主要介紹了Centos7 Redis主從搭建配置的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Redisson如何解決Redis分布式鎖提前釋放問(wèn)題

    Redisson如何解決Redis分布式鎖提前釋放問(wèn)題

    本文主要介紹了Redisson如何解決Redis分布式鎖提前釋放問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05

最新評(píng)論