Redis 缓存淘汰机制 :LRU 淘汰

  • U),但仅限于在过期集合的键,使得新添加的数据有空间存放。
  • volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
  • volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

可以看到上面回收策略有俩个纬度,

  1. 回收的键的范围
  2. 过期集合
  3. 不区分是过期集合
  4. 回收策略
  5. 随机
  6. 基于lru

然后基于上面俩种纬度,做个组合就是四种主要策略。

需要注意的这里提到的过期集合,翻译并不是特别准确。它并不是指的这些键是已经过期了,而是指存放着含有过期时间的键;如果一个键没有过期时间,那么就不会存在在该集合中。redis中可以对键设置过期时间,只要是设置了过期时间的键都会存放在redis中专门的一个数据结构。

淘汰逻辑

lru淘汰的主要执行逻辑是在方法freeMemoryIfNeeded(void) 。在方法执行期间,客户端发出的命令会被阻塞住。阻塞命令执行也是为了避免更多的内存被使用。

算法主要逻辑:


do
{
         for(db in dbs)
         {
                根据配置的淘汰策略
                选择最适合的key
                释放资源
          }

}while(freed < tofreed)//已经释放的小于需要释放的

选择最合适的key这一步操作就要结合上面所说的,redis设置的几种淘汰策略。根据redis设置的淘汰策略,选择出需要淘汰的key,然后通过key释放起资源。

需要注意的是在这里的lru也不是严格的lru算法,它是基于一个配置的大小值maxmemory_samples,循环遍历samples,随机获取key然后找到一个最合适的key,然后把该key删除掉。网上也有文章分析,在这种类lru算法下,基本和真正的lru算法的性能没有太大差异,但是相比较于真正严格的lru效率要更高。

判断那个key是最合适是通过比较该key的lru时间和sever里维护的lru_clock差值。server.lruclock在定时事件中会被定时循环更新,会更新成和当前时钟值有个倍数关系的值。

/* Given an object returns the min number of seconds the object was never
 * requested, using an approximated LRU algorithm. */
unsigned long estimateObjectIdleTime(robj *o) {
    if (server.lruclock >= o->lru) {
        return (server.lruclock - o->lru) * REDIS_LRU_CLOCK_RESOLUTION;
    } else {
        return ((REDIS_LRU_CLOCK_MAX - o->lru) + server.lruclock) *
                    REDIS_LRU_CLOCK_RESOLUTION;
    }
}

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PHP在线

设计模式之—单例模式(Singleton)的常见应用场景

单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的...

3396
来自专栏绿巨人专栏

设计模式大集合

943
来自专栏鸿的学习笔记

事务处理的数据存储

在上篇文章我们讨论了数据模型,今天试着讨论更基础的数据存储和搜索。数据存储根据开发者使用,可以分为一般的事务处理和数据分析,因为这两者面临的情况不一样。事务处理...

793
来自专栏犀利豆的技术空间

Redis 数据库、键过期的实现

之前的文章讲解了 Redis 的数据结构,这回就可以看看作为内存数据库,Redis 是怎么存储数据的以及键是怎么过期的。

1012
来自专栏大内老A

WCF技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[上篇]

WCF事务编程主要涉及到这么三个方面:通过服务(操作)契约确定TransactionFlow的策略;通过事务绑定实现事务流转;通过服务操作行为控制事务的自动登记...

1978
来自专栏进击的程序猿

Linearizability versus Serializability

原文 Linearizability和Serializability是在数据库和分布式系统中重要的两个概念,而且比较容易混淆,这篇文章试着对两个概念的不同进行...

763
来自专栏Golang语言社区

高并发服务器的设计--连接池的设计

高并发服务器需要有一些池的设计,如内存池,连接池,数据库连接池。 池(pool)的设计主要考虑到一些资源的频繁申请和释放,尤其是在高并发的服务器中,几万甚至几十...

2714
来自专栏后端技术探索

mysql问题排查实例

最近遇到应用频繁的响应缓慢,无法正常访问。帮忙一起定位原因,最后定位到的问题说起来真的是很小的细节问题,但是就是这些小细节导致了服务不稳定,真是细节决定成败。这...

612
来自专栏码洞

深入理解 RPC 消息协议设计

本节我们开始讲解 RPC 的消息协议设计背后的基本原理,了解 RPC 的协议开发背后有哪些需要考虑的基本点。在通晓原理之后,我们就可以自己设计一套协议来开发属于...

903
来自专栏吉浦迅科技

Independent Thread Scheduling

Volta架构下新增加的一个特性——独立线程调度机制。 ? 独立线程调度机制可以这样理解,主要是为线程与线程之间的通信和同步提供更加灵活的方式。 ? GPU...

3766

扫码关注云+社区