暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis【理论篇】Redis内存回收机制

花好夜猿 2019-05-19
379

前置问题

  • Q1、设置的 key 明明已经过期了,为啥 仍然占用内存?

  • Q2、设置的 key 明明还没有过期,为啥 这个 key 就不见了?

这两个问题,通过 Redis 内存回收机制能够得到完美的解答。

Redis内存回收机制

Redis 在两种情况下会回收 key 占用的内存:

  • 用户主动设置过期时间,时间到了,被回收

  • redis 中key达到了 redis 设置的 max_memory ,内存溢出。Redis 通过 LRU 算法进行Redis 内存回收。

1、删除达到过期时间的键对象

在 Redis 进程内保存了大量用户存入的 key ,针对设置了过期时间的 key ,如果每一个 key 进行精准的控制-当key过期立即回收空间,对于单线程的Reids来说成本太高。所以 Redis 中的 key 过期了,占用的内存空间并不会马上被回收, Redis 采用了两种方式:惰性删除定时任务删除 来进行空间回收

  • 惰性删除

    当客户端进行某个 key 的get 访问,该key被设置了过期时间,如果此时 get 操作的时候 key 过期了,此时 Redis 将会针对该 key 占用的空间进行回收。

    优点:该方式采用用户访问的方式进行空间回收,无需维护 key 的 TTL 链表数据。

    缺点:如果存在大量已过期的 key 但是长时间内用户一直没有进行 get 方法,会导致过期 key 堆积在内存中,产生内存泄漏。

  • 定时任务删除

    Redis 内部维护一个定时任务,每秒执行10次。定时随机的进行过期key的内存回收。
    优点:能够定时的进行内存回收。
    缺点:只能够进行定时删除,并且删除是随机的。

惰性删除 、 定时任务删除两者各有利弊,Redis 结合两种方式进行过期对象内存空间的回收。

运维知识

定时任务删除,每秒执行次数 在 redis.conf 中 hz 进行配置,默认 hz 10

2、内存使用达到 max memory 上限时触发内存溢出控制策略

Redis 是一个缓存中间件,使用的内存空间,Redis 可以通过配置每个 Redis 实例的内存上限,或者 载体机器的内存上限。

在 Redis 的最大内存达到上限的时候,需要进行内存回收,或者拒绝写等策略来保证 Redis 正常提供服务。Redis 支持6种策略:

  • noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息(error)OOM command not allowed when used memory,此时Redis只响应读操作。

  • volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。

  • allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。

  • allkeys-random:随机删除所有键,直到腾出足够空间为止。

  • volatile-random:随机删除过期键,直到腾出足够空间为止。

  • volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。

运维知识

内存溢出控制策略 在  redis.conf 中 maxmemory-policy 进行配置,默认: maxmemory-policy noeviction

建议1:策略使用 volatile-lru 。保证服务正常提供的前提下,优先删除不常用的待过期的 key 。
建议2:频繁的策略回收会导致 Redis 性能下降设置阻塞,所以在设置 maxmemory 时,评估系统需要多大内存的 Redis 提供服务,尽量确保使用的内存 < max memory。
建议3:能够 通过 confg 命令进行动态配置策略。如:confg set maxmeory-policy {policy}

问题解答

Q1、设置的 key 明明已经过期了,为啥 仍然占用内存?

过期 key 需要通过 惰性删除 或者 定时任务删除,才会真正的被回收。

此时 key 过期了的key 仍然占用内存,是因为还未被回收。

Q2、设置的 key 明明还没有过期,为啥 这个 key 就不见了?

Redis  max memory 达到上限。刚好设置策略为  非noeviction ,即使 key 未过期 仍然存在被回收的可能。

反之,如果当 Redis 明明没有挂掉,但是总是写操作失败,就得看看报错信息,看看 max memory ,对比 内存使用量,加上 max memory 策略来判定,是否设置了 noeviction 策略,导致的问题。

-- END --

       长按二维码      

关注 [ WTF名字好难取 ] 公众号


往期回顾


Redis【应用篇】我用过的那些场景

分布式锁解决方案-Redis分布式锁

Rabbitmq延迟队列-实现任务延迟处理

文章转载自花好夜猿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论