22

Redis是用来保存数据的,但是它消耗大量的内存,它的内存使用率高达52.5%。我在redis中删除了一半的key,删除操作的返回码是ok的,但是它的内存使用并没有减少。

什么原因?提前致谢。

我的操作代码如下:

// 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> 信息
redis_version:2.4.8
redis_git_sha1:00000000
redis_git_dirty:0
拱位: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
连接的奴隶:0
client_longest_output_list:0
client_biggest_input_buf:0
阻塞的客户端:0
已用内存: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
加载:0
aof_enabled:0
changes_since_last_save:177467
bgsave_in_progress:0
最后保存时间:1343456339
bgrewriteaof_in_progress:0
total_connections_received:820
total_commands_processed:2412759064
expired_keys:0
驱逐键:0
keyspace_hits:994257907
keyspace_misses:32760132
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:11672476
vm_enabled:0
角色:奴隶
主主机:192.168.252.103
主端口:6479
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
db0:keys=66372158,expires=0
4

3 回答 3

22

请参阅以下链接上的内存分配部分:

http://redis.io/topics/memory-optimization

我在这里引用它:

删除键时,Redis 并不总是向操作系统释放(归还)内存。这对于 Redis 来说并没有什么特别之处,但它是大多数 malloc() 实现的工作方式。例如,如果您用 5GB 的数据填充一个实例,然后删除相当于 2GB 的数据,则驻留集大小(也称为 RSS,即进程消耗的内存页数)可能仍然是大约 5GB,即使 Redis 声称用户内存在 3GB 左右。发生这种情况是因为底层分配器不能轻易释放内存。例如,大多数已删除的键通常与仍然存在的其他键分配在相同的页面中。

于 2014-08-18T18:45:47.993 回答
7

从 Redis 4.0.0 开始,有一个命令:

MEMORY PURGE

应该做的伎俩:https ://redis.io/commands/memory-purge

但是请注意,命令文档状态:

此命令当前仅在使用 jemalloc 作为分配器时实现,并且对所有其他命令评估为良性 NOOP。

自述文件提醒我们:

默认情况下,Redis 是针对 libc malloc 编译和链接的,但 jemalloc 是 Linux 系统上的默认设置。之所以选择此默认值,是因为 jemalloc 已被证明比 libc malloc 具有更少的碎片问题。

于 2018-12-27T23:11:55.017 回答
2

一个好的起点是使用 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”配置选项。
于 2020-09-16T09:47:31.690 回答