将Redis用作LRU缓存

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 当Redis用作缓存时,通常很方便在添加新数据时让它自动逐出旧数据。此行为在开发人员社区中是众所周知的,因为它是流行的内存缓存系统的默认行为 。

将Redis用作LRU缓存


当Redis用作缓存时,通常很方便在添加新数据时让它自动逐出旧数据。此行为在开发人员社区中是众所周知的,因为它是流行的内存缓存系统的默认行为 。


LRU实际上只是支持的驱逐方法之一。本页涵盖Redis maxmemory指令的更一般主题,该指令用于将内存使用量限制为固定数量,并且还深入介绍了Redis使用的LRU算法,实际上是确切的LRU的近似值。


从Redis版本4.0开始,引入了新的LFU(最不常用)驱逐策略。本文档的单独部分对此进行了介绍。


Maxmemory配置指令

使用maxmemory配置指令是为了将Redis配置为对数据集使用指定的内存量。可以使用redis.conf文件来设置配置指令,或者稍后在运行时使用CONFIG SET命令来设置。


例如,为了配置100 MB的内存限制,可以在redis.conf文件内部使用以下指令。

maxmemory 100mb

设置maxmemory为零将导致没有内存限制。这是64位系统的默认行为,而32位系统使用3GB的隐式内存限制。


当达到指定的内存量时,可以在不同的行为之间进行选择,这称为策略。Redis只会为可能导致使用更多内存的命令返回错误,或者它可以逐出某些旧数据,以便在每次添加新数据时返回到指定的限制。

驱逐政策

maxmemory使用maxmemory-policy配置指令配置达到限制时,会发生确切的行为Redis 。


可以使用以下策略:

noeviction:在达到内存限制并且客户端尝试执行可能导致使用更多内存的命令时返回错误(大多数写入命令,但DEL和一些其他异常)。

allkeys-lru:通过尝试先删除较新使用的(LRU)键来退出键,以便为添加的新数据腾出空间。


volatile-lru:通过尝试先删除较新使用的(LRU)密钥来退出密钥,但仅在已设置了expire set的密钥之间,以便为添加的新数据腾出空间。

allkeys-random:随机逐出密钥,以便为添加的新数据腾出空间。

volatile-random:随机逐出键,以便为添加的新数据腾出空间,但仅逐出设置了expire set的键。


volatile-ttl:逐出设置了expire的键,并尝试首先逐出具有较短生存时间(TTL)的键,以便为添加的新数据腾出空间。

该政策挥发性-LRU,挥发性随机和挥发性-TTL的行为很像noeviction如果没有钥匙驱逐匹配的先决条件。

选择正确的逐出策略很重要,具体取决于应用程序的访问模式,但是您可以在应用程序运行时在运行时重新配置该策略,并使用Redis INFO输出监视缓存未命中和命中的次数,以调整设置。


一般而言,根据经验:

当您希望请求的流行程度具有幂律分布时,请使用allkeys-lru策略,也就是说,您希望访问元素的子集比访问其他元素更多。如果不确定,这是一个不错的选择。

如果您具有对所有密钥进行连续扫描的周期性访问,或者当您期望分布是统一的(所有元素以相同的概率被访问)时,请使用allkeys-random。


如果您希望能够在创建缓存对象时通过使用不同的TTL值向Redis提供有关哪些是最佳到期候选者的提示,请使用volatile-ttl。


当您要使用单个实例进行缓存并拥有一组持久密钥时,volatile-lru和volatile-random策略主要有用。但是,通常最好运行两个Redis实例来解决此问题。

还值得注意的是,将密钥设置为过期会消耗内存,因此使用诸如allkeys-lru之类的策略会提高内存效率,因为无需为要在内存压力下驱逐密钥设置过期。


驱逐过程如何进行

重要的是要了解驱逐过程的工作方式如下:

客户端运行新命令,从而添加更多数据。

Redis会检查内存使用情况,如果大于使用maxmemory限制,则会根据策略逐出密钥。

执行新命令,依此类推。

因此,我们不断越过内存限制,然后越过该限制,然后逐出按键以在限制范围内返回,从而不断跨越该限制。

如果某个命令导致大量内存被使用(例如,将较大的交集存储到新键中)一段时间,则内存限制可能会超出明显的数量。


近似LRU算法

Redis LRU算法不是确切的实现。这意味着Redis无法选择最好的驱逐对象,即过去访问最多的访问。取而代之的是,它将尝试对LRU算法进行近似处理,方法是对少量密钥进行采样,然后从采样的密钥中驱出最好的(访问时间最长)密钥。

但是,自Redis 3.0起,对该算法进行了改进,使其也可以将大量优秀候选人逐出。这提高了算法的性能,使其能够更接近地逼真的LRU算法的行为。

Redis LRU算法的重要意义在于,您可以通过更改样本数量来检查每次逐出,从而调整算法的精度。此参数由以下配置指令控制:

maxmemory-samples 5

Redis之所以不使用真正的LRU实现,是因为它占用更多内存。但是,近似值实际上与使用Redis的应用程序等效。以下是Redis使用的LRU近似与真实LRU比较的图形比较。


LRU比较

生成以上图形的测试用给定数量的密钥填充了Redis服务器。密钥是从第一个到最后一个访问的,因此第一个密钥是使用LRU算法驱逐的最佳候选者。后来又添加了50%的密钥,以强制淘汰一半的旧密钥。

您可以在图形中看到三种点,形成三个不同的带。

浅灰色带是被逐出的对象。

灰带是未被逐出的对象。

绿带是添加的对象。


在理论上的LRU实现中,我们期望在旧密钥中,前半部分将过期。相反,Redis LRU算法只会概率地使较早的密钥过期。

如您所见,与Redis 2.8相比,Redis 3.0在5个样本上做得更好,但是Redis 2.8仍保留了最新访问的对象中的大多数。在Redis 3.0中使用10的样本大小,近似值非常接近Redis 3.0的理论性能。


请注意,LRU只是预测未来将访问给定密钥的可能性的模型。此外,如果您的数据访问模式与幂律极为相似,则大多数访问将位于LRU近似算法将能够很好处理的密钥集中。

在仿真中,我们发现使用幂定律访问模式,真实LRU和Redis近似之间的差异很小或不存在。


但是,您可以以一些额外的CPU使用为代价将样本大小增加到10,以接近真实的LRU,并检查这是否会导致高速缓存未命中率有所不同。

使用CONFIG SET maxmemory-samples <count>命令以不同的样本量值在生产中进行实验非常简单。


新的LFU模式

从Redis 4.0开始,可以使用新的“ 最少使用”逐出模式。在某些情况下,此模式可能会更好地工作(提供更好的命中率/未命中率),因为使用LFU Redis会尝试跟踪物品的访问频率,因此,极少使用的物品会被驱逐,而经常使用的物品则有更高的机会保留在内存中。


如果您认为在LRU,最近访问过但实际上几乎从未请求过的项目不会过期,因此风险在于逐出将来有更高机会被请求的密钥。LFU没有这个问题,通常应该更好地适应不同的访问模式。


要配置LFU模式,可以使用以下策略:

volatile-lfu 使用具有过期集的密钥在近似LFU中进行驱逐。

allkeys-lfu 使用近似的LFU退出任何密钥。

LFU近似于LRU:它使用概率计数器(称为莫里斯计数器),以便仅使用每个对象几个位来估计对象访问频率,并结合一个衰减周期,以便使计数器随时间减少:在某些时候,我们不再希望将密钥视为频繁访问的密钥,即使它们是过去的密钥也是如此,因此该算法可以适应访问模式的转变。

这些信息的采样方式与LRU发生的情况类似(如本文档前面的部分中所述),以选择驱逐候选人。


但是,与LRU不同,LFU具有某些可调参数:例如,如果频繁访问的项目不再被访问,应该将其降低多快?还可以调整Morris计数器范围,以使算法更好地适应特定的用例。

默认情况下,Redis 4.0配置为:

在大约一百万个请求时使计数器饱和。

每隔一分钟使计数器衰减一次。

这些应该是合理的值,并且已经过实验测试,但是用户可能希望使用这些配置设置来选择最佳值。


有关如何调整这些参数的说明,可以redis.conf在源代码发行版的示例文件中找到,但简要地说,它们是:

lfu-log-factor 10
lfu-decay-time 1

衰减时间是显而易见的时间,它是在采样时发现计数器早于该值应衰减的分钟数。平均值的一个特殊值0:每次扫描时总是使计数器衰减,并且很少有用。

计数器对数因子会更改要使频率计数器达到饱和所需的命中次数,频率计数器刚好在0-255的范围内。因数越高,为了达到最大值需要更多的访问。根据下表,系数越低,计数器的分辨率越低,分辨率越好:

factor 100 hits 1000 hits 100K hits 1M hits 10M hits
0 104 255 255 255 255
1 18 49 255 255 255
10 10 18 142 255 255
100 8 11 49 143 255


因此,基本上,因素是在具有较低访问权限的更好区分项与具有较高访问权限的区分项之间进行权衡。示例redis.conf文件自我记录注释中提供了更多信息。

由于LFU是一项新功能,因此与LRU相比,我们将非常感谢您提供有关LFU在您的用例中的性能的反馈。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
2天前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
10天前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
71 22
|
9天前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
72 7
|
14天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
46 10
|
1月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
|
1月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
68 6
|
1月前
|
缓存 NoSQL 关系型数据库
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
本文深入探讨了Redis缓存的相关知识,包括缓存的概念、使用场景、可能出现的问题(缓存预热、缓存穿透、缓存雪崩、缓存击穿)及其解决方案。
164 0
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
|
14天前
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
46 5
下一篇
无影云桌面