本文知识点

过期数据概念

数据删除策略

逐出算法

过期数据

先来看三个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. VUE基础插值表达式

    vue 基本操作插值表达式 首先使用js导入vue.js文件 <style> [v-claok]{ display:none;//解决闪烁问题 } </style> <d ...

  2. python爬取页面内容

    from selenium import webdriverimport xlwt driver = webdriver.Chrome(r'D:\chromedriver.exe')driver.ma ...

  3. 面向对象案例-学生信息管理系统V1.1

    1.学生类 package com.qfedu.student.entity; /** * 学生类实体 * * @author GGGXXC * */ public class Student { p ...

  4. js解析MarkDown语法

    1.问题描述: 我们使用MarkDown编辑器之后,比如我们写的MarkDown的语法是:  # 一级标题  ## 二级标题  ### 三级标题 这种语法我们最终要转换成HTML的格式最终要存入数据库 ...

  5. Jenkins在Pod中实现Docker in Docker并用kubectl进行部署

    Jenkins在Pod中实现Docker in Docker并用kubectl进行部署 准备工作 安装Jenkins Jenkins的kubernetes-plugin使用方法 说明 Jenkins的 ...

  6. Rocket - devices - TLError

    https://mp.weixin.qq.com/s/s_6qPkT2zwdqYLw5iK7_8g 简单介绍TLError的实现. 1. 继承自DevNullDevice TLError继承自DevN ...

  7. excel表 更改后缀名 xlsx转成csv csv转换xlsx

    excel 转成CSV 步骤: 1.打开你需要转换的Excel表格.这里特别介绍一下多个数字的现象,我们知道,像身份证这些多位数字,在正常表格里都是会加上一个'来使其显示的,或者换成"文本& ...

  8. Java实现台阶问题

    1 问题描述 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级,求总共有多少种跳法. 2 解决方案 2.1 递归法 如果整个台阶只有1级,则显然只有一种跳法.如果台阶有2级,则有两种跳法:一种是分 ...

  9. Java 虚拟机是如何判定两个 Java 类是相同的?

    Java 虚拟机是如何判定两个 Java 类是相同的? 答:Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样.只有两者都相同的情况,才认为两个类是相同的.即便是同样的字节代码 ...

  10. 循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用

    在我前面随笔<循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用>里面曾经介绍过一些常规的界面组件的处理,主要介绍到单文本输入框.多文本框.下拉列 ...