Redis-缓存过期淘汰策略
缓存淘汰策略

生产上redis内存设置为多少
设置为最大内存的 3/4
redis 会占用物理机多少内存
默认大小是 0,64 位系统下表示不限制内存大小,32位系统表示 3G
如何设置修改redis内存大小
- config get maxmemory 查看
- 修改方式
- 配置文件 单位是字节

2. <font style="color:#000000;">临时修改,重启后失效 config set maxmemory 104857600</font>
如果redis内存满了会怎么样
redis 将会报错:(error) OOM command not allowed when used memory > ‘maxmemory’
通过命令查看 redis 内存使用情况?
info memory

redis 对于过期 key 的三种不同删除策略
定时删除:创建kv的同时cpu会创建定时器,内存友好,cpu占用高
惰性删除:再次访问这个 key 的时候才会去检查过期时间,内存不友好

定时删除:每隔一段时间去抽样扫描一定(注意不是所有)数量的key是否过期,并可通过限制执行的频率和时长来控制对 cpu 的影响,折中,但可能存留较多过期key,并且需要根据具体情况合适的设置频率和时长
如果执行时间太长,退化成定时。太短则又会出现过期key太多
引出兜底方案,缓存淘汰策略
redis 缓存淘汰策略
8种内存淘汰策略
- noevition: 不操作 默认,看上面oom案例
- allkeys-lru: 对所有 key 使用 lru
- volatile-lru: 对所有设置了过期时间的key lru
- allkeys-random
- volatile-random
- volatile-ttl: 删除快要过期
- allkeys-lfu lfu
- volatile-lfu
修改 -> maxmemory-policy

总结记忆
- 2个维度
- 过期键中筛选 allkeys
- 所有键中筛选 volatile
- 4个方面
- lru 最少使用,最长时间未被使用
- lfu 最不常用,一段时间内使用次数最少
- random 随机
- ttl
用哪种

后两种都对业务有精确的要求,推荐 allkeys-lru
lru算法手写,最近最少使用算法
leetcode 146

哈希链表

基于 LinkedHashMap 的写法

public class LruCacheDemo<K,V> extends LinkedHashMap<K,V> {private int capacity;public LruCacheDemo(int capacity) {super(capacity, 0.75f, false); // true = accessOrder false insertionOrderthis.capacity = capacity;}@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return super.size() > capacity;}public static void main(String[] args) {LruCacheDemo lruCacheDemo = new LruCacheDemo(3);lruCacheDemo.put(1, 1);lruCacheDemo.put(2, 2);lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.keySet());lruCacheDemo.put(4, 4);System.out.println(lruCacheDemo.keySet());lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.keySet());lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.keySet());lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.keySet());lruCacheDemo.put(5, 5);System.out.println(lruCacheDemo.keySet());}
}
/*** true* [1, 2, 3]* [2, 3, 4]* [2, 4, 3]* [2, 4, 3]* [2, 4, 3]* [4, 3, 5]*/
// false,只看插入顺序,不看访问顺序,多次插入3,3的位置不变
/*** false*[1, 2, 3]* [2, 3, 4]* [2, 3, 4]* [2, 3, 4]* [2, 3, 4]* [3, 4, 5]*/
手写的案例
// 手写 LruCache
public class MyLruCacheDemo {// map 负责查找,构建一个虚拟的双向链表,它里面安装的就是一个个Node节点,作为数据载体// 1 构造一个 Node 作为数据载体class Node<K, V> {K key;V value;Node<K, V> prev;Node<K, V> next;public Node() {this.prev = this.next = null;}}//2 构建一个虚拟的双向链表,里面安放的就是我们的Nodeclass DoubleLinkedList<K, V> {Node<K, V> head;Node<K, V> tail;// 2.1 构造方法public DoubleLinkedList() {head = new Node<K, V>();tail = new Node<K, V>();head.next = tail;tail.prev = head;}//2.2 添加到头public void addFirst(Node<K, V> node) {node.next = head.next;node.prev = head;head.next.prev = node;head.next = node;}//2.3 删除节点public void remove(Node<K, V> node) {node.prev.next = node.next;node.next.prev = node.prev;node.prev = null;node.next = null;}//2.4 获得最后一个节点public Node<K, V> getLast() {return tail.prev;}}private int cacheSize;Map<Integer, Node<Integer, Integer>> map;DoubleLinkedList<Integer, Integer> doubleLinkedList;public MyLruCacheDemo(int cacheSize) {this.cacheSize = cacheSize; // 坑位map = new HashMap<>(); // 查找doubleLinkedList = new DoubleLinkedList<>();}public int get(int key) {if (!map.containsKey(key)) {return -1;}Node<Integer, Integer> node = map.get(key);doubleLinkedList.remove(node);doubleLinkedList.addFirst(node);return node.value;}// saveOrUpdatepublic void put(int key, int value) {if (map.containsKey(key)) { // updateNode<Integer, Integer> node = map.get(key);node.value = value;doubleLinkedList.remove(node);doubleLinkedList.addFirst(node);} else {if (map.size() == cacheSize) { // 坑位满了Node<Integer, Integer> last = doubleLinkedList.getLast();map.remove(last.key);doubleLinkedList.remove(last);}// 才是新增Node<Integer, Integer> node = new Node<>();node.key = key;node.value = value;map.put(key, node);doubleLinkedList.addFirst(node);}}public static void main(String[] args) {MyLruCacheDemo lruCacheDemo = new MyLruCacheDemo(3);lruCacheDemo.put(1, 1);lruCacheDemo.put(2, 2);lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.map.keySet());lruCacheDemo.put(4, 4);System.out.println(lruCacheDemo.map.keySet());lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.map.keySet());lruCacheDemo.put(3, 3);System.out.println(lruCacheDemo.map.keySet());lruCacheDemo.put(5, 5);System.out.println(lruCacheDemo.map.keySet());}
}
相关文章:
Redis-缓存过期淘汰策略
缓存淘汰策略 生产上redis内存设置为多少 设置为最大内存的 3/4 redis 会占用物理机多少内存 默认大小是 0,64 位系统下表示不限制内存大小,32位系统表示 3G 如何设置修改redis内存大小 config get maxmemory 查看修改方式 配置文件 单位是字节 2.…...
如何设置LED电子显示屏的屏幕参数?
LED电子显示屏因其高亮度、低能耗和长寿命等优点,在广告、信息显示等领域得到了广泛应用。正确设置屏幕参数对于确保显示屏的最佳性能至关重要。以下是LED电子显示屏设置屏幕参数的步骤: 1. 确定屏幕参数 在开始设置之前,需要了解显示屏的基本…...
Spring Boot Starter Parent介绍
引言 spring-boot-starter-parent 是一个特殊的项目,为基于 Spring Boot 的应用程序提供默认配置和默认依赖。 在本 Spring Boot 教程中,我们将深入了解所有 Spring Boot 项目内部使用的 spring-boot-starter-parent 依赖项。我们将探讨此依赖项所提供…...
【含开题报告+文档+PPT+源码】基于SpringBoot乡村助农益农平台的设计与实现
开题报告 近年来,随着社会经济的快速发展和人民生活水平的提高,人们对优质农产品的需求越来越高。然而,传统的农产品销售管理模式存在一些问题。首先,农产品供应链信息不透明,导致生产者难以了解市场需求和价格变动趋…...
数据中心运维挑战:性能监控的困境与智能化解决方案的探寻
随着数字化进程的加速,数据中心已成为企业信息架构的核心支撑,其运维管理的复杂度和重要性也随之提升。运维团队需应对设备老化、资源分配失衡、性能波动等多重难题,以确保数据中心持续高效运行。 其中,性能监控作为运维管理的关键…...
基于SSM的民宿管理系统【附源码】
基于SSM的民宿管理系统(源码L文说明文档) 目录 4 系统设计 4.1 系统概要设计 4.2 系统功能结构设计 4.3 数据库设计 4.3.1 数据库E-R图设计 4.3.2 数据库表结构设计 5 系统实现 5.1用户信息管理 5.2 房东信息管理…...
显卡 3090 vs v100
1.3090 Date: 2020 AmperePielines/ Cuda cores: 10496 2.V100 Date: 2018 VoltaPielines/ Cuda cores: 5129 3.结构 & Core比较: v100优点: v100功耗小v100较快的双精度(fp64)和混合精度(fp16fp32)pcie版的NVLink与2080ti完全一致 v100缺点: 不支持整数格式计算&…...
怎么在单片机裸机程序中移植EasyLogger?
1、介绍 EasyLogger 是一款超轻量级、高性能的C日志库,非常适合对资源敏感的软件项目。例如:IoT产品、可穿戴设备、智能家居等等。相比log4c、zlog这些知名的C日志库,EasyLogger的功能更加简单,提供给用户的接口更少,但…...
C/C++解析文件名和目录路径
文章目录 主要函数使用注意事项示例程序总结 #include <libgen.h> 是一个 C/C 语言的头文件,主要用于字符串处理,特别是在处理文件路径时。它提供了一些函数来帮助你解析文件名和目录路径。 主要函数 以下是 libgen.h 中一些常见的函数ÿ…...
Git 基本命令行操作
Git是一个开源的分布式版本控制系统,用于管理源代码和文档的版本。以下是Git的基本命令行操作: 一、配置 安装完成后,需要配置Git的用户名和邮箱,以便在提交记录时记录操作者的信息。 配置全局用户名:git config --g…...
【Rust练习】17.泛型
练习题来自:https://practice-zh.course.rs/generics-traits/generics.html 函数 1 // 填空 struct A; // 具体的类型 A. struct S(A); // 具体的类型 S. struct SGen<T>(T); // 泛型 SGen.fn reg_fn(_s: S) {}fn gen_spec_t(_s: SGen<A&…...
java脚手架系列4--测试用例、拦截器
异常处理、拦截器、数据库连接 1 测试用例 单元测试是一个老生常谈的问题,无论是后端对自己的代码质量把的第一道关也好,也是对测试减缓压力。这里就不过多讲述测试用例的重要性,但是有2个框架我们必须了解一下。 1.1 JUnit和mockito 我们…...
论文推荐 |【Agent】自动化Agent设计系统
论文标题: Automated Design of Agentic Systems 论文地址: https://arxiv.org/abs/2408.08435 GitHub地址: https://github.com/ShengranHu/ADAS 自动化代理设计在性能和通用性方面显著超越了手动方法。 • 引入了自动化代理系统设计&am…...
Linux操作系统提供了五种主要的IO(输入/输出)模型
Linux操作系统提供了五种主要的IO(输入/输出)模型,这些模型旨在优化应用程序对输入输出操作的管理和处理。以下是关于这五种IO模型的详细介绍。 一、阻塞IO(Blocking IO) 阻塞IO是最常见、最传统的IO模型。在这种模型…...
基于深度学习的花卉识别系统
简介: 基于Python的花卉识别分类系统利用深度学习和计算机视觉技术,能够准确识别和分类各种花卉,如玫瑰、郁金香和向日葵等。这种系统不仅有助于植物学研究和园艺管理,还在生态保护、智能农业和市场销售等领域展现广泛应用前景。随…...
【斯坦福CS144】Lab0
一、实验目的 1.初步了解计算机网络,准备实验所需的材料和环境; 2.掌握基础实验方法; 3.动手实现网络功能。 二、实验内容 1.下载实验所需的资料,安装虚拟机,配置环境; 2.获取一个网页; …...
关于Mybatis中,IPage<PO>转换成IPage<VO>的问题
以下是一个比较常见通用的一个查询并且为单表查询,在开发初期,或者项目不是很复杂的时候,或者一开始项目框架就规划好的情况下,通常我们都会封装。 在我们的项目中,这部分代码其实是自动生成的,足以满足大…...
使用idea和vecode创建vue项目并启动(超详细)
一、idea创建vue项目 创建项目之前先下载好插件 新建项目找到vue生成器 写好名称,找到自己需要存放的地址,node解释器安装方式可以看我上一个博客,vueCLI是选择vue的版本,我们可以使用idea自带的vue版本默认是vue3,创…...
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
今天想通过和大家分享如何删除字符串最后一个字符的N种实现方法,来回顾一些基础知识点。 01第一类、字符串方式 这类方法是通过string类型自身方法直接实现。 1、Substring方法 相信大多数人第一个想到的可能就是这个方法。Substring方法是字符串内置方法&#…...
成都睿明智科技有限公司怎么样靠谱吗?
随着短视频与直播的深度融合,抖音电商凭借其强大的流量入口、精准的算法推荐以及便捷的购物体验,迅速崛起。对于传统企业和新兴品牌而言,这无疑是一个不可多得的机遇。然而,如何在这片红海中脱颖而出,就需要借助专业的…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
