将redis用作缓存时,如果内存空间用满,就会自动驱逐老的数据。默认情况下,memcached就是这种方式。


LRU是Redis唯一支持的回收算法。

maxmemory配置指令

maxmemory用于指定Redis能使用的最大内存。既可以在redis.conf文件中配置,也可以在运行过程中通过CONFIG SET命令动态修改。

例如,要设置100MB的内存限制,可以在redis.conf文件中这样配置

maxmemory 100mb

# 将maxmemory设置为0,则表示不进行内存限制。当然,对32位系统来说有一个隐性的限制条件:最多3GB内存。
当内存使用达到最大限制时,如果需要存储新数据,根据配置的淘汰策略不同,Redis可能直接返回错误信息,或者删除部分老的数据。

淘汰策略

达到最大内存限制(maxmemory),redis根据maxmemory-policy配置的策略,来决定具体的行为。

  • noeviction:不删除策略。达到最大内存限制时,如果需要更多内存,直接返回错误信息。大多数写命令都会导致占用更多的内存(极少数里外:DEL)
  • allkeys-lru:所有key通用;优先删除最近最少使用的key
  • volatile-lru:只限于设置了expire的部分;优先删除最近最少使用的key
  • allkeys-random:所有key通用;随机删除一部分key
  • volatile-random:只限于设置了expire的部分;随机删除一部分key
  • volatile-ttl:只限于设置了expire的部分;优先删除剩余时间短的key

如果没有设置expire的key,不满足先决条件;那么volatile-lru,volatile-random和volatile-ttl策略的行为,和noeviction(不删除)基本上一致。

需要根据系统的特征,来选择合适的驱逐策略。当然,在运行过程中也可以通过命令动态设置淘汰策略,并通过INFO命令监控缓存的miss和hit,来进行调优

一般来说:

  • 如果分为热数据与冷数据,推荐使用allkeys-lru策略。也就是说,其中一部分key经常被读写。如果不确定具体的业务特征,那么allkeys-lru是一个很好的选择。
  • 如果需要循环读写所有的keys,或者各个key的访问频率差不多,可以使用allkeys-random策略,即读写所有元素的概率该不多。
  • 假如要让redis根据TTL来筛选需要删除的key,请使用volatile-ttl策略。

volatile-lru和volatile-random策略主要应用场景是:既有缓存,又有持久key的实例中。一般来说,这样的场景,应该有两个单独的redis实例。

注意:设置expire会消耗额外的内存,所以使用allkeys-lru策略,可以更高效地利用内存,因为这样可以不再设置过期时间了。

淘汰的内部实现

淘汰过程可以这样理解:

  • 客户端执行一个命令,导致redis中的数据增加,占用更多内存
  • redis检查内存使用量,如果超出maxmemory限制,根据策略清除部分key
  • 继续执行下一条命令,以此类推。

在这个过程中,内存使用量会不断达到limit值,然后超过,然后删除部分key,使用量又下降到limit值之下。

如果某个命令导致大量内存(比如key保存一个很大的set),在一段时间内,可能内存的使用量会明显超过maxmemory限制。

近似LRU算法

Redis使用的并不是完全的LRU算法。自动驱逐key,并不一定是最满足LRU特征那个。而是通过近似LRU算法,抽取少量的key样本,然后删除其中访问时间最古老的那个key

驱逐算法, 从 Redis 3.0 开始得到了巨大的优化, 使用 pool(池子) 来作为候选. 这大大提升了算法效率, 也更接近于真实的LRU算法。

在 Redis 的 LRU 算法中, 可以通过设置样本(sample)的数量来调优算法精度。 通过以下指令配置:

maxmemory-samples 

为什么不使用完全LRU实现? 原因是为了节省内存。但 Redis 的行为和LRU基本上是等价的. 下面是 Redis LRU 与完全LRU算法的一个行为对比图。

测试过程中, 依次从第一个 key 开始访问, 所以最前面的 key 才是最佳的驱逐对象。

从图中可以看到三种类型的点, 构成了三个不同的条带。

  • 浅灰色部分表示被驱逐的对象。
  • 灰色部分表示 “未被驱逐” 的对象。
  • 绿色部分表示后面加入的对象。

在纯粹的LRU算法实现中, 前半部分旧的key被释放了。而 Redis 的 LRU 算法只是将时间较长的 key 较大概率地(probabilistically)释放了。

如你所见, Redis 3.0 中, 5样本的效果比 Redis 2.8 要好很多。 当然, Redis 2.8 也不错,最后访问的key基本上都还留在内存中. 在 Redis 3.0 中使用 10 样本时, 已经非常接近纯粹的LRU算法了。

注意,LRU只是用来预测将来可能会继续访问某个key的一个概率模型. 此外,如果数据访问的情况符合幂律分布(power law), 那么对于大部分的请求来说, LRU都会表现良好。

在模拟中, 我们发现, 如果使用幂律方式访问, 纯粹的LRU和Redis的结果差别非常, 甚至看不出来。

当然也可以将样本数量提高到10, 以额外消耗一些CPU为代价, 使得结果更接近于真实的LRU, 并通过 cache miss 统计信息来判断差异。

设置样本大小很容易, 使用命令 CONFIG SET maxmemory-samples <count> 即可。

原文:https://blog.csdn.net/ligupeng7929/article/details/79603060

redis-淘汰策略的更多相关文章

  1. redis 淘汰策略有哪些?

    noeviction: 不删除策略, 达到最大内存限制时, 如果需要更多内存, 直接返回错误信息. 大多数写命令都会导致占用更多的内存(有极少数会例外, 如 DEL ). allkeys-lru: 所 ...

  2. redis淘汰策略和过期策略

    淘汰策略 https://blog.csdn.net/qq_55961709/article/details/124568269 LRU算法和LFU算法的区别: LRU:最近最少使用,淘汰时间长没有使 ...

  3. 【redis前传】自己手写一个LRU策略 | redis淘汰策略

    title: 自己手写一个LRU策略 date: 2021-06-18 12:00:30 tags: - [redis] - [lru] categories: - [redis] permalink ...

  4. 缓存的有效期和淘汰策略【Redis和其他缓存】【刘新宇】

    缓存有效期与淘汰策略 有效期 TTL (Time to live) 设置有效期的作用: 节省空间 做到数据弱一致性,有效期失效后,可以保证数据的一致性 Redis的过期策略 过期策略通常有以下三种: ...

  5. redis六种内存淘汰策略学习

    当客户端会发起需要更多内存的申请,Redis检查内存使用情况,如果实际使用内存已经超出maxmemory,Redis就会根据用户配置的淘汰策略选出无用的key; 当前Redis3.0版本支持的淘汰策略 ...

  6. Redis的内存回收原理,及内存过期淘汰策略详解

    Redis 内存回收机制Redis 的内存回收主要围绕以下两个方面: 1.Redis 过期策略:删除过期时间的 key 值 2.Redis 淘汰策略:内存使用到达 maxmemory 上限时触发内存淘 ...

  7. Redis++:Redis 内存爆满 之 淘汰策略

    前言: 我们的redis使用的是内存空间来存储数据的,但是内存空间毕竟有限,随着我们存储数据的不断增长,当超过了我们的内存大小时,即在redis中设置的缓存大小(maxmeory 4GB),redis ...

  8. Redis数据过期和淘汰策略详解(转)

    原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...

  9. Redis的过期策略和内存淘汰策略(转)

    Redis的过期策略 我们都知道,Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间.Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理. ...

  10. Redis的过期策略和内存淘汰策略

    Redis的过期策略:通常有三种,Redis中同时使用惰性过期和定期过期两种过期策略组合. 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除.该策略可以立即清除过期的数据 ...

随机推荐

  1. java中I/O类

    总结:输入流/输出流 方法,变量: package com.aini; //流类.输入输出流 import java.io.*; public class rtyeew {// (File file) ...

  2. Struts2中web.xml里面struts-cleanup作用

    struts2.1.3之后的版本均不需要配置该过滤器 参考: struts-cleanup作用 升级到struts-2.3.14.3之后涉及的改动以及ActionContextCleanUp,Stru ...

  3. Mongodb 分片与副本集

    测试搭建192.168.3.110mongos 30000,30001,30002config 40000,40001,40002shard1 50001,50002,50003shard2 5000 ...

  4. java中内部类的讲解

    java中有一个内部类的概念,由于之前一直比较忙,没有单独拿出时间总结一下,今天我就把内部类的相关知识进行一下汇总,如果有不足之处,欢迎批评指正. 1)java内部类的概念.       在一个类的的 ...

  5. 渗透测试框架-Fsociety

    下载项目并赋予权限,打开 ┌─[root@sch01ar]─[/sch01ar] └──╼ #git clone https://github.com/Manisso/fsociety ┌─[root ...

  6. C语言在32位和64位机器下数字数据类型的字节数取决于编译器和平台, 主要由编译器决定。

    C语言中数字数据类型的字节数 C声明 32位机器 64位机器 char 1 1 short int 2 2 int   4 4 //整型在32位和64位下都是4个字节 long int   4 8 l ...

  7. windows服务编写和“以管理员运行”程序的方法

    本文将首先解释如何 创建 一个定期查询可用物理内存并将结果写入某个文本文件的服务.然后指导你完成生成,安装和实现服务的整个过程. 第一步:主函数和全局定义 首先,包含所需的头文件.例子要调用 Win3 ...

  8. 第六章 Java性能调优工具(待续)

    Java性能调优工具 Windows工具 JDK命令行工具 JConsole工具 Visual VM多合一工具 Visual VM对QQL的支持 MAT内存分析工具 MAT对QQL的支持 JProfi ...

  9. JS中,split()用法(将字符串按指定符号分割成数组)

    <!DOCTYPE html> <html> <head> <meta charset="{CHARSET}"> <title ...

  10. python爬虫框架(1)--框架概述

    框架概述 其中比较好用的是 Scrapy 和PySpider.pyspider上手更简单,操作更加简便,因为它增加了 WEB 界面,写爬虫迅速,集成了phantomjs,可以用来抓取js渲染的页面.S ...