簡體   English   中英

為什么刪除一半鍵時redis內存使用量沒有減少

[英]why does the redis memory usage not reduce when del half of keys

Redis是用來保存數據的,但是它非常耗費內存,內存占用高達52.5%。 我在redis中刪除了一半的key,刪除操作的返回碼是可以的,但是它的內存占用並沒有減少。

什么原因? 提前致謝。

我的操作代碼如下:

// save data
m_pReply = (redisReply *)redisCommand(m_pCntxt, "set %b %b", mykey.data(), mykey.size(), &myval, sizeof(myval));
// del data
m_pReply = (redisReply *)redisCommand(m_pCntxt, "del %b", mykey.data(), mykey.size());

redis信息:

redis 127.0.0.1:6979> info
redis_version:2.4.8
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.6
process_id:28799
uptime_in_seconds:1289592
uptime_in_days:14
lru_clock:127925
used_cpu_sys:148455.30
used_cpu_user:38023.92
used_cpu_sys_children:23187.60
used_cpu_user_children:123989.72
connected_clients:22
connected_slaves:0
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
used_memory:31903334872
used_memory_human:29.71G
used_memory_rss:34414981120
used_memory_peak:34015653264
used_memory_peak_human:31.68G
mem_fragmentation_ratio:1.08
mem_allocator:jemalloc-2.2.5
loading:0
aof_enabled:0
changes_since_last_save:177467
bgsave_in_progress:0
last_save_time:1343456339
bgrewriteaof_in_progress:0
total_connections_received:820
total_commands_processed:2412759064
expired_keys:0
evicted_keys:0
keyspace_hits:994257907
keyspace_misses:32760132
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:11672476
vm_enabled:0
role:slave
master_host:192.168.252.103
master_port:6479
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
db0:keys=66372158,expires=0

請參考以下鏈接中的內存分配部分:

http://redis.io/topics/內存優化

我在這里引用它:

當刪除鍵時,Redis 不會總是釋放(返回)內存給操作系統。 這不是 Redis 的特殊之處,但這是大多數 malloc() 實現的工作方式。 例如,如果你用 5GB 的數據填充一個實例,然后刪除相當於 2GB 的數據,Resident Set Size(也稱為 RSS,它是進程消耗的內存頁數)可能仍然是大約 5GB,即使 Redis 會聲稱用戶內存在 3GB 左右。 發生這種情況是因為底層分配器無法輕易釋放內存。 例如,大多數已刪除的鍵通常與其他仍然存在的鍵分配在相同的頁面中。

從 Redis 4.0.0 開始,有一個命令:

MEMORY PURGE

應該做的伎倆: https ://redis.io/commands/memory-purge

但是請注意命令文檔狀態:

此命令當前僅在使用 jemalloc 作為分配器時實施,並且對所有其他分配器評估為良性 NOOP。

README提醒我們:

默認情況下,Redis 是針對 libc malloc 編譯和鏈接的,除了 jemalloc 是 Linux 系統上的默認值。 選擇此默認值是因為 jemalloc 已被證明比 libc malloc 具有更少的碎片問題。

一個好的起點是使用 Redis CLI 命令: MEMORY DOCTOR
它可以為您提供非常有價值的信息,並指出潛在的問題。

一些有用的鏈接:
MEMORY DOCTOR 命令文檔
什么是碎片整理以及 Redis 碎片整理配置是什么

例子:

  • 內存峰值:過去此實例使用的內存超過當前使用內存的 150%。 分配器通常無法在峰值后釋放內存,因此您可以預期看到很大的碎片率,但這實際上是無害的,只是由於內存峰值,如果 Redis 實例駐留集大小 (RSS) 為當前大於預期,一旦您用更多數據填充 Redis 實例,就會使用內存。 如果內存峰值只是偶爾出現,而您想嘗試回收內存,請嘗試使用 MEMORY PURGE 命令,否則唯一的選擇就是關閉並重啟實例。
  • 高總 RSS:此實例內存碎片和 RSS 開銷大於 1.4(這意味着 Redis 進程的 Resident Set Size 遠大於 Redis 執行的邏輯分配的總和)。 此問題通常是由於較大的峰值內存(檢查報告中是否存在上面的峰值內存條目)引起的,或者可能是由於工作負載導致分配器產生大量內存碎片。 如果問題是大峰值內存,則沒有問題。 否則,請確保您使用的是 Jemalloc 分配器而不是默認的 libc malloc。 注意:當前使用的分配器是“jemalloc-5.1.0”。
  • 高分配器碎片:此實例的分配器外部碎片大於 1.1。 此問題通常是由於較大的峰值內存(檢查報告中是否存在上面的峰值內存條目)引起的,或者可能是由於工作負載導致分配器產生大量內存碎片。 您可以嘗試啟用“activedefrag”配置選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM