首页 > 数据库 >Redis 为何使用Nearly LRU 算法淘汰数据

Redis 为何使用Nearly LRU 算法淘汰数据

时间:2023-04-21 18:33:34浏览次数:37  
标签:采样 元素 Redis 访问 算法 LRU Nearly

Redis 使用该 LRU 算法淘汰过期数据吗?不是的。

  • 由于 LRU 算法需要用链表管理所有的数据,会造成大量额外的空间消耗。
  • 大量的节点被访问就会带来频繁的链表节点移动操作,从而降低了 Redis 性能。

Redis的内存空间是很宝贵的,而维护LRU的双向链表需要使用比较多的额外空间,至少需要一个前向指针、一个后向指针和一个指向数据的指针。

Redis的作者使用了一种基于随机采样的近似LRU(NearlyLRU),并不是真正的 LRU,Redis 通过对少量的 key 采样,并淘汰采样的数据中最久没被访问过的 key,它在Redis里面是不需要花费额外空间的。

 

一、随机采样

随机访问更加一般的情况我们想要的是频繁被访问的元素不会被淘汰,而LRU刚好就有这种思想,其实LRU也可以实现为一个根据元素被访问时间戳排序的列表,每次淘汰列表的尾部的元素,也就是时间戳最小的元素。

而NearlyLRU就是利用了这个时间戳的思想,也就是每个元素带有最后一次被访问的时间戳(Redis里面本来就有记录,因此不需要额外的空间),但是它没有去维护一个堆,因此它只能随机进行采样。淘汰算法流程如下:

  1. 从所有元素里面随机采样5个元素
  2. 淘汰5个里面最后一次被访问的时间戳最小的元素

可以发现第2步其实就有LRU的思想,只是LRU是选取全部元素里面最后一次被访问的时间戳最小的元素,而NearlyLRU则是采样一小批。

因此NearlyLRU其实命中率是不如LRU的,但是它的好处也是明显的,不需要额外的数据结构。

如果想提高命中率,可以增大采样数量,这样会更加接近LRU,当然时间成本也会相应的上升。

 

二、优化场景总结

1、Memcached

Memcached 前面有文章已讲解过,思想与Multi Queue类似。

2、MySQL buffer pool

MySQL change buffer缓存,使用的是类LRU-k的算法,读取新数据页页,不是放于LRU列表首部,而是放于5/8处,因为索引或数据扫描需要访问很多页,非活跃热点数据,放于首部,可能会移除真正的热点数据

3、Redis

Redis中的数据整体上是一个大的字典,Redis采用了基于采样的近似LRU算法,redis并没有去遍历所有对象,每个对象都记有最近访问时间戳。

LRU算法也比较简单,Redis有一个全局的LRU时钟,每次随机取出5(maxmemory-samples默认参数)个redis对象,淘汰时间戳最小的。

 

 

 

 

 

标签:采样,元素,Redis,访问,算法,LRU,Nearly
From: https://www.cnblogs.com/binyue/p/17341392.html

相关文章

  • redis:清空 spring boot注解式
    flushall清空打开D:\ProgramFiles\Java\Redis-x64-3.2.100\redis-cli.exeauth123456flushall  dockerdockerexec-it65e343434e6eredis-cliauth123flushall exit @Cacheable :根据方法的请求参数对其结果进行缓存参数解释examplevalue缓存的名称,在spring配置文......
  • Redis-Cluster(redis集群)
    Redis-Cluster(redis集群)Redis-Cluster的背景介绍1.1存在的问题1.并发量:单机Redisqps为10w/s,但是我们需要百万级别的并发量2.数据量:机器内存16-256g,如果存储500g数据呢1.2解决#解决方法:加机器,分布式rediscluster在15年加入了,满足了分布式的需求数据发布(分布式数据......
  • redis2
    1哈希类型###!---hget,hset,hdelhgetkeyfield#获取hashkey对应的field的value时间复杂度为o(1)hsetkeyfieldvalue#设置hashkey对应的field的value值时间复杂度为o(1)hdelkeyfield#删除hashkey对应的field的值时间复杂度为o(1)#测试hsetuser:1:in......
  • redis的key命名规范
    一、键值设计1.key名设计【建议】:可读性和可管理性以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:idredis使用的时候注意命名空间,一个项目一个命名空间,项目内业务不同命名空间也不同。一般情况下:1)第一段放置项目名或缩写如project2)第二段把表名......
  • 【汇智学堂】单机部署使用Redis
    First:https://github.com/microsoftarchive/redis/releasesDownload,unzip,asthis:Second,runcmd,startredisserviceredis-server.exeredis.windows.confAsabove,serviceissuccess。Thisisserver,ifclosethiswindow,servicewillbeclosed.ThirdAnotherc......
  • Redis 热 Key 发现以及解决办法
    内容转自:https://joyspace.jd.com/sheets/YZxilLHtAc98E1k5kHDK一、背景介绍  最近在技术交流微信群里看大家讨论技术,其中有谈到 Redis 热 Key 的一些问题解决方案,我也仔细思考了一下我们目前系统中 Redis 的使用场景,我们是不是也存在热 Key 问题,或者说如果我们也出......
  • 非关系型数据库安装-redis安装
    linux安装redis最新稳定版本原创 PHP星 编程经验共享 2023-03-1608:00 发表于广东收录于合集#linux18个#redis5个在安装redis之前我们需要提前安装编译安装需要的扩展库,例如:gcc,make等。但是最新版本要求需要python3的支持,所以我们还需要安装python3.1.安装......
  • Redis - 数据类型映射底层结构
    简介从数据类型上体现就是,同一个数据类型,在不同的情况下会使用不同的编码类型,底层所使用的的数据结构也不相同。字符串对象字符串对象的编码可以是int、raw和embstr三者之一。embstr编码是专门用于保存简短字符串的一种优化编码方式,与raw编码会调用两次内存分配函数分......
  • Spring中Redis存取数据示例
    1.导入StringRedisTemplate类importorg.springframework.data.redis.core.StringRedisTemplate;2.自动装配@AutowiredprivateStringRedisTemplatestringRedisTemplate;3.存数据(设置5分钟过期)Stringtoken=UUID.randomUUID().toString();Stringkey=RedisPrefix......
  • Redis 缓存失效问题
    目录Redis缓存缓存击穿场景解决方案:缓存穿透场景解决方案缓存雪崩场景解决方案大量数据同时过期Redis故障宕机Redis缓存引入了缓存层,就会有缓存异常的三个问题,分别是缓存雪崩、缓存击穿、缓存穿透。它们的区别如下:缓存击穿场景高并发流量场景下,大量请求同时访问一个热点......