九、redis缓存的回收策略-LRU算法

导读

前面文章【一、深入理解redis之需要掌握的知识点 】中,我们对redis需要学习的内容框架进行了一个梳理。

二、redis中String和List两种数据类型和应用场景 】、【二、redis中Hash、Set、SortedSet应用场景 】两篇文章我们对redis中String、List、Hash、Set、SortedSet五种数据类型做了一下讲解,并且对他们各自的应用场景进行了介绍。

三、redis数据存储之跳跃表(SKIP LIST) 】深入学习了支撑SortedSet排序背后的数据结构,跳跃表;

【四、redis持久化之RDB与AOF 】学习了redis中的两种持久化策略:RDB(快照)和AOF(追加日志);
五、redis集群进化过程 】文章中我们学习了redis集群的进化过程,包括解决单点故障问题和性能瓶颈问题等。
六、redis中AKF问题解决方案 】讲解了Redis使用及集群进化过程中AKF问题的解决方案。
七、redis中CAP问题解决方案-Paxos理论过半通过 】我们讲解了Redis使用过程中出现CAP问题的解决方案,以及初步认识Paxos分布式一致性协议。
八、redis中布式锁的实现及原理 】讲解了redis中布式锁的理论、原理及解决方案。

本章我们将要讲解redis中如何配置缓存回收策略及回收策略的几种模式,另外还要讲解回收策略的执行过程和redis中实际使用的回收策略。

注意:Redis缓存中使用LRU算法回收旧数据。LRU是redis支持的唯一的回收算法。

在这里插入图片描述

如果大家在工作、学习、面试中针对redis还有什么疑问或者其他问题,可以评论区告诉我。
为了保证可以连续不间断地获取最新的技术分析及讲解,建议关注本博客【不吃_花椒】。

1.MaxMemory配置指令

使用maxmemary配置指令配置redis存储数据时限制的内存大小。通过在redis.conf配置文件中设置该指令或者使用CONFIG SET命令进行运行时设置。
例如为了配置内存限制为100mb,以下的指令可以放在redis.conf文件中。“maxmemory 100mb”。
设置maxmemory为0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。
当指定的内存限制大小达到时,需要选择不同的行为,也就是策略。 Redis可以仅仅对命令返回错误,这将使得内存被使用得更多,或者回收一些旧的数据来使得添加数据时可以避免内存限制。

2.redis的回收策略

当redis中存储的数据达到maxmemary最大限制时候,redis只有的行为有redis的maxmemary-policy指令来进行配置。
Redis中存在以下几种配置策略:

noeviction:返回错误信息。当内存限制达到并且客户端尝试执行会让内存更多的命令时。
allkeys-lru:尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
volatile-lru:尝试回收过期集合内最少使用的键(LRU),使得新添加的数据有空间存放。
allkeys-random:回收随机的键,使得新添加的数据有空间存放。
volatile-random:在过期集合内回收随机的键,使得新添加的数据有空间存放。
volatile-ttl:回收过期集合内的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

注意:
1.在实际使用中,如果没有存在回收集合,那么volatile-lru、volatile-random、volatile-ttl三种策略其实跟noevivition策略是相同的。
2.默认情况下allkeys-lru回收策略是最好的选择,当你不确定自己redis真实的应用场景时,使用allkeys-lru策略是最好的选择。
3.使用allkeys-random:如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常(所有元素被访问的概率都差不多)。
4.为键设置过期时间是需要消耗内存的,因此不必为了使用或满足某种回收策略而去设置键过期时间。这种时候使用allkeys-lru算法使最好的选择,也是最高效的。

3.redis回收策略执行过程

①当客户端运行了新命令,添加了新数据导致内存变大;
②redis检查当前内存的使用情况,如果超过了maxmemary设置的最大值,则使用配置文件中的回收策略进行回收;
③新命令继续被执行;
④如果内存一直在最大边界值徘徊,那么我们就需要不断的来回执行回收策略。

4.redis使用近似LRU算法

Redis中的并非对LRU算法进行了完整实现,而是是用了一个近似算法。RedisLRU可以通过调整每次回收时检查的采样数量来动态调整LRU算法的精度。在配置文件中配置 maxmemary-samples 5
Redis为什么不使用真实的LRU算法呢,这是因为真实的LRU算法非常消耗内存。在模拟实验的过程中,我们发现如果使用幂定律的访问模式,则真实的LRU算法和近似的Redis算法几乎没有差别。当然你可以提升采样大小到10,消耗更多的CPU时间以实现更真实的LRU算法,同时查看下是否让你的缓存命中率有差别。
通过CONFIG SET maxmemory-samples 命令在生产环境上设置不同的采样大小是非常简单的。

如需了解更多更详细内容也可关注本人CSDN博客:不吃_花椒

后续redis中将要讲解的内容梳理

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

往期文章

Redis

一、深入理解redis之需要掌握的知识点

二、redis中String和List两种数据类型和应用场景

二、redis中基础数据类型Hash、Set、SortedSet及其应用场景

三、redis数据存储之跳跃表(SKIP LIST)

四、redis持久化之RDB与AOF

五、redis集群进化过程简单梳理

六、redis中AKF问题解决方案

七、redis中CAP问题解决方案-Paxos理论过半通过

八、redis中布式锁的实现及原理

Java集合

一、深入理解-Java集合初篇

二、Jdk1.7和1.8中HashMap数据结构及源码分析

三、JDK1.7和1.8HashMap数据结构及源码分析-续

四、深入理解Java中的HashMap「网易面试快答」

五、深入理解JDK1.7中HashMap哈希冲突解决方案

六、深入理解JDK1.8中HashMap哈希冲突解决方案

七、JDK1.7中HashMap扩容机制

八、JDK1.8中HashMap扩容机制

Java-IO体系

一、C10K问题经典问答

二、java.nio.ByteBuffer用法小结

三、Channel 通道

四、Selector选择器

五、Centos-Linux安装nc

六、windows环境下netcat的安装及使用

七、IDEA的maven项目的netty包的导入(其他jar同)

八、JAVA IO/NIO

九、网络IO原理-创建ServerSocket的过程

十、网络IO原理-彻底弄懂IO

十一、JAVA中ServerSocket调用Linux系统内核

十二、IO进化过程之BIO

十三、Java-IO进化过程之NIO

十四、使用Selector(多路复用器)实现Netty中Reactor单线程模型

十五、使用Selector(多路复用器)实现Netty中Reactor主从模型

十六、Netty入门服务端代码

十七、IO进化过程之EVENT(EPOLL-事件驱动异步模型)

如需了解更多更详细内容也可关注本人CSDN博客:不吃_花椒