Redis 的内存管理和内存过期策略

摘要:redis 的内存管理和过期策略,redis 主要通过控制内存上限和回收策略实现内存管理,redis 的内存回收策略,主要是由过期删除,惰性删除,内存淘汰机制来控制。

Redis 的内存管理

redis 主要通过控制内存上限和回收策略实现内存管理。


Redis 的 info 命令

我们 info 命令以一种易于理解和阅读的格式,返回关于 redis 服务器的各种信息和统计数值,如果给定 section 参数,可以让命令只返回指定的信息。命令返回结果请参考:Redis Info 命令 / redis info信息详解

127.0.0.1:6379> info memory
# Memory
used_memory:853208
used_memory_human:833.21K
used_memory_rss:12935168
used_memory_rss_human:12.34M
used_memory_peak:4953864
used_memory_peak_human:4.72M
used_memory_peak_perc:17.22%
used_memory_overhead:840822
used_memory_startup:791016
used_memory_dataset:12386
used_memory_dataset_perc:19.92%
allocator_allocated:1453856
allocator_active:1818624
allocator_resident:10706944
total_system_memory:1033498624
total_system_memory_human:985.62M
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.25
allocator_frag_bytes:364768
allocator_rss_ratio:5.89
allocator_rss_bytes:8888320
rss_overhead_ratio:1.21
rss_overhead_bytes:2228224
mem_fragmentation_ratio:15.93
mem_fragmentation_bytes:12122984
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0


Redis 内存上限配置

redis 使用 maxmemory 参数限制最大可用内存,redis 默认是无限使用内存,为防止极端情况导致系统内存消耗尽,建议所有的 reids 进程都要配置 maxmemory 参数,但是要合理的设置 maxmemory 参数,保证机器有 20%~30% 的闲置内存,设置最大内存限制主要目的有:

1、用于缓存场景,当超出内存上线 maxmemory 后,释放内存。

2、防止所用内存超过服务器物理内存。

3、通过设置内存上限可以非常方便地实现一台服务器部署多个 redis 进程的内存控制。

需要注意 maxmemory 限制的是 redis 实际使用的内存量,也就是 used_memory 统计项对应的内存。由于内存碎片率的存在,实际消耗的内存可能会比 maxmemory 设置的更大,实际使用时要小心这部分内存溢出。


Redis 内存上限配置方法

redis 的内存上限需要 maxmemory 参数和 maxmemory-policy 参数一起使用,maxmemory 参数配置内存的最大使用上限,而 maxmemory-policy 参数配置如果超出上限 redis 要实行淘汰机制,maxmemory-policy 参数对应着 6 个淘汰机制。配置内存上限有两种方法,一种是动态调整,一种是通过配置文件调整。

# 动态调整

127.0.0.1:6379> config set maxmemory 6GB
127.0.0.1:6379> config set maxmemory-policy {policy}
# 通过 redis 配置文件调整

############################## MEMORY MANAGEMENT ################################
...
# 配置 redis 使用内存大小,超过这个大小就会采取内存淘汰机制,如果配置了 maxmemory 选项,就需要配置 maxmemory-policy 的淘汰规则
# 这个 maxmemory 默认是注释的,也就是说默认不限制内存使用
# 这个配置网上说的是 redis 的内存一般是服务器内存的四分之三或者二分之一。
# maxmemory <bytes> 
...
# 当使用内存超过 maxmemory 限制,会触发淘汰策略,有 6 个淘汰准则
maxmemory-policy

# 6 个淘汰准则如下:
1、no-enviction:(默认策略),禁止淘汰数据,新写入数据会报错(error)OOM command not allowed when used memory,此时 redis 只响应读操作。
2、volatile-lru:(使用)从已设置过期时间的 key 中,挑选最少使用的 key 进行淘汰,直到腾出足够空间为止。如果没有可删除的键对象,回退到 noeviction 策略。
3、allkeys-lru:从所有 key 中挑选最少使用的 key 进行淘汰,直到腾出足够空间为止。
4、allkeys-random:从所有 key 中挑选即将过期的 key 进行淘汰,直到腾出足够空间为止。
5、volatile-random:从已设置过期时间的 key 中随机进行淘汰,直到腾出足够空间为止。
6、volatile-ttl:从已设置过期时间的 key 中,挑选即将过期的 key 进行淘汰。如果没有,回退到 noeviction 策略。


Redis 的过期策略

redis 的过期策略指的是,删除到达过期时间的键和对象,和内存使用达到 maxmemory 上限时触发内存溢出控制策略。redis 每个 key 都可以设置过期属性,内部保存在过期字典中,由于进程内保存大量的键,维护每个键精准的过期删除机制会导致消耗大量的 cpu,对于单线程的 redis 来说成本过高,因此 redis 采用定期删除、惰性删除和超过内存上限自动触发内存淘汰机制。

定期删除:redis 的过期策略指的是,默认每隔 100 ms 就会抽取一些设置了过期时间的 key,检测是否过期,如果过期就删除。因为是定期抽取部分 key 来检测是否过期,然后删除。如果 key 非常多的情况下,会有很多 key 没有检测到,从而导致过期时间到了,还是没有被删除,这样既会占用内存,也会让用户获取到过期的 key。

惰性删除:redis 的惰性删除就是,当时你每次去请求 key 时,redis 会检测下此 key 是否过期,如果过期就是删除,没有过期就返回。利用过期策略和惰性删除可以有效的解决用户获取到过期 key 的问题。

但这里需要注意一个问题就是,如果被动的过期策略检测不到,你又没有去主动请求 key,也就是没有触发惰性删除,这个 key 还是会在 redis 的内存中,还是在占用 redis 的内存。

内存淘汰机制:当 redis 所用内存达到 maxmemory 上限时会触发相应的内存淘汰策略,redis 会实行数据淘汰策略自行删除一些数据,把内存腾出来,给新的数据来写入,具体淘汰策略实施准则由 maxmemory-policy 参数来控制。


Redis 的内存不够怎么办

这种情况就涉及到 redis 的内存优化了,我们应该先排查问题,看看 redis 是否足够优化,如果 redis 已经足够优化,我们可以增加服务器物理内存,但是这种方法治标不治本,因为我们没有办法一直依靠增加物理内存来解决内存不够的问题。一般如果垂直优化已经解决不了问题,只能横向扩展,搭建 redis 集群了。

结束语:感谢您对本网站文章的浏览,欢迎您的分享和转载,但转载请说明文章出处。
Top