首页 > 数据库 >redis自学(26)

redis自学(26)

时间:2024-04-01 14:13:40浏览次数:12  
标签:26 次数 redis lfu 访问 key TTL 淘汰 自学

内存淘汰策略

内存淘汰:就是当Redis内存使用达到设置的阈值时,redis主动挑选部分key删除以释放更多内存的流程。

Redis会在处理客户端命令的方法processCommand()中尝试做内存淘汰:

 

 

也就是说,redis是在任何命令执行之前,做内存的检查或者说尝试去淘汰一部分内存。

 

Redis支持8种不同策略来选择要删除的key:

noeviction:不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略。

volatile-ttl:对设置了TTL的key,比较key剩余的TTL值,TTL越小越先被淘汰

allkeys-random:对全体key,随机进行淘汰。也就是直接从db->dict中随机挑选

volatile-random:对设置TTL的key,随机进行淘汰。也就是从db->expires中随机挑选

Allkeys-lru:对全体key,基于LRU算法进行淘汰。

Volatile-lru:对设置TTL的key,基于LRU算法进行淘汰。

Allkeys-lfu:对全体key,基于LFU算法进行淘汰。

Volatile-lfu:对设置TTL的key,基于LFU算法进行淘汰。

比较容易混淆的有两个:

LRU(Least Recently Used),最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。

LFU(Least Frequently Used),最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。

 

 

根据策略不同,记录的信息也不一样

LFU的访问次数之所以叫做逻辑访问次数,是因为并不是每次key被访问都计数,而是通过运算:

① 生成0~1之间的随机数R

② 计算1/(旧次数*lfu_log_factor+1),记录为P,lfu_log_factor默认为10

③ 如果R<P,则计数器+1,且最大不超过255

④ 访问次数会随时间衰减,距离上一次访问时间每隔lfu_decay_time分钟(默认1),计数器-1

8个比特位只能记录255个数,也就不可能记录真实的访问次数,所以采用了逻辑访问次数,用一个概率行的增加,上面的意思是,访问了,除了第一次,访问次数有可能不增加,但是只要访问次数多,逻辑计数的值大于其他访问次数少的可能性还是很高的。但是长时间不访问的话,它的次数也是一点点的随时间减少的。

lfu_log_factor和lfu_decay_time都可通过配置文件或者命令行配置。

策略在配置文件设定

 

 

 

 

LRU和LFU以及TTL,不是一个一个去比较的,这样如果redis的缓存数量很大的话,挨个遍历消耗的时间和资源是很恐怖的,所以,搞了一个eviction_pool,随机找一堆,比较谁最应该被淘汰,虽然准确率不如挨个遍历,但是也够满足使用了,最主要是性能好。

随机数maxmemory_samples的默认值是5个,随机到后经过筛选才有可能按照idleTime升序放入eviction_pool,因为eviction_pool满了的情况下,如果idleTime比池子里的最小的idleTime还要小的话,就没有必要放入了,大的话,放入酒吧原先池子里最小的挤出去了。而idleTime根据策略不同计算方式不同(now是指现在时间,maxTTL是指long的最大值即9223372036854775807)。删除的时候倒序从eviction_pool中获取一个key删除。随着循环的次数越来越多,eviction_pool里面的idleTime会越来越大,那么准确率就会越来越高。

标签:26,次数,redis,lfu,访问,key,TTL,淘汰,自学
From: https://www.cnblogs.com/bulesea/p/18108276

相关文章

  • 如何保证MySQL和Redis数据一致性?
    背景在高并发的业务场景中,因为MySQL数据库是操作磁盘效率比较低,因此大多数情况下数据库都是高并发系统的瓶颈。因为Redis操作数据是在内存中进行,所以就需要使用Redis做一个缓存。让请求先访问到Redis,而不是直接访问MySQL数据库。效果图如下查询数据上面的业务场景,就是一个典......
  • C#中的缓存处理方案 (MemoryCache,Redis)
    缓存处理在C#和WPF日常开发中非常重要,可以提高应用程序的性能和响应速度。以下是关于缓存处理方案的知识点,以及可能会在面试中被问到的一些问题和答案:缓存处理方案的知识点:内存缓存:内存缓存是最常见的一种缓存处理方案,它将数据存储在应用程序的内存中,以提高数据的访问速......
  • C#中的消息中间件(RabbitMQ 和 Redis)
    消息中间件是一种用于在分布式系统中进行异步通信的技术,常用于解耦应用程序的不同组件、实现消息传递、提高系统的可伸缩性和可靠性等。以下是关于消息中间件的知识点以及可能会在面试中被问到的一些问题和答案:消息中间件的知识点:消息队列(MessageQueue):消息中间件通常基于消......
  • Redis+lua脚本配合AOP限流
    限流Redis脚本限流脚本配合切面注解定义注解:@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceRateLimiter{/***限流key*/publicStringkey()defaultCacheConstants.RATE_LIMIT_KEY;/**......
  • 如何使用PHP和Redis实现消息队列功能?
    前言今天,我们继续讲消息队列,如何使用Redis实现消息队列的功能。前期准备,需要安装好docker、docker-compose的运行环境。PHP的项目运行环境可以参考下面的文章内容。如何使用docker部署php服务-CSDN博客前面我们也讲了PHP和RabbitMQ实现消息队列的功能,感兴趣的可以查看下面......
  • 一个现代化轻量级的跨平台Redis桌面客户端
    大家好,我是Java陈序员。Redis作为一款高性能的非关系型数据库,可是深受开发者的喜爱,无论是什么开发,都能看到Redis的身影。今天,给大家介绍一款跨平台的Redis客户端连接工具,功能强大,界面美观!关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机......
  • 2673. 使二叉树所有路径值相等的最小代价
    思路先看3节点的子树,想要路径值相同,只能修改叶子节点的值,如上图只能2去+1操作。核心思想:那么对于任意左右孩子节点,想要从根节点下来的路径相同,只能修改孩子节点。所以我们只需要从下至上记录叶子节点到当前节点的路径值,然后计算当前节点和右节点的差值。详细看灵神树上贪心......
  • 【Redis】快速入门 数据类型 常用指令 在Java中操作Redis
    文章目录一、简介二、特点三、下载与安装四、使用4.1服务器启动4.2客户端连接命令4.3修改Redis配置文件4.4客户端图形化界面五、数据类型5.1五种常用数据类型介绍5.2各种数据类型特点六、常用命令6.1字符串操作命令6.2哈希操作命令6.3列表操作命令6.4集合操......
  • 从 Redis 开源协议变更到 ES 国产化:一次技术自主的机遇
    引言近日,RedisLabs宣布其主导的开源项目Redis将采用双重源代码可用许可证(RSALv2)和服务器端公共许可证(SSPLv1)。这一重大决策标志着Redis从传统的BSD许可证向更加严格的控制权转变,同时也引发了广泛的社区和行业讨论。这不仅是一个关于许可证变更的故事,更是关于开源社区如何......
  • Redission分布式锁介绍和配置引入
        本人在实际项目用于确保Key一致性经常使用的一种加锁方式,帮助分布式环境中互斥访问。很多人问不用锁不是一样完成目标吗?但需要清楚的是这是在高并发的场景下,多节点同时访问缓存的场景,是一般单体项目所无法比拟的,使用锁方式可以控制并发访问,避免缓存击穿和雪崩等问......