本文知识点

过期数据概念

数据删除策略

逐出算法

过期数据

先来看三个key值,分别为sex、name、age。

这三个值设置的指令为 set name kaka setex age 100 24 setex sex 10 1

在redis中我们可以使用ttl来获取某个key的状态,下面我们来使用ttl分别获取一下上边name、age、sex的状态

可以看到出来了三个值,分别为 -1  775   -2

那么这三个值给出的信息是什么呢!

  • -1 表示永久有效的数据
  • 775 这个值是设置在age上,使用的指令为setex age 1000 24,表示为剩余有效时间
  • -2 表示已经过期的数据,或者是被删除的数据,或者说是么有定义的数据

过期数据的存储结构

  • 当我们设置一个带有时效性的name时,redis存储的是一个内存地址0x10101
  • 然后redis会再开辟一个空间用来存储带有时效性的key
  • 但是存储方式是key对应的内存地址  和  过期时间

    那么今天我们所说的redis删除策略,就是删除的这部分数据。

定时删除

定时删除就是写一个定时器,然后当key的时间过期后,定时器任务立即对过期的key进行删除

优点:可想而知key到期就删,肯定对内存时最友好的,节约内存

缺点:redis单线程的特性是所有的命令都在按照一定的顺序进行执行。key值到期就删cpu的压力就会变大,会直接影响到redis服务器响应时间和IO

定时删除就是用时间来换取空间

当执行完定时删除后,key值对应的数据会被删除,同时在过期的内存区里边也会直接删除。

惰性删除

在来看这个图当key值过期后不会直接删除,那是什么时候删除呢!继续往下看

当我们使用惰性删除时,数据到期了也不会自动删除,那么他的删除方式是,在下一次在获取这个key值时,会做一个判断,判断这个key是否过期,如果过期了在执行删除。

也就是说当再次执行get name时  会走一个函数expirelfNeeded()  这个函数就是判断此key是否过期的。过期的返回nil,然后从内存在进行删除

优点:会减少一定的CPU性能,只有到必须要删的时候才会删除

缺点:那肯定就是内存压力大了,例如一些热点新闻,热点过了就基本没人访问了,没有人访问这个key就一直存在,就会出现长期占用一定的内存空间

也就说这种方式是用空间换时间

定期删除

在上文中我们提及了俩种删除方式,一种是定时删除,一种是惰性删除。一个是用空间换时间。一个是用时间换空间。俩种方案都是比较极端的方式。那么接下来我们在来看看定期删除的实现方案。

先来看一下redis的存储空间,一共有默认为16个,在redis.conf里边有一个配置参数database这个参数控制的。每个数据库都有自己的过期分区,里边存储就是数据地址  和  数据过期时间。

实现方式

redis在启动时,会取读取server下的hz的值,默认为10。这个值直接在终端使用info server就可以查看的到

然后会每秒钟执行server下hz次  进行serverCron()轮询

继续使用databasesCron对redis的16个库进行挨个访问信息

访问时候会再执行activeExpireCycel对每个expires[*]逐一进行检测,每个执行的时间为250ms / server hz这个参数

在对每个expirs[*]逐一检测时,会随机拿出ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC个可以进行检测

  • 如果key超时,直接删除key
  • 一轮中删除的key数量>ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC*25%继续循环该过程
  • 如果一轮中删除的key数量<=ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC25% ,检查下一个expires[]

那么现在问题来了,我们的250ms / hz这个时间执行完了,但是把expires的16个数据库没有循环完怎么办呢!  下次来在循环那个库呢!  其实这个值是有存的,就是current_db这个值。这个值会记录activeExpireCycel 下次进入那个expires[*]执行

特点1:CPU使用没有高峰值,检测频率自定义设置

特点2:内存压力不会很大, 长时间占用的内存会被持续的清理

逐出算法

在上文中我们说了三种删除策略,但是这三种策略都是相对于设置了有效期的key才会有效。

那现在我们的redis使用的内存不足了,就会使用逐出策略来保证redis的正常使用。

redis在每次执行命令前会调用freeMemorylfNeeded()检测内存是否充足,当不充足时就会清理一些key,这种清除数据的策略称为逐出策略。

redis最大可使用内存的参数为:maxmemory  默认为0   指的是占用物理内存的比例   一般设置50%就可以了

每次选取待删除key的个数:maxmemory-samples

删除策略:maxmemory-policy

下面我们来着重说明删除策略

  • 检测易失数据(也就是我们设置了有效期,但是还没有到期的数据,就是上文expires[*])
    • volatile-lru:挑选最近少使用的数据
    • volatile-lfu:挑选最近使用次数最少的数据
    • volatile-ttl:挑选将要淘汰的数据
    • volatile-random:随机选择

接下来看一幅图

  • 9s就是现在的时间
  • 距离9s最长的一个key就是age
  • 使用次数最少的就是gender这个key
  • 如果按照volatile-lru就会把age删除掉
  • 如果按照volatile-lfu就会把gender删除掉
  • 检测全部数据
    • allkeys-lru:挑选最近少使用的数据
    • allkeys-lfu:挑选最近使用次数最少的数据
    • allkeys-random:全库随机删除
  • 放弃数据驱逐
    • no-enviction  : 数据不会进行任何的删除,直到内存用完,引发oom错误。

总结

以上就是redis对数据的删除策略和逐出策略。

这里就一个注意点就是在逐出策略中,易失数据指的是设置了过期时间的key,并非永久性的值。

全库是指的全部的值,设置了过期时间和永久数据。

Redis删除策略和逐出策略的更多相关文章

  1. redis 数据删除策略和逐出算法

    数据存储和有效期 在 redis 工作流程中,过期的数据并不需要马上就要执行删除操作.因为这些删不删除只是一种状态表示,可以异步的去处理,在不忙的时候去把这些不紧急的删除操作做了,从而保证 redis ...

  2. Redis 数据结构与内存管理策略(上)

    Redis 数据结构与内存管理策略(上) 标签: Redis Redis数据结构 Redis内存管理策略 Redis数据类型 Redis类型映射 Redis 数据类型特点与使用场景 String.Li ...

  3. Redis 数据结构与内存管理策略(下)

    Redis 数据结构与内存管理策略(下) 标签: Redis Redis数据结构 Redis内存管理策略 Redis数据类型 Redis类型映射 Redis 数据类型特点与使用场景 String.Li ...

  4. Redis数据过期和淘汰策略详解(转)

    原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...

  5. Redis(二十):Redis数据过期和淘汰策略详解(转)

    原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...

  6. 动手实现 LRU 算法,以及 Caffeine 和 Redis 中的缓存淘汰策略

    我是风筝,公众号「古时的风筝」. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 那天我在 LeetCode 上刷到一道 LRU 缓存机制的问题, ...

  7. Storage API简介和存储限制与逐出策略

    目录 简介 常用的客户端存储方式 data storage的类型 逐出策略 Storage API estimate persist persisted 综合使用 总结 简介 对于现代浏览器来说,为了 ...

  8. Redis++:Redis 内存爆满 之 淘汰策略

    前言: 我们的redis使用的是内存空间来存储数据的,但是内存空间毕竟有限,随着我们存储数据的不断增长,当超过了我们的内存大小时,即在redis中设置的缓存大小(maxmeory 4GB),redis ...

  9. 你应该知道的Redis过期键和过期策略

    今天,我和大家分享一篇关于 Redis 有关过期键的内容,主要有四个内容: 如何设置过期键 如何取消设置的过期时间 过期键的过期策略是怎样的 RDB.AOF 和复制对过期键的处理又是怎样的 设置键的生 ...

随机推荐

  1. java链接redis

    创建maven项目 2.导入jar包 <dependencies> <dependency> <groupId>redis.clients</groupId& ...

  2. GPG配置、命令、实例与apt-key密钥测试

    环境 Ubuntu18.04 gpg version 2.24 参考文档 GnuPG (简体中文) 例子文档 阮一峰 key Management 简介 他人用公钥来加密,自己用私钥来解密 自己用私钥 ...

  3. redis使用技巧十连胜,学会工作六到飞起

    Redis 在当前的技术社区里是非常热门的.从来自 Antirez 一个小小的个人项目到成为内存数据存储行业的标准,Redis已经走过了很长的一段路. 随之而来的一系列最佳实践,使得大多数人可以正确地 ...

  4. 这个Maven依赖的问题,你敢说你没遇到过

    Maven 依赖没处理好的话经常会导致发生一些问题,非常烦.今天给大家分享一个依赖相关的问题,说不定你之前就遇到过. 问题背景 有个 ES 搜索的项目,刚开始还是好好的状态,过了一段时间,然后就发现启 ...

  5. 【asp.net core 系列】2 控制器与路由的恩怨情仇

    0. 前言 在上一篇文章中,我们初步介绍了asp.net core,以及如何创建一个mvc项目.从这一篇开始,我将为大家展示asp.net core 的各种内容,并且尝试带领大家来挖掘其中的内在逻辑. ...

  6. 概念辨析-Description Language还是Description Library?

    https://mp.weixin.qq.com/s/p7eyD6GkniFGHrnr8t2SZQ   概念辨析-Description Language还是Description Library? ...

  7. 【Storm】与Hadoop的区别

    1)Storm用于实时计算,Hadoop用于离线计算. 2)Storm处理的数据保存在内存中,源源不断:Hadoop处理的数据保存在文件系统中,一批一批处 理. 3)Storm的数据通过网络传输进来: ...

  8. 【SpringMVC】使用三层架构实现登录,注册。(下篇)

    上篇写了构思与界面层,本篇写一下业务逻辑层.数据访问层 目录 业务逻辑层 包:pojo 用户类(JavaBean):User public class User { private String us ...

  9. Java实现 LeetCode 500 键盘行

    500. 键盘行 给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词.键盘如下图所示. 示例: 输入: ["Hello", "Alaska", & ...

  10. Java实现 LeetCode 424 替换后的最长重复字符

    424. 替换后的最长重复字符 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 注意: 字 ...