Redis内存管理

news2024/11/26 20:24:48

文章目录

    • Redis内存管理
      • 删除策略
      • 淘汰策略
      • LRU算法

Redis内存管理

长期把Redis做缓存用,总有一天Redis内存总会满的。有没有思考过这个问题,Redis内存满了会怎么样?在redis.conf中把Redis内存设置为1个字节,做一个测试:

// 默认单位就是字节
maxmemory 1 

设置完之后重启是为了保证测试的准确性,重启一下Redis,之后在用下面的命令,向Redis中存入键值对,模拟Redis打满的情况:

set k1 v1

执行完后会看到下面的信息:

(error) OOM command not allowed when used memory > 'maxmemory'.

大意:OOM,当前内存大于最大内存时,这个命令不允许被执行。

Redis也会出现OOM,正因如此,我们才要避免这种情况发生。正常情况下,不考虑极端业务,Redis只存放热点数据,Redis不是MySQL数据库,不能什么都往里边写。Redis默认最大内存是全部的内存,我们在实际配置的时候,一般配实际服务器内存的3/4也就足够了。

删除策略

正因为Redis内存打满后报OOM,为了避免出现该情况所以要设置Redis的删除策略。Redis提供了几种删除策略:

  • 定期删除:在后台定期扫描数据库并删除过期数据。这种方法能有效清理过期数据,防止积累大量无用数据,保持内存使用效率。定期删除可能导致性能开销增加,尤其是当数据量很大时。适用于需要清理过期数据的场景,如缓存系统中的临时数据管理。
  • 惰性删除:在客户端访问数据时检查数据是否过期,如果过期则删除。实现简单,对 Redis 性能的影响较小,但可能导致过期数据在被访问前仍然存在,占用内存。适合对数据过期处理要求不严格的应用,尤其是在需要高性能的场景中。
  • 过期时间:策略允许为每个键设置过期时间,数据到达指定时间后会自动删除。精确控制数据的生命周期,可以避免过期数据占用空间。需要管理过期时间,增加了一定的复杂度。适用于需要精确控制数据生命周期的应用,例如缓存数据和会话管理。
  • 主动删除:通过应用逻辑或管理工具手动删除数据,可以根据业务需求自定义删除规则。提供了灵活的删除控制,但需要额外的管理和维护工作,删除操作可能影响 Redis 性能。适合需要手动管理或根据业务逻辑自定义删除规则的场景。

淘汰策略

Redis的内存淘汰策略用于管理当 Redis 数据库达到最大内存限制时,决定如何处理额外的数据。淘汰策略默认,使用noeviction,意思是不再驱逐的,即等着内存被打满。Redis内存淘汰策略在Redis 4.0版本之前有6种策略,4.0增加了两种,主要新增了LFU算法。下图为Redis 6.2.0版本的配置文件:

在这里插入图片描述

策略名称描述优点缺点使用场景
noeviction当达到最大内存限制时,拒绝所有写操作。保持数据完整性,不会自动删除任何数据。一旦达到内存限制,所有新的写操作都会失败。对数据完整性要求高,不希望数据被自动删除的场景。
allkeys-lru在所有键中使用 LRU 算法来淘汰数据。能够有效释放内存空间,保留活跃数据。LRU 算法的性能可能会受到大规模数据集的影响。数据访问模式有明显使用频率差异的场景。
allkeys-random在所有键中随机选择一些进行删除。实现简单,开销较小。删除的数据是随机的,重要数据可能被淘汰。对数据重要性没有明确排序的场景。
volatile-lru只在设置了过期时间的键中使用 LRU 算法进行淘汰。优先淘汰过期数据,能更好地利用内存。对没有设置过期时间的键没有影响。希望优先淘汰过期数据,同时保留重要数据的场景。
volatile-random只在设置了过期时间的键中随机选择一些进行删除。实现简单,不需要计算键的使用频率。删除的数据是随机的,可能会淘汰重要的过期数据。需要删除过期数据,但对具体选择方式要求不高的场景。
volatile-ttl只在设置了过期时间的键中,优先淘汰即将过期的键。能够控制内存使用,同时保留即将过期的数据。可能会导致频繁的内存释放操作,增加 Redis 的管理开销。优先删除即将过期的数据的场景。

Redis中,最常使用的内存淘汰策略通常是allkeys-lruvolatile-lru

allkeys-lru策略在 Redis 达到内存限制时,会在所有存储的键中使用LRU算法进行数据淘汰。无论键是否设置了过期时间,Redis都会选择最近最少使用的键进行删除,释放内存。这种策略适用于需要对所有数据进行管理的场景,例如web缓存和会话管理,可以有效保留访问频率高的数据。

相比之下,volatile-lru策略只对设置了过期时间的键使用 LRU 算法。当Redis达到内存限制时,它会在所有设置了过期时间的键中选择最近最少使用的数据进行淘汰。未设置过期时间的键不会被考虑,这样能够保留重要的未过期数据。这种策略适合有明确过期需求的应用,如缓存系统和用户会话存储,能够有效管理内存而不会影响长期存在的数据。

区别在于处理数据的范围。allkeys-lru适用于管理所有存储的键,考虑所有数据的使用情况;volatile-lru专注于管理设置了过期时间的键,优先淘汰过期数据,保留未过期的键。volatile-lru适合处理需要管理过期数据的场景,而allkeys-lru适用于全面管理所有数据的情况。

LRU算法

LRULeast Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法。

页面置换算法:进程运行时,若其访问的页面不在内存而需将其调入,但内存已无空闲空间时,就需要从内存中调出一页程序或数据,送入磁盘的对换区,其中选择调出页面的算法就称为页面置换算法。

这个算法的思想是,如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。所以当指定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。LRU算法常用于缓存管理,目的是在缓存满时,保留最常使用的数据,同时移除最久未被使用的数据。

使用哈希表与双向链表结合实现LRU算法:

class LRUCache {
    private final int capacity;
    private final HashMap<Integer, Node> cache;
    private final DoublyLinkedList list;

    class Node {
        int key, value;
        Node prev, next;

        Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    class DoublyLinkedList {
        private final Node head, tail;

        DoublyLinkedList() {
            head = new Node(-1, -1);
            tail = new Node(-1, -1);
            head.next = tail;
            tail.prev = head;
        }

        void addFirst(Node node) {
            node.next = head.next;
            node.prev = head;
            head.next.prev = node;
            head.next = node;
        }

        void remove(Node node) {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }

        Node removeLast() {
            if (tail.prev == head) return null;
            Node node = tail.prev;
            remove(node);
            return node;
        }
    }

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.list = new DoublyLinkedList();
    }

    public int get(int key) {
        if (!cache.containsKey(key)) return -1;
        Node node = cache.get(key);
        list.remove(node);
        list.addFirst(node);
        return node.value;
    }

    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            list.remove(node);
            node.value = value;
            list.addFirst(node);
        } else {
            if (cache.size() >= capacity) {
                Node tail = list.removeLast();
                if (tail != null) cache.remove(tail.key);
            }
            Node node = new Node(key, value);
            list.addFirst(node);
            cache.put(key, node);
        }
    }
}

使用哈希表提供快速查找,同时利用链表维护访问顺序。哈希表保证了操作的平均时间复杂度为O(1),适合高效的缓存实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1962193.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【随机链表的复制】python刷题记录

R3-哈希表 参考k神题解 哈希表法&#xff1a; """ # Definition for a Node. class Node:def __init__(self, x: int, next: Node None, random: Node None):self.val int(x)self.next nextself.random random """class Solution:def copy…

“打破常规:评估八股文对工作的真正影响“

“八股文”在实际工作中是助力、阻力还是空谈&#xff1f; 作为现在各类大中小企业面试程序员时的必问内容&#xff0c;“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢&#xff1f;有IT人士不禁发出疑问&#xff1a;程序员面试考什…

基于深度学习的结肠炎严重度诊断

基于深度学习的结肠炎严重度诊断 本文所涉及所有资源均在传知代码平台可获取 文章目录 基于深度学习的结肠炎严重度诊断1.概述1.1 数据集展示1.2 Resnet50介绍1.2.1结构与特点1.2.2关键优势1.2.3总结 2.创新点3.结果可视化展示结果展示4.核心逻辑5.部署及使用方式5.1 环境配置5…

彻底搞清楚SSR同构渲染的首屏

作为.NET技术栈的全干工程师&#xff0c;Blazor、Vue/Nuxt.js和React/Next.js都会接触到。它们&#xff08;准确的说是Blazor、Nuxt和Next&#xff09;&#xff0c;都实现了SSR同构渲染。要了解同构渲染&#xff0c;需要从服务端渲染开始。 传统的服务端渲染 如下图所示&…

开放式耳机什么牌子的好?看这6大品牌就够了

移动互联网时代&#xff0c;听歌、追剧、网课、短视频……这几年全球青年人对于耳机和耳朵的依赖程度&#xff0c;可谓前所未有的提升。但选择一款好的耳机&#xff0c;也不是一件容易的事&#xff0c;入耳式耳机戴久了耳道会疼&#xff0c;还可能引起一系列不必要的炎症&#…

【C语言】C语言期末突击/考研--数据的类型

目录 一、编程环境的搭建 二、数据的类型、数据的输入输出 2.1.数据类型 2.2.常量 2.3.变量 2.4.整型数据 2.4.1.符号常量 2.4.2.整型变量 2.5.浮点型数据 2.5.1.浮点型常量 2.5.2.浮点型变量 2.6.字符型数据 2.6.1字符型常量 2.6.2.字符数据在内存中的存储形式及…

Python 【机器学习】 进阶 之 【实战案例】房价数据中位数分析 | 1/3(含分析过程)

Python 【机器学习】 进阶 之 【实战案例】房价数据中位数分析 | 1/3&#xff08;含分析过程&#xff09; 目录 Python 【机器学习】 进阶 之 【实战案例】房价数据中位数分析 | 1/3&#xff08;含分析过程&#xff09; 一、简单介绍 二、机器学习 1、为什么使用机器学习&a…

react antd upload custom request处理多个文件上传

react antd upload custom request处理多个文件上传的问题 背景&#xff1a;第一次请求需要请求后端返回aws 一个link&#xff0c;再往link push文件&#xff0c;再调用另一个接口告诉后端已经上传成功&#xff0c;拿到返回值。 再把返回值传给业务api... 多文件上传一直是循环…

字体表绘制的理解

下载字体到项目根目录下&#xff0c;我们通过一些在写预览本地字体的网站&#xff0c;简单看一下 通过图片不难看出阴书与原文的对应关系&#xff0c;接下来通过程序去完成这一过程&#xff0c;通过 fonttools 处理 ttf&#xff0c;然后获取字体和文字对应的 xml 文件 下面简单…

分布式SQL查询引擎之ByConity

ByConity 是字节跳动面向现代数据栈的一款开源数仓系统&#xff0c;应用了大量数据库成熟技术&#xff0c;如列存引擎&#xff0c;MPP 执行&#xff0c;智能查询优化&#xff0c;向量化执行&#xff0c;Codegen&#xff0c;indexing&#xff0c;数据压缩&#xff0c;适合用于 O…

线程池和进程池,输出有区别吗?

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor def fn(name):for i in range(1000):print(name,i)if __name__ __main__:with ThreadPoolExecutor(10) as t:for i in range(100):t.submit(fn,namef"线程{i}")with ProcessPoolExecutor(10…

艾体宝干货 | 如何分析关键网络性能指标?持续接收样品试用申请!

网络性能是企业顺利运营的重要基础&#xff0c;而Allegro流量分析仪作为一款强大的网络性能分析工具&#xff0c;为企业提供了深入了解网络运行状况的途径。在本文中&#xff0c;我们将探讨如何利用Allegro 流量分析仪分析关键网络性能指标&#xff0c;以优化网络性能、提高安全…

【综合案例】使用DevEco Studio编写京东登录界面

效果展示 模块拆分 布局容器 顶部 Logo输入框登录区域底部模块区域 知识点 复选框 Checkbox一段文本多个样式&#xff1a;Text 包裹 SpanRow 或 Column 空白区域填充&#xff1a;Blank线性渐变背景&#xff1a; .linearGradient({angle: 135, // 设置颜色渐变起始角度为顺时针…

BUGKU-WEB-文件包含

解题思路 你说啥我就干啥&#xff1a;点击一下试试你会想到PHP伪协议这方面去嘛&#xff0c;你有这方面的知识储备吗&#xff1f;看到?fileXXX.php&#xff0c;那不就是典型的文件包含吗&#xff1f;这里需要用的一个伪协议php://filter:是一种元封装器&#xff0c; 设计用于…

Python学习计划——7.2数据可视化

数据可视化是数据分析的重要组成部分&#xff0c;通过图表和图形将数据直观地展示出来&#xff0c;帮助我们发现数据中的模式和趋势。Python中常用的数据可视化库有matplotlib和seaborn。以下是对这些库的详细讲解及可运行的Python案例。 1. matplotlib 库 matplotlib 是一个…

RuntimeError: TensorRT currently only builds wheels for x86_64 processors

jetson 板卡似乎不能直接使用pip安装tensorrt&#xff0c;可以通过以下方式进行安装 在官网下载对应的tensorrt包 Log in | NVIDIA Developer 在包里面有python库 pip install 对应python版本的库 安装完成之后在终端 import tensorrt 测试是否安装成功

ubuntu 查找文件find

find -name xxx 查找当前路径下名字为xxx的文件 find . -name xxx 查找当前路径下名字为 train_logs的文件 find . -name train_logs 具体说明 【Ubuntu】find命令_ubuntu find命令-CSDN博客 其中&#xff0c;路径 指定要搜索的目录路径&#xff0c;而 表达式 用于指定匹配条…

单片机外围设备-TFTLCD

stm32f103zet6的fsmc接口实现 8080 时序驱动tftlcd显示&#xff0c;驱动IC是ILI9341。 1、什么是FSMC? FSMC (flexible static memory controller)灵活的静态存储控制器&#xff0c;可以驱动SRAM、 NAND FLASH、 NOR FLASH 和 PSRAM 等存储器。 1、1fsmc框图 1、2fsmc外部设…

18万就能买华为智驾车,你当不了韭菜!

文 | AUTO芯球 作者 | 雷慢 万万没想到啊&#xff0c; 把智能驾驶汽车价格打到最低的&#xff0c; 居然是智驾实力最强的华为&#xff0c; 这你敢信吗 就现在&#xff0c;17.99万就能买华为智驾的车了&#xff0c; 它就是长安和华为合作的首个车型&#xff0c; 深蓝S07…

Python酷库之旅-第三方库Pandas(055)

目录 一、用法精讲 206、pandas.Series.reset_index方法 206-1、语法 206-2、参数 206-3、功能 206-4、返回值 206-5、说明 206-6、用法 206-6-1、数据准备 206-6-2、代码示例 206-6-3、结果输出 207、pandas.Series.sample方法 207-1、语法 207-2、参数 207-3、…