Redis内存淘汰的探究(redis的内存淘汰策论)
Redis内存淘汰的探究
Redis是一款常见的开源内存数据库,常被用于缓存、消息队列等场景。由于其采用了内存存储,因此在使用时需要注意内存的使用情况。
为了避免内存溢出,Redis提供了多种内存淘汰策略。本文将系统地探究Redis内存淘汰策略的相关知识,并通过代码实践加深理解。
一、Redis内存淘汰策略介绍
1.1 noeviction
noeviction表示不进行内存淘汰,当内存占用达到maxmemory限制时,后续写入操作会返回错误信息。这种策略一般用于保证数据的完整性,但不利于系统的稳定性和可用性。
1.2 allkeys-lru
allkeys-lru表示对所有key进行LRU淘汰操作。它会按照键的最后一次使用时间顺序淘汰掉访问时间最早的key,直到腾出足够的内存空间。
1.3 volatile-lru
volatile-lru表示对过期键中最长时间未使用的key进行LRU淘汰操作。它会按照键的最后一次使用时间顺序淘汰掉访问时间最早的key,直到腾出足够的内存空间。
1.4 allkeys-random
allkeys-random表示随机淘汰所有key,它并不考虑每个key的使用情况。这种策略在持久化存储过程中难以保证一致性,因此不被推荐使用。
1.5 volatile-random
volatile-random表示随机淘汰过期键中的key,它并不考虑每个key的使用情况。和allkeys-random策略一样,不利于保证一致性。
1.6 volatile-ttl
volatile-ttl表示淘汰剩余有效期最短的key。将剩余有效期最短的key作为优先考虑对象,直到腾出足够的内存空间。
二、Redis内存淘汰的实践
下面我们通过代码实践来加深对Redis内存淘汰的理解。
假设我们有一个Redis实例,maxmemory设置为2MB。现在我们向Redis中写入一些数据,每个key大小为100KB。具体代码如下所示:
import redis
client = redis.Redis()
key_size = 1024 * 100 # 100KBtotal_size = 1024 * 1024 * 2 # 2MB
write_size = 0
while write_size key = "key_" + str(write_size)
value = "value" + str(write_size) client.set(key, value)
write_size += key_size
运行以上代码后,我们可以通过如下命令查看内存使用情况:
redis-cli info memory
其中,used_memory_peak记录当前内存使用峰值;maxmemory指定的最大内存限制。
开启Redis的maxmemory-policy设置为volatile-lru,即采用LRU淘汰过期键中最长时间未使用的key。
client.config_set("maxmemory-policy", "volatile-lru")
接着,我们向Redis中写入一些数据,每个key的有效期为60s。
key_size = 1024 * 100 # 100KB
total_size = 1024 * 1024 * 2 # 2MBwrite_size = 0
while write_size key = "key_" + str(write_size)
value = "value" + str(write_size) client.setex(key, 60, value)
write_size += key_size
等待60s后,Redis的内存淘汰策略生效,我们可以查看系统日志,发现Redis按照LRU策略淘汰掉了最久未被使用的key。
如下所示:
2021-12-20T09:12:16.585807393Z [160] 20 Dec 09:12:16.585 # Redis is now ready to exit, bye bye...
2021-12-20T09:12:16.681584335Z [160] 20 Dec 09:12:16.680 * Running mode=standalone, port=6379.2021-12-20T09:12:16.681601956Z [160] 20 Dec 09:12:16.680 # Server initialized
2021-12-20T09:12:16.682593737Z [160] 20 Dec 09:12:16.682 # WARNING overcommit_memory is set to 0! Background save may fl under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.2021-12-20T09:12:16.682647838Z [160] 20 Dec 09:12:16.682 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retn the setting after a reboot. Redis must be restarted after THP is disabled.
2021-12-20T09:12:16.683406032Z [160] 20 Dec 09:12:16.683 # Server running in protected mode (pid=160)2021-12-20T09:12:16.683423874Z [160] 20 Dec 09:12:16.683 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2021-12-20T09:12:16.683430985Z [160] 20 Dec 09:12:16.683 # Server initialized and ready to accept connections2021-12-20T09:12:16.683438676Z [160] 20 Dec 09:12:16.683 # Server listening on 0.0.0.0:6379
2021-12-20T09:12:16.683445987Z [160] 20 Dec 09:12:16.683 # Server started, Redis version 6.2.62021-12-20T09:12:16.689878958Z [160] 20 Dec 09:12:16.689 # *** Overcommit on memory (-o bytes): FALSE ***
2021-12-20T09:13:16.306625381Z [160] 20 Dec 09:13:16.306 * 1 changes in 900 seconds. Saving...2021-12-20T09:13:16.306702818Z [160] 20 Dec 09:13:16.306 * Background saving started by pid 186
2021-12-20T09:13:16.963921423Z [186] 20 Dec 09:13:16.963 * DB saved on disk2021-12-20T09:13:16.964287960Z [186] 20 Dec 09:13:16.963 * RDB: 0 MB of memory used by copy-on-write
2021-12-20T09:13:16.964294332Z [160] 20 Dec 09:13:16.964 * Background saving terminated with success2021-12-20T09:13:17.307347063Z [160] 20 Dec 09:13:17.307 # Redis is now ready to exit, bye bye...
2021-12-20T09:13:19.831007485Z [160] 20 Dec 09:13:19.831 * Running mode=standalone, port=6379.2021-12-20T09:13:19.831147840Z [160] 20 Dec 09:13:19.831 # Server initialized
2021-12-20T09:13:25.545417915Z [160] 20 Dec 09:13:25.545 # WARNING overcommit_memory is set to 0! Background save may fl under low memory condition. To fix this issue add 'vm.overcommit_memory =