redis缓存满了的话会发生什么?

线上问题

未及时加监控,导致线上redis被逐出,业务有损

示例:
一个key临时存储在redis等缓存中,如果该key在一段时间内有很大作用
比如一次业务请求,上游服务写入一个value,时长1小时,下游服务需要在1小时内读取它,并完成核心逻辑
如果被逐出后,导致下游拿不到数据,使得此次请求带来也业务问题

解决方法

redis 80%容量时添加监控,及时告警,及时进行业务处理。

学习文档

https://juejin.cn/post/6921884079830859789
在这里插入图片描述

影响

内存数据库,当其使用的内存超过物理内存限制后,内存和磁盘产生频繁的数据交换
导致Redis性能急剧下降

策略

通过配置参数maxmemoey来限制使用的内存大小。
当实际使用内存超过maxmemoey后,Redis提供了如下几种可选策略。

noeviction:(不驱逐,eviction表示驱逐)写请求返回错误
volatile-lru:使用lru算法删除设置了过期时间的键值对
volatile-lfu:使用lfu算法删除设置了过期时间的键值对
volatile-random:在设置了过期时间的键值对中随机进行删除
volatile-ttl:根据过期时间的先后进行删除,越早过期的越先被删除

allkeys-lru:在所有键值对中,使用lru算法进行删除
allkeys-lfu:在所有键值对中,使用lfu算法进行删除
allkeys-random:所有键值对中随机删除

附录

LRU - Least Recently Used

最近最少使用
最近访问的数据,后续很大概率还会被访问到
长时间未被访问的数据,应该被淘汰

LRU算法中数据会被放到一个链表中
链表的头节点为最近被访问的数据
链表的尾节点为长时间没有被访问的数据

LRU算法的核心实现是哈希表+双向链表
链表用来维护访问元素的顺序,哈希表可以在O(1)时间复杂度下进行元素访问

为什么是双向链表呢?
删除元素的话,需要获取前继节点

LFU - Least Frequently Used

LRU算法有一个问题,当一个长时间不被访问的key,偶尔被访问一下后,可能会造成一个比该key访问更频繁的key被淘汰。
LRU算法对key的冷热程度判断不准确。

最不经常使用
按照访问频率来判断key的冷热程度,每次删除的是一段时间内访问频率较低的数据,比LRU算法更准确

如何设计?

  1. 需要存储k-v的map:keyToVal

  2. 需要存储某个k的访问频次的map:keyToFreq

  3. 需要存储当前系统最小的访问频次:minFreq

  4. 当缓存满时有数据k2需要插入,需要先O1寻找访问频次最低且插入最早的k1,然后删除它,接着O1更新k2的访问频次
    某个访问频次的k可能不止一个,有多个,如何O1找到这些k,用访问频次-集合的存储:freqTokeys
    如何从找到的集合中O1找到插入最早的k1,用双向链表,表头作为该频次中插入最早的元素。
    最终选择既有O1找到集合的map+O1找到插入最早的k1 -> HashMap<Integer, LinkedHashSet>

    LinkedHashSet类,链表和集合的结合体
    链表不能快速删除元素,但是能保证插入顺序
    集合内部元素无序,但是能快速删除元素(O(lgN))
    LinkedHashSet是一种在迭代其元素时可以返回它们被插入的顺序的set(集合类型)
    也就是说,它可以保证元素的插入与访问顺序。

private HashMap<K, V> keyToVal; // HashMap
private HashMap<K, Integer> keyToFreq; // HashMap
private int minFreq;
private int capacity;
private HashMap<Integer, LinkedHashSet<K>> freqTokeys;
public class LfuCache<K, V> {private HashMap<K, V> keyToVal;private HashMap<K, Integer> keyToFreq;private HashMap<Integer, LinkedHashSet<K>> freqTokeys;private int minFreq;private int capacity;public LfuCache(int capacity) {keyToVal = new HashMap<>();keyToFreq = new HashMap<>();freqTokeys = new HashMap<>();this.capacity = capacity;this.minFreq = 0;}public V get(K key) {V v = keyToVal.get(key);if (v == null) {return null;}// 如果k存在,则增加访问频次increaseFrey(key);return v;}public void put(K key, V value) {// get方法里面会增加频次if (get(key) != null) {// 重新设置值keyToVal.put(key, value);return;}// 超出容量,删除频率最低的key 【逐出策略】if (keyToVal.size() >= capacity) {removeMinFreqKey();}// 能进入到这里说明:最小访问频次一定是1// k-v插入keyToVal.put(key, value);// k-访问频次插入keyToFreq.put(key, 1);// freqTokeys中,key对应的value存在,返回存在的key;不存在,添加key和value// 不存在则创建一个新的LinkedHashSet并插入freqTokeys.putIfAbsent(1, new LinkedHashSet<>());// 访问频次为1的集合中,有序插入当前keyfreqTokeys.get(1).add(key);// 系统最小访问频次一定是1this.minFreq = 1;}// 【逐出策略】// 删除出现频率最低且插入最早的keyprivate void removeMinFreqKey() {// 找到最小访问频次对应的 LinkedHashSet<K> 集合&列表LinkedHashSet<K> keyList = freqTokeys.get(minFreq);// 获取keyList中的第一个元素// iterator()方法返回一个在一系列元素上进行迭代的迭代器// next()方法获取迭代器当前位置的下一个元素K deleteKey = keyList.iterator().next();// 从 keyList 中删除链表第一个节点,如果keyList中只有一个元素,则将整个keyList删除keyList.remove(deleteKey);if (keyList.isEmpty()) {// 这里删除元素后不需要重新设置minFreq,因为put方法执行完会将minFreq设置为1freqTokeys.remove(keyList);}// k-v中逐出keyToVal.remove(deleteKey);// k-访问频次中逐出keyToFreq.remove(deleteKey);}// 增加频率private void increaseFrey(K key) {// 获取当前key的访问频次int freq = keyToFreq.get(key);// 当前key的访问频次+1keyToFreq.put(key, freq + 1);// 当前访问频次中维护的key集合中,删除当前keyfreqTokeys.get(freq).remove(key);// 当前访问频次+1中维护的key集合中,插入当前key(如果LinkedHashSet不存在,则先new一个)freqTokeys.putIfAbsent(freq + 1, new LinkedHashSet<>());freqTokeys.get(freq + 1).add(key);// 当前访问频次中维护的key集合为空,则remove掉该LinkedHashSetif (freqTokeys.get(freq).isEmpty()) {freqTokeys.remove(freq);// remove掉该LinkedHashSet,代表系统中最小的访问频次为 this.minFreq++if (freq == this.minFreq) {this.minFreq++;}}}
}

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

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

相关文章

蓝桥杯刷题5--GCD和LCM

目录 1. GCD 1.1 性质 1.2 代码实现 2. LCM 2.1 代码实现 3. 习题 3.1 等差数列 3.2 Hankson的趣味题 3.3 最大比例 3.4 GCD 1. GCD 整数a和b的最大公约数是能同时整除a和b的最大整数&#xff0c;记为gcd(a, b) 1.1 性质 GCD有关的题目一般会考核GCD的性质。   …

QGridLayout网格布局和QVBoxLayout垂直布局有着非常大的差别

QGridLayout网格布局&#xff1a;1.把这块控件划分成一个个的 单元格 2.把你的控件填充进入 单元格 3.这些有关限制大小的函数接口统统失效 setMaximumWidth&#xff08;&#xff09; setMinimumWidth() setPolicySize()图示&#xff1a;我是用的网格布局&#xff0c;左边放QT…

300分钟吃透分布式缓存-24讲:Redis崩溃后,如何进行数据恢复的?

Redis 持久化是一个将内存数据转储到磁盘的过程。Redis 目前支持 RDB、AOF&#xff0c;以及混合存储三种模式。 RDB Redis 的 RDB 持久化是以快照的方式将内存数据存储到磁盘。在需要进行 RDB 持久化时&#xff0c;Redis 会将内存中的所有数据以二进制的格式落地&#xff0c;每…

项目实战之跨语言调用api——结合语言优点解决实际问题

前情提要 在一个项目开发中需要后端解析并分析数据得出结果报告&#xff0c;一开始用的Java后端&#xff0c;后面一堆Json数据解析的实在头疼&#xff0c;于是捡起老胶水&#xff1a;Python 辅助开发作为后端的核心算法部分服务接口 Java&#xff1a;SpringBoot 结合 RestTemp…

html--彩虹爱心

文章目录 js内容cssreset.min.cssstyle.css html内容 js内容 const colors ["#e03776","#8f3e98","#4687bf","#3bab6f","#f9c25e","#f47274"]; const SVG_NS http://www.w3.org/2000/svg; const SVG_XLINK &q…

数据分析-Pandas数据画箱线图

数据分析-Pandas数据画箱线图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&#xff…

Python快速入门系列-2(Python的安装与环境设置)

第二章&#xff1a;Python的安装与环境设置 2.1 Python的下载与安装2.1.1 访问Python官网2.1.2 安装Python对于Windows用户对于macOS用户对于Linux用户 2.2 集成开发环境&#xff08;IDE&#xff09;的选择与设置2.2.1 PyCharm2.2.2 Visual Studio Code2.2.3 Jupyter Notebook2…

7. 交叉开发环境设置

嵌入式交叉编译工具 ​ 交叉编译工具是为了使在上位机中编译的文件能够在不同平台的目标机中执行&#xff0c;搭建交叉编译环境是嵌入式开发的第一步&#xff0c;也是关键的一步。不同的体系结构、不同的操作系统&#xff0c;甚至是不同版本的内核&#xff0c;都会用到不同的交…

看了很多文章,就这篇说明白了什么是接口测试!

接口&#xff08;API&#xff09;是一个简称&#xff0c;全名叫应用程序编程接口(Application Programming Interface)&#xff0c;是一些预先定义的函数。目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解…

进腾讯工作一个月,我想辞职了......

前几天&#xff0c;我在网上看到一个微博。 一个应届的校招生&#xff0c;目前入职腾讯&#xff0c;工作了一个月。这一个月给他的感受是大量的写测试用例&#xff0c;自己写测试用例的能力熟练了不少&#xff0c;测试技能倒是没有多大的提高&#xff0c;真正需要技术的工作却…

深入理解MySQL中的MVCC(多版本并发控制)

在MySQL中&#xff0c;MVCC是一种用于提供并发控制的技术&#xff0c;它允许数据库系统在事务并发执行的情况下保持数据的一致性&#xff0c;同时提高了数据库的并发性能。MVCC背后的理念是允许每个事务可以看到一个一致性的快照&#xff0c;从而避免了读取操作被写入操作所阻塞…

存储引擎的简介

简介&#xff1a; 1.在mysql存储引擎可以说就是指表的类型&#xff0c;可以称为表处理器&#xff0c;以表的形式存储。 2.他的功能就是接收上层传下来的指令&#xff0c;然后对表中的数据进行提取写入操作。 目的&#xff1a; 为了管理方便&#xff0c;我们把连接管理&#xf…