Redis-缓存过期淘汰策略

缓存淘汰策略

生产上redis内存设置为多少

设置为最大内存的 3/4

redis 会占用物理机多少内存

默认大小是 0,64 位系统下表示不限制内存大小,32位系统表示 3G

如何设置修改redis内存大小

  1. config get maxmemory 查看
  2. 修改方式
    1. 配置文件 单位是字节

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

总结记忆

  1. 2个维度
    1. 过期键中筛选 allkeys
    2. 所有键中筛选 volatile
  2. 4个方面
    1. lru 最少使用,最长时间未被使用
    2. lfu 最不常用,一段时间内使用次数最少
    3. random 随机
    4. 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());}
}

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

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

相关文章

深入Postman- 自动化篇

前言 在前两篇博文《Postman使用 - 基础篇》《玩转Postman:进阶篇》中,我们介绍了 Postman 作为一款专业接口测试工具在接口测试中的主要用法以及它强大的变量、脚本功能,给测试工作人员完成接口的手工测试带来了极大的便利。其实在自动化测试上,Postman 也能进行良好的支…

校车购票微信小程序的设计与实现(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…

软考《信息系统运行管理员》- 4.1信息系统软件运维概述

4.1信息系统软件运维概述 文章目录 4.1信息系统软件运维概述信息系统软件运维的概念信息系统软件的可维护性及维护类型对软件可维护性的度量可以从以下几个方面进行&#xff1a;软件维护分类&#xff1a; 信息系统软件运维的体系1.**需求驱动**2.**运维流程**3.**运维过程**4.*…

斯坦福 CS229 I 机器学习 I 构建大型语言模型 (LLMs)

1. Pretraining -> GPT3 1.1. Task & loss 1.1.1. 训练 LLMs 时的关键点 对于 LLMs 的训练来说&#xff0c;Architecture&#xff08;架构&#xff09;、Training algorithm/loss&#xff08;训练算法/损失函数&#xff09;、Data&#xff08;数据&#xff09;、Evalu…

两种方式创建Vue项目

文章目录 引言利用Vue命令创建Vue项目准备工作安装Vue CLI创建Vue项目方法一&#xff1a;使用vue init命令方法二&#xff1a;使用vue create命令启动Vue项目 利用Vite工具创建Vue项目概述利用Vite创建项目启动项目 结语 引言 大家好&#xff0c;今天我将向大家展示如何使用不…

【layui】多文件上传组件实现

插件预览效果&#xff1a; 需要引入layui的脚本文件layui.js和样式文件layui.css html代码&#xff1a; <div class"layui-input-block"><div class"layui-upload-list"><table class"layui-table"><colgroup><col…

vue3中如何更改当前类的文件名称

首先&#xff0c;使用script指定文件名称 <template><div class"person"><h2>姓名&#xff1a;{{ name }}</h2><h2>年龄&#xff1a;{{ age }}</h2><button click"showTel">查看联系方式</button><bu…

VS2017 编译 SQLite3 动态库

首先官方下载源码: Tags sqlite/sqlite (github.com) 1.安装 VS2017 community edition 2.打开VS2017命令行工具 3.安装TCL 开发库,推荐 TCL 9.0 先下载源码: Tcl/Tk 9.0 使用vs2017编译tcl&

【STM32-HAL库】实现微秒、毫秒、纳秒延时。(STM32F4系列)(附带工程下载链接)

使用了本代码后不能使用HAL库自带的HAL_Delay函数 使用了本代码后不能使用HAL库自带的HAL_Delay函数 使用了本代码后不能使用HAL库自带的HAL_Delay函数 一、新建工程 可以参考我的新建工程系列教程 stm32-HAL库cubeMX新建工程教程&#xff08;以F103C8T6为例&#xff09;ht…

基于IDEA+SpringBoot+Vue+Uniapp的投票评选小程序系统的详细设计和实现

2. 详细视频演示 文章底部名片&#xff0c;联系我获取更详细的演示视频 3. 论文参考 4. 项目运行截图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框…

Flink 批作业如何在 Master 节点出错重启后恢复执行进度?

摘要&#xff1a;本文撰写自阿里云研发工程师李俊睿&#xff08;昕程&#xff09;&#xff0c;主要介绍 Flink 1.20 版本中引入了批作业在 JM failover 后的进度恢复功能。主要分为以下四个内容&#xff1a; 背景解决思路使用效果如何启用 一、背景 在 Flink 1.20 版本之前&am…

extern “C“ 的作用、C++ 和 C 编译的不同、C++ 编译过程的五个主要阶段

在 C 中&#xff0c;如果需要从 C 语言导入函数或与 C 代码交互&#xff0c;需要使用 extern "C" 关键字。这是因为 C 和 C 在编译过程中的 符号命名机制&#xff08;即 "名称修饰" 或 "name mangling"&#xff09;不同。 1. extern "C&qu…

2014年国赛高教杯数学建模D题储药柜的设计解题全过程文档及程序

2014年国赛高教杯数学建模 D题 储药柜的设计 储药柜的结构类似于书橱&#xff0c;通常由若干个横向隔板和竖向隔板将储药柜分割成若干个储药槽(如图1所示)。为保证药品分拣的准确率&#xff0c;防止发药错误&#xff0c;一个储药槽内只能摆放同一种药品。药品在储药槽中的排列…

【机器学习】金融预测 —— 风险管理与股市预测

我的主页&#xff1a;2的n次方_ 在金融领域&#xff0c;机器学习&#xff08;ML&#xff09;已经成为了不可或缺的工具。金融预测&#xff0c;尤其是风险管理和股市预测&#xff0c;涉及海量数据和复杂模式的分析&#xff0c;而这些正是机器学习擅长处理的领域。通过分析历…

Sentinel最全笔记,详细使用步骤教程清单

一、Sentinel的基本功能 1、流量控制 流量控制在网络传输中是一个常用的概念&#xff0c;它用于调整网络包的发送数据。然而&#xff0c;从系统稳定性角度考虑&#xff0c;在处理请求的速度上&#xff0c;也有非常多的讲究。任意时间到来的请求往往是随机不可控的&#xff0c;…

[单master节点k8s部署]37.微服务(一)springCloud 微服务

微服务架构的一个重要特点是&#xff0c;它与开发中使用的具体编程语言或技术栈无关。每个微服务都可以使用最适合其功能需求的语言或技术来实现。例如&#xff0c;一个微服务可以用Java编写&#xff0c;另一个微服务可以用Python、Go、Node.js等编写。微服务架构允许这种灵活性…

数据结构-C语言顺序栈功能实现

栈 栈&#xff1a;类似于一个容器&#xff0c;如我们生活中的箱子&#xff0c;我们向箱子里放东西&#xff0c;那么最先放的东西是最后才能拿出来的 代码实现 #include <stdio.h> #include <stdlib.h>#define MAX_SIZE 100typedef struct {int* base; // 栈底指针…

通过PyTorch 手写数字识别 入门神经网络 详细讲解

通过PyTorch 手写数字识别 入门神经网络 数据集 MNIST数据集中有手写数字图片7万张&#xff0c;划分训练集6万张&#xff0c;划分测试集1万张。 每张图片都会有一张标签&#xff0c;也就是代表着图片的真实值&#xff08;真实含义&#xff09;。 概念 计算机是如何读取图片的…

多态常见面试问题

1、什么是多态&#xff1f; 多态&#xff08;Polymorphism&#xff09;是面向对象编程中的一个重要概念&#xff0c;它允许同一个接口表现出不同的行为。在C中&#xff0c;多态性主要通过虚函数来实现&#xff0c;分为编译时多态&#xff08;静态多态&#xff09;和运行时多态…

【Spring AI】Java实现类似langchain的第三方函数调用_原理与详细示例

Spring AI 介绍 &#xff1a;简化Java AI开发的统一接口解决方案 在过去&#xff0c;使用Java开发AI应用时面临的主要困境是没有统一且标准的封装库&#xff0c;导致开发者需要针对不同的AI服务提供商分别学习和对接各自的API&#xff0c;这增加了开发难度与迁移成本。而Sprin…