Redis从入门到放弃系列(七) 过期、内存淘汰策略

Stella981
• 阅读 746

Redis从入门到放弃系列(七) 过期、内存淘汰策略

本文例子基于:5.0.4

过期策略

Redis对于设置了过期时间的key的过期策略有两种

  • 惰性删除
  • 定时随机删除

惰性删除

惰性删除的时机在于当你要获取该key的时候再去做判断.这里我以String类型作为演示画图: Redis从入门到放弃系列(七) 过期、内存淘汰策略

int expireIfNeeded(redisDb *db, robj *key) {
    if (!keyIsExpired(db,key)) return 0;

    /* If we are running in the context of a slave, instead of
     * evicting the expired key from the database, we return ASAP:
     * the slave key expiration is controlled by the master that will
     * send us synthesized DEL operations for expired keys.
     *
     * Still we try to return the right information to the caller,
     * that is, 0 if we think the key should be still valid, 1 if
     * we think the key is expired at this time. */
    if (server.masterhost != NULL) return 1;

    /* Delete the key */
    server.stat_expiredkeys++;
    propagateExpire(db,key,server.lazyfree_lazy_expire);
    notifyKeyspaceEvent(NOTIFY_EXPIRED,
        "expired",key,db->id);
    return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
                                         dbSyncDelete(db,key);
}

我们发现,当key有设置了过期时间,然后key已经过期的话,那么redis会判断是否开启了lazyfree_lazy_expire ,如果开启的话,那么异步删除.没有则同步直接删除.(4.0之后的特性,当大key删除的时候非常有用)

定时随机删除

当有了惰性删除之后,满足了一部分的需求,可是在实际应用中,会存在有过期而没有被访问到的key,这样就会平白的占据着内存.那么redis是通过怎样去解决的呢?

redis会有一个定时任务,每秒跑10次。

  • 随机选择设置了过期时间的20个key进行过期检测
  • 删除所有已经过期的keys
  • 如果超过25%的密钥过期,请从步骤1重新开始。

由于redis是单线程,如果任由上面定时随机删除策略的话,那么当有大量的key过期的时候,redis会存在无法处理客户端请求的情况?不不不,其实redis在做定时随机删除的时候,有一个限制,就是设置扫描时间的上限,默认至多为25ms(timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;),所以当客户端请求到来时,服务器正处于过期扫描期间,客户端会等到至多25ms然后进行其业务处理.

那么如果redis设置超时时间过短的话,有可能出现大量超时连接,为了避免这个问题,建议是在设置过期时间是时候,加多一个随机范围,避免大量的key同时过期~

当有做主从的时候,从库是不会开启定时随机删除的,都是依赖master开启的aof文件中增加一条del命令,然后从库去执行该语句实现删除该过期key

内存淘汰策略

我们知道redis是纯内存数据库,如果redis使用超出了内存限制的时候,便会产生swap行为. 使用磁盘来操作相比内存来说,性能下降的不是一丁半点。 这时候我们需要设置redis最大使用内存

maxmemory <bytes>

通过设置maxmemory,当使用内存超过maxmemory的时候,redis提供了几种可选的策略来控制内存的使用量

  • noeviction (当内存不足以容纳新写入数据时,新写入操作会报错)
  • allkeys-lru (当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key)
  • allkeys-random (当内存不足以容纳新写入数据时,在键空间中,随机移除某个key)
  • volatile-lru (当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key)
  • volatile-random (当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key)
  • volatile-ttl (当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除)

写在最后

端午三天就这样过去啦愿各位看官好好休息,然后继续起来搬砖hhhhh

Redis从入门到放弃系列(七) 过期、内存淘汰策略

点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Redis从入门到放弃系列(二) Hash
Redis从入门到放弃系列(二)Hash本文例子基于:5.0.4Hash是Redis中一种比较常见的数据结构,其实现为hashtable/ziplist,默认创建时为ziplist,当到达一定量级时,redis会将ziplist转化为hashtableRedis从入门到放弃系列(一)String
Stella981 Stella981
3年前
Redis 知识整理
_本文以Redis5.0.7为准。_基本概念Redis是开源的(BSD协议)内存数据存储。以KV的方式存储数据。key类型固定为string,value支持的类型有:stringlistsetzsethashtable淘汰策略volat
Stella981 Stella981
3年前
Redis从入门到放弃系列(十) Cluster
Redis从入门到放弃系列(十)Cluster本文例子基于:5.0.4RedisCluster集群高可用方案,去中心化,最基本三主多从,主从切换类似Sentinel,关于Sentinel内容可以查看编者另外一篇【Redis从入门到放弃系列(九)Sentinel(https://www.o
Stella981 Stella981
3年前
Redis 总结精讲
本文围绕以下几点进行阐述1、为什么使用redis2、使用redis有什么缺点3、单线程的redis为什么这么快4、redis的数据类型,以及每种数据类型的使用场景5、redis的过期策略以及内存淘汰机制6、redis和数据库双写一致性问题7、如何应对缓存穿透和缓存雪崩问题8、如何解决redis的并发竞争问题
Stella981 Stella981
3年前
Redis从入门到放弃系列(九) Sentinel
Redis从入门到放弃系列(九)Sentinel本文例子基于:5.0.4RedisSentinel作为Redis高可用方案,具有监听,通知,自动故障转移等功能.这一切都是依赖主备同步的大前提(参考上一节:Redis从入门到放弃系列(八)主备同步).监听:Sentinel会不断
Stella981 Stella981
3年前
Redis从入门到放弃系列(三) List
Redis从入门到放弃系列(三)List本文例子基于:5.0.4List是Redis中一种比较常见的数据结构,其实现为quicklist,quicklist是一个ziplist的双向链表Redis从入门到放弃系列(一)String(https://www.oschina.net/action/
Stella981 Stella981
3年前
Redis中的Scan命令踩坑记
1原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作。但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限。所以记录下这个踩坑的过程,背景如下:公司因为redis服务器内存吃紧,需要删除一些无用的没有设置过期时间的key。大概有500多w的key。虽然key的数目听起来
胖大海 胖大海
2年前
Redis 的数据过期了就会马上删除么?
Redis的数据过期了就会马上删除么?我在3A服务器平台购买了服务器,部署了相关环境,正好可以解答一下这个问题先说结论,并不会立马删除,Redis有两种删除过期数据的策略:定期选取部分数据删除;惰性删除;该命令
Spring缓存是如何实现的?如何扩展使其支持过期删除功能? | 京东云技术团队
我们希望将这些rpc结果数据缓存起来,并在一定时间后自动删除,以实现在一定时间后获取到最新数据。类似Redis的过期时间。接下来是我的调研步骤和开发过程。