Redis内存管理中的LRU算法
在讨论Redis内存管理中的LRU算法之前,先简单说一下LRU算法:
LRU算法:即Least Recently Used,表示最近最少使用页面置换算法。是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU算法就是将最近最久未使用的页面予以淘汰,类似于末尾淘汰制。
比如:
如输入以下序列时:4,7,0,7,1,0,1,2,1,2,6
可以用一个特殊的栈来保存当前正在使用的各个页面的页面号。当一个新的进程访问某页面时,便将该页面号压入栈顶,其他的页面号往栈底移,如果内存不够,则将栈底的页面号移除。这样,栈顶始终是最新被访问的页面的编号,而栈底则是最近最久未访问的页面的页面号。

用java代码实现LRU算法如下:
1 import java.util.ArrayList;
2 import java.util.List;
3
4
5 public class LRU {
6 /**
7 * 内存块的个数
8 */
9 public static final int N = 5;
10 /**
11 * 内存块数组
12 */
13 Object[] array = new Object[N];
14 private int size;
15
16 public LRU() {
17 }
18 /**
19 * 判断内存区是否为空
20 * @return
21 */
22 public boolean isEmpty() {
23 if(size == 0) {
24 return true;
25 } else {
26 return false;
27 }
28 }
29 /**
30 * 判断内存区是否达到最大值
31 * @return
32 */
33 public boolean isOutOfBoundary() {
34 if(size >=N) {
35 return true;
36 } else {
37 return false;
38 }
39 }
40 /**
41 * 查找元素o在数组中的位置
42 * @param o
43 * @return
44 */
45 public int indexOfElement(Object o) {
46 for(int i=0; i<N; i++) {
47 if(o == array[i]) {
48 return i;
49 }
50 }
51 return -1;
52 }
53 /**
54 * 有新的数据o需要申请内存
55 * @param o
56 * @return 移出内存区的数据
57 */
58 public Object push(Object o) {
59 int t = -1;
60 if(!isOutOfBoundary() && indexOfElement(o) == -1){
61 array[size] = o;
62 size ++;
63 } else if(isOutOfBoundary() && indexOfElement(o) == -1){
64 for(int i=0; i<size-1; i++) {
65 array[i] = array[i+1];
66 }
67 array[size-1] = o;
68 } else {
69 t = indexOfElement(o);
70 for(int i=t; i<size-1; i++) {
71 array[i] = array[i+1];
72 }
73 array[size-1] = o;
74 }
75 if( -1 == t) {
76 return null;
77 } else {
78 return array[t];
79 }
80 }
81 /**
82 * 输出内存区中的各数据
83 */
84 public void showMemoryBlock() {
85 for(int i=0; i<size; i++) {
86 System.out.print(array[i] + "\t");
87 }
88 }
89
90 /**
91 * @param args
92 */
93 public static void main(String[] args) {
94 Integer iter[] = {4,7,0,7,1,0,1,2,1,2,6};
95 LRU lru = new LRU();
96 for(int i=0; i<iter.length; i++) {
97 lru.push(iter[i]);
98 lru.showMemoryBlock();
99 System.out.println();
100 }
101 }
102
103 }
LRU算法也可以用于一些实际的应用中,如你要做一个浏览器,或类似于淘宝客户端的应用的就要用到这个原理。大家都知道浏览器在浏览网页的时候会把下载的图片临时保存在本机的一个文件夹里,下次再访问时就会,直接从本机临时文件夹里读取。但保存图片的临时文件夹是有一定容量限制的,如果你浏览的网页太多,就会一些你最不常使用的图像删除掉,只保留最近最久使用的一些图片。这时就可以用到LRU算法 了,这时上面算法里的这个特殊的栈就不是保存页面的序号了,而是每个图片的序号或大小;所以上面这个栈的元素都用Object类来表示,这样的话这个栈就可以保存的对象了。
Redis的数据淘汰机制
Redis提供了5种数据淘汰策略:
- volatile-lru:使用LRU算法进行数据淘汰(淘汰上次使用时间最早的,且使用次数最少的key),只淘汰设定了有效期的key
- allkeys-lru:使用LRU算法进行数据淘汰,所有的key都可以被淘汰
- volatile-random:随机淘汰数据,只淘汰设定了有效期的key
- allkeys-random:随机淘汰数据,所有的key都可以被淘汰
- volatile-ttl:淘汰剩余有效期最短的key
一般来说,推荐使用的策略是volatile-lru,并辨识Redis中保存的数据的重要性。
配置方法: maxmemory-policy volatile-lru #默认是noeviction,即不进行数据淘汰
Redis内存管理中的LRU算法的更多相关文章
- Redis 笔记整理:回收策略与 LRU 算法
Redis的回收策略 noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外) allkeys-lru: 尝试回收最少使用的键(L ...
- 动手实现 LRU 算法,以及 Caffeine 和 Redis 中的缓存淘汰策略
我是风筝,公众号「古时的风筝」. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 那天我在 LeetCode 上刷到一道 LRU 缓存机制的问题, ...
- Redis 内存满了怎么办……
我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 通过在Redis安装目录 ...
- Redis 内存满了怎么办? Redis的内存淘汰策略
https://juejin.im/post/5d674ac2e51d4557ca7fdd70 Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限, ...
- Redis内存回收:LRU算法
Redis技术交流群481804090 Redis:https://github.com/zwjlpeng/Redis_Deep_Read Redis中采用两种算法进行内存回收,引用计数算法以及LRU ...
- redis的LRU算法(一)
最近加班比较累,完全不想写作了.. 刚看到一篇有趣的文章,是redis的作者antirez对redis的LRU算法的回顾.LRU算法是Least Recently Used的意思,将最近最少使用的资源 ...
- Redis的LRU算法
Redis的LRU算法 LRU算法背后的的思想在计算机科学中无处不在,它与程序的"局部性原理"很相似.在生产环境中,虽然有Redis内存使用告警,但是了解一下Redis的缓存使用策 ...
- 【Redis 设置Redis使用LRU算法】
转自:http://ifeve.com/redis-lru/ 本文将介绍Redis在生产环境中使用的Redis的LRU策略,以及自己动手实现的LRU算法(php) 1.设置Redis使用LRU算法 L ...
- LRU工程实现源码(一):Redis 内存淘汰策略
目录 内存淘汰是什么?什么时候内存淘汰 内存淘汰策略 Redis中的LRU淘汰算法 源码剖析 第一步:什么时候开始淘汰key 配置读取 检查时机 getMaxmemoryState 第二步:淘汰哪些k ...
随机推荐
- AVA编程中button按钮,actionlistener和mouseClicked区别
在java的编程中,对于按钮button 有两个事件: 1.actionPerformed 2.mouseClicked 区别: actionPerformed:一般事件,仅侦听鼠标左键的单击事件,右 ...
- 获取Java线程转储的常用方法
1. 线程转储简介 线程转储(Thread Dump)就是JVM中所有线程状态信息的一次快照. 线程转储一般使用文本格式, 可以将其保存到文本文件中, 然后人工查看和分析, 或者使用工具/API自动分 ...
- jackson学习之三:常用API操作
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 使用amoeba实现mysql读写分离
使用amoeba实现mysql读写分离 1.什么是amoeba? Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明. ...
- Go RPC 框架 KiteX 性能优化实践 原创 基础架构团队 字节跳动技术团队 2021-01-18
Go RPC 框架 KiteX 性能优化实践 原创 基础架构团队 字节跳动技术团队 2021-01-18
- RSA2对于所有商户都是单独一对一的,并且只支持开发平台密钥管理和沙箱
蚂蚁金服开发者社区 https://openclub.alipay.com/club/history/read/1495 RSA 和 RSA2 签名算法区别 - 支付宝开放平台 https://ope ...
- 拓扑排序(topo sort)之 最大食物链计数( 洛谷P4017)
前言: 复习复习拓扑排序,自己把自己弄没了/kk 题目传送门 简化题意: 在一个DAG中,求从所有入度为0的点到所有出度为0的点路径的条数 md理解错题意把自己卡了半天,生物学的好的就可以直接理解为求 ...
- [BJOI2016]水晶 做题心得
[BJOI2016]水晶 做题心得 这是一个写了我两小时的傻逼题.写这个题浪费了一堆时间后,我才意识到我码力又不行了.于是整理起了实现技巧,开始练码力. 思路 不难.首先把 \((x,y,z)\) 变 ...
- Vue技术点整理-Vuex
什么是Vuex? 1,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 2,每一个 Vuex ...
- JavaWeb——Ajax与MVC学习总结
Ajax: 什么是Ajax? 为什么使用Ajax? 使用jquery Ajax实现登录 Ajax实例练习: 设计模式 设计模式的定义: 设计模式的作用: MVC设计模式 MVC设计模式的模块组成: M ...