为什么要有过期策略?

因为我们的redis是一个内存型数据库,我们的数据都是放在内存里面的!但是内存是有大小的!
比如,redis有个很重要的配置文件,redis.conf,里面有个配置

# maxmemory <bytes> //redis占用的最大内存

如果我们不淘汰,那么它的数据就会满,满了肯定就不能再放数据,发挥不了redis的作用!
比如冰箱,你如果放满了,那么你的菜就不能放冰箱了!
过期策略:拿出redis中已经过期了的数据,就像你从冰箱把坏的菜拿出来!!但是有一种情况,就是冰箱里面的菜都没坏,redis里面的数据都没过期,它也是会放满的,那怎么办?

那么当redis里面的数据都没过期。但是内存满了的时候,我们就得从未过期的数据里面去拿出一些扔掉,那么这个就是我们的淘汰策略,详见另一篇文章:Redis的淘汰策略详解

Redis自带的有两种过期策略,我们也可以自己实现一些过期的策略,不过今天主要研究自带的

惰性过期(被动过期)

这个怎么实现的呢?所谓惰性,是不是就很懒的意思,就是只有访问我的时候,我才会去判断过不过期,不然我懒得去判断,我不会主动去判断过没过期
访问一个key时判断该 key 是否已过期,过期则清除
该策略就可以最大化地节省CPU资源,因为它平时都懒得去判断,所以也没有啥cpu损耗,因为只有访问的时候我才去判断一下!
但是却对内存非常不友好。因为你不实时过期了,该过期删除的就可能一直堆积在内存里面!极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
源码(expireIfNeeded db.c文件下1302行):

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);int retval = server.lazyfree_lazy_expire ?dbAsyncDelete(db,key):dbSyncDelete(db,key);if (retval) signalModifiedKey(NULL,db,key);return retval;
}

我们刚才说了主动过期因为太耗CPU它不用
但是惰性这种又会可能导致大量无效数据堆积在内存里面,我们总得有个办法来解决吧!不能让他一直堆在内存里面啊!
所以我们就有了一个定期过期策略,虽然实时性比不上定时的,但是也足够解决垃圾数据大量堆积在内存的这种情况!

定期过期

所谓定期过期,就是每过一段时间去执行一次删除过期key。
这里需要先学习下redis的一个数据结构:字典 必须学哦
Redis数据结构——dict(字典)
大概的结构如图:

redis的hash默认使用的是ht[0],ht[1]不会初始化和分配空间。
哈希表dictht是用链地址法来解决碰撞问题的。如果节点数量比哈希表的大小要大很多的话,那么哈希表就会退化成多个链表,哈希表本身的性能优势就不再存在,在这种情况下需要扩容。
Redis里面的这种操作叫做rehash。 那么它怎么做rehash的,也是看上面字典这篇文章

我们来看定期过期到底是怎么实现的:
先想一下,如果让我们实现一个定期删除,应该怎么做?
我想到的是定期去循环找过期的key,然后去删掉!巧的是Redis也是这样做的
那么问题又来了:

  1. 我们去循环谁?是不是所有的key
  2. 我们多久循环一次?

第一个问题,我们并不是去循环所有的key,因为Redis里经常会存放巨多的数据,对我们需要经常清理,全部遍历一遍显然不现实,而Redis采取的是取样这个操作
具体实现方式为:

  1. 不是一次性把所有设置了过期时间的数据拿出来,而是按hash桶维度取 里面取值,取到20个值为止,如果第一个有30个,那么也会取30个! 如果一直取不到20,那么最多400个桶
  2. 删除取出值的过期key
  3. 如果400个桶都取不到值,或者取出的key 删除的比例大于10%,继续上 面的操作
  4. 每循环16次会去检测时间,超过指定时间就跳出

ps:按hash桶维度取key的逻辑是:最后一个桶会取完桶内所有的key,不论里面有多少个,每取完一个桶判断一下是否取到了20个,最多取400个桶

现在我们第一个问题解决了!那么第二个问题,定期定期,那么多久去做上面那件时间!那么redis里面有个很重要的概念叫做时间事件,那么这个时间事件是什么意思了,就是定时去做一些事情,那么redis里面有个方法叫serverCron(),在文件server.c中;就是它的时间事件去调用的清理
它里面干了很多事情,比如:

  1. 更新服务器的各类统计信息,比如时间、内存占用、数据库占用情况等
  2. 清理数据库中的过期键值对。
  3. 关闭和清理连接失效的客户端
  4. 尝试进行持久化操作

那么这个时间事件多久去执行一次呢,其实是由你们自己决定的!
redis.conf 中通过 hz 配置,hz代表的意思是每秒执行多少次!默认10次,也就是100ms我们就会去执行定期过期!!

定期过期的逻辑,简单画图

怎么样,学会了Redis的过期策略了吧,还不一键三连

Redis过期策略详解相关推荐

  1. Redis学习笔记--Redis数据过期策略详解==转

    本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...

  2. Redis学习笔记--Redis数据过期策略详解

    过期策略 https://www.cnblogs.com/xuliangxing/p/7151812.html 内存淘汰机制 https://blog.csdn.net/yuanlong122716/ ...

  3. Redis--Redis数据过期策略详解

    本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...

  4. Redis数据过期策略详解

    2019独角兽企业重金招聘Python工程师标准>>> 内存淘汰策略主要采用了6种方式进行内存对象的释放操作 1.volatile-lru:从设置了过期时间的数据集中,选择最近最久未 ...

  5. redid过期策略_Redis数据过期策略详解

    内存淘汰策略主要采用了6种方式进行内存对象的释放操作 1.volatile-lru:从设置了过期时间的数据集中,选择最近最久未使用的数据释放 2.allkeys-lru:从数据集中(包括设置过期时间以 ...

  6. Redis的淘汰策略详解

    接上一篇Redis的过期策略详解 Redis的过期策略详解 所谓的淘汰策略就是: 我们redis中的数据都没有过期,但是内存有大小,所以我们得淘汰一些没有过期的数据!! 那么怎么去淘汰了,我们上一篇讲 ...

  7. Redis系列教程(九):Redis的内存回收原理,及内存过期淘汰策略详解

    Redis内存回收机制 Redis的内存回收主要围绕以下两个方面: 1.Redis过期策略:删除过期时间的key值 2.Redis淘汰策略:内存使用到达maxmemory上限时触发内存淘汰数据 Red ...

  8. redis lua 设置过期_详解 Redis 内存管理机制和实现

    Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...

  9. Redis配置文件redis.conf文件详解

    Redis配置文件redis.conf文件详解 唠嗑 这里面的意思只要看得差不多其实就是已经对redis有熟悉的感觉,就比如 推塔已经推到别人家的大门~~~~~~~~废话不多说直接开始了 知道大家都不 ...

  10. Redis最全详解(一)——基础介绍

    Redis介绍 redis是基于内存可持久化的日志型.Key-Value数据库.redis安装在磁盘,但是数据存储在内存.非关系型数据库NoSql.开源免费,遵守BSD协议,不用关注版权问题. red ...

最新文章

  1. 计算机硬件技术 实验的软件,计算机硬件技术基础软件实验讲义.doc
  2. 看人装X,我就来气,开启极限装X模式
  3. 黑客与网管的30天较量
  4. php empty,isset,is_null比较
  5. python 3.8.2 / 内置的数据结构 / list (类似于 STL 中的 vector)
  6. URI is not registered (Settings | Languages Frameworks | Schemas and DTDs)
  7. golang开发环境配置及Beego框架安装
  8. java自学笔记_JAVA自学笔记(4)
  9. Docker实战 (docker swarm的应用,docker集群的构建,在docker集群中部署服务)
  10. selenium火狐驱动_在Selenium Firefox驱动程序上运行测试
  11. slf4j+log4j在Java中实现日志记录
  12. 一张正面人脸照片,3D真人头像毫秒级重建。
  13. 资产管理(记账系统)03
  14. 计算机视觉将打造中国技术的“胜利者效应”
  15. 科技云报道:腾“云”驾“数”,制造业数字化升级进行时
  16. RecyclerView EditText数据混乱解决
  17. Windows常用快捷组合键整理Dos命令基础集合
  18. Android编程红外编程——红外码详析
  19. 【网络工程师配置篇】华为RIP路由基础配置续篇——重分发
  20. Netty 工作流程图梳理

热门文章

  1. Windows环境搭建Web自动化测试框架Watir(基于Ruby)
  2. 《出版专业实务》(2015年版初级)思考与练习答案 第一章
  3. 中文分词 及发展现状(总结的不错)
  4. JSP教程【2】JSP基本语法
  5. Oracle数据库sql语句空字段筛选方法,sql语句值为空判断方法
  6. Gazebo学习笔记4:模型编辑器
  7. 点餐小程序源码­|PHP微信点餐小程序
  8. 无线打印服务器三星3200,求助三星3200打印机“USB打印机不可用”
  9. HSQL 中修改字段的语法
  10. 《普通心理学》读书笔记