前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis技术知识总结之三——Redis数据淘汰机制

Redis技术知识总结之三——Redis数据淘汰机制

作者头像
剑影啸清寒
发布2020-07-09 10:20:27
7140
发布2020-07-09 10:20:27
举报
文章被收录于专栏:琦小虾的Binary

接上篇《Redis技术知识总结之二——Redis线程模型》

三. Redis 的数据淘汰机制

3.1 Redis 的数据淘汰策略

当 Redis 内存超出物理内存限制时,为了保持高效的可用性,Redis 需要对内存中部分数据进行淘汰。Redis 早起版本使用的数据淘汰策略是 LRU (Least Recently Used,最近最少使用) 策略,LRU 策略是基于最近访问时间进行排序、淘汰的。后来加入了 LFU (Least Frequency Used,最近最低频率) 策略。

Redis 主要使用的还是 LRU 策略。

  • noeviction: 可以继续读请求,不可以进行写请求。
    • 返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但 DEL 和几个例外);
    • 默认淘汰策略。
  • volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在设置了过期时间的键,使得新添加的数据有空间存放。
  • volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在设置了过期时间的键
  • volatile-ttl: 回收设置了过期时间的键,淘汰策略是优先回收剩余时间 (TTL) 较短的键,使得新添加的数据有空间存放。
  • allkeys-lru: 对全部集合进行回收,尝试回收最少使用的键 (LRU),使得新添加的数据有空间存放。
  • allkeys-random: 对全部集合进行回收,回收随机的键使得新添加的数据有空间存放。
  • volatile-lfu: 对设置了过期时间的键进行 LFU 策略的过期筛选;
  • allkeys-lfu: 对全部的键进行 LFU 策略的过期筛选;

3.2 LRU 策略

Redis 的数据都是由 key-value 形式构成的,在实现 LRU 的内存淘汰机制时,除了 key-value,LRU 还需要维护一个列表,链表尾部的数据是最少被访问的数据。列表按照最近访问时间进行排序。当内存达到物理内存限制触发 LRU 回收时,对链表尾部的 k-v 进行回收。

但 Redis 的 LRU 并不是这样执行的,Redis 使用了一种近似 LRU 算法。对于所有 Redis 对象,对象头中包含一个 24bit 的信息,作为对象热度的标志。在 LRU 淘汰算法中,该标志是一个时间戳,记录了最近一次访问该标志位的时间。

在触发了 LRU 淘汰时,Redis 会随机抽取若干个(默认是 5 个)key,然后删掉最旧的 key。如果这时候内存依旧超出限制,则再次抽选、删除最旧的 Key 值,直到内存低于最大内存限制为止。

Redis Object 的对象头如下所示:

代码语言:javascript
复制
typedef struct redisObject {
    // 对象类型,如 zset, set, hash 等
    unsigned type: 4; 
    // 对象编码如 ziplist, inset, skiplist 等
    unsigned encoding: 4;
    // 对象的热度
    unsigned lru: 24;
    // 引用计数
    int refcount;
    // 对象的 body
    void *ptr;
}

其中,lru 值即为表示热度的值。在 LRU 模式下,该字段存储的时间戳是 Redis 服务器的时钟信息 server.lruclock,单位为毫秒。server.lruclock 持续更新,某对象被访问时,对象头中的 LRU 值被更新为当前 server.lruclock 的值,最后当触发 LRU 内存淘汰时,该对象的 LRU 值会与当前 server.lruclock 进行取模等一系列运算,即可得到 LRU 值。

3.3 LFU 策略

LFU 策略与 LRU 的计算方式大致相同,都是根据 Redis 对象头的 LRU 值与 server.lruclock 值进行计算的。但是 LFU 策略下,24bit 的 lru 值被分为 16+8 两部分。

  • ldt (last decrement time,): 前 16 位,记录上一次更新时间,计算单位是分钟。
    • ldt 不是对象被访问的时候被更新,而是在 Redis 触发淘汰逻辑时进行更新;
  • logc (logistic counter,对数计数): 后 8 位记录频率信息,且以对数形式储存,计算单位是分钟。
    • logc 有衰减算法,在 ldt 更新时触发。当前 logc 值减去对象空闲时间,除以一个衰减系数;
    • 由于 logc 的统计的是对数信息,所以它的 +1 策略是基于概率的 +1;于是当对数值越大时,+1 操作概率越小,就越难被更新。大致流程如下:
      1. 计算差值:当前对数值 - 基值 (5)
      2. 计算更新 +1 操作概率:p = 1 / 差值
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/07/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三. Redis 的数据淘汰机制
    • 3.1 Redis 的数据淘汰策略
      • 3.2 LRU 策略
        • 3.3 LFU 策略
        相关产品与服务
        云数据库 Redis
        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档