redis内存回收——过期、淘汰

redis内存设置过大时会增加同步等操作的复杂度

DB结构

/* Redis database representation. There are multiple databases identified
 * by integers from 0 (the default database) up to the max configured
 * database. The database number is the 'id' field in the structure. */
typedef struct redisDb {
    dict *dict;                 /* keyspace,存储所有key,value */
    dict *expires;              /* 存储设置过期时间的key,ttl */
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*/
    dict *blocking_keys_unblock_on_nokey;   /* Keys with clients waiting for
                                             * data, and should be unblocked if key is deleted (XREADEDGROUP).
                                             * This is a subset of blocking_keys*/
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    int id;                     /* Database ID */
    long long avg_ttl;          /* Average TTL, just for stats */
    unsigned long expires_cursor; /* Cursor of the active expire cycle. */
    list *defrag_later;         /* List of key names to attempt to defrag one by one, gradually. */
    clusterSlotToKeyMapping *slots_to_keys; /* Array of slots to keys. Only used in cluster mode (db 0). */
} redisDb;

在这里插入图片描述

删除策略

惰性删除

访问时,检查过期时间,删除
已过期但不访问的数据,永远存在,占据内存

周期删除

定期抽样部分key检查过期时间,删除

SLOW

redis初始化时设置定期任务

  • 默认每秒执行10次,每个周期100ms
  • 执行清理耗时不超过一次执行周期的25%
  • 遍历所有db(每个db类似于一个数组)的所有bucket(数组下标index),抽取20个key检查(记录本次遍历位置,下次定时任务从该位置继续)
  • 如果没有达到时间上限(25ms)&过期key比例大于10%,再进行一次抽样,否则结束
FAST

redis每个事件执行之前

  • 两次fast间隔大于2ms,执行清理不超过1ms
  • 遍历所有db(每个db类似于一个数组)的所有bucket(数组下标index),抽取20个key检查(记录本次遍历位置,下次定时任务从该位置继续)
  • 如果没有达到时间上限(1ms)&过期key比例大于10%,再进行一次抽样,否则结束

淘汰策略

redis主动删除key,释放内存

  • noeviction:只返回错误,不会删除任何key。该策略是Redis的默认淘汰策略,一般不会选用。

  • volatile-ttl:将设置了过期时间的key中即将过期(剩余存活时间最短)的key删除掉。

  • volatile-random:在设置了过期时间的key中,随机删除某个key。

  • allkeys-random:从所有key中随机删除某个key。

  • volatile-lru:基于LRU算法,从设置了过期时间的key中,删除掉最近最少使用的key。

  • allkeys-lru:基于LRU算法,从所有key中,删除掉最近最少使用的key。该策略是最常使用的策略。

  • volatile-lfu:基于LFU算法,从设置了过期时间的key中,删除掉最不经常使用(使用次数最少)的key。

  • allkeys-lfu:基于LFU算法,从所有key中,删除掉最不经常使用(使用次数最少)的key。

struct redisObject {
    unsigned type:4;//对象类型
    unsigned encoding:4;//编码方式
    unsigned lru:LRU_BITS; /* LRU time 最近一次访问时间 秒为单位
                            * LFU data 低八位记录逻辑访问次数
                            			高16位记录最近一次访问时间 分钟为单位). */
    int refcount;//对象引用计数器
    void *ptr;//指针,指向不同数据类型的数据,真实数据
};

在这里插入图片描述

淘汰过程在这里插入图片描述

  • 将设置ttl的key抽取部分存入pool
  • 将pool中所有key按照值升序排列
  • 从pool中按序删除
  • 避免排序,效率更高
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Redis是一款高性能的Key-Value存储系统,它提供了多种数据结构和丰富的功能,能够满足各种存储需求。在Redis中,内存淘汰是一种非常重要的机制,通过控制内存使用来保证系统的稳定性和性能。 内存淘汰Redis中的一个重要机制,它可以将一部分数据从内存中删除,以释放更多的内存空间。在Redis中,内存淘汰一般有几种策略,包括LRU(Least Recently Used)、LFU(Least Frequently Used)、Random等等,而Redis默认的内存淘汰策略是LRU。 但是,在一些场景中,Redis中的数据并不是按照时间顺序进行访问的,而是需要在指定的时间点过期。为了解决这个问题,Redis还提供了一种特殊的内存淘汰策略——volatile-lru和volatile-ttl。这两种内存淘汰策略的特点是:它们只会淘汰过期数据或者TTL(Time To Live)值到期的数据,而不会淘汰过期的数据。 在使用这两种策略时,需要加上volatile选项,例如指定maxmemory-policy为volatile-lru或volatile-ttl。此时,Redis会将未过期的数据和已经过期但未被删除的数据分别保存在两个不同的哈希表中,内存淘汰只会针对已过期但仍在内存中的数据进行操作。 因此,Redis可以通过特殊的内存淘汰策略来解决不会过期的数据的问题。通过使用可volatile-lru和volatile-ttl两种策略,Redis只会淘汰过期的数据,而不会淘汰过期的数据,从而保证系统的正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值