redis的LRU策略理解
首先看下serverCron中,服务器每次循环执行的时候,都会刷新server.lrulock。
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
...
server.lruclock = getLRUClock();
...
使用的方法是getLRUClock,LRU_CLOCK_RESOLUTION代表LRU算法的精度,即一个LRU的单位是多长时间。LRU_CLOCK_MAX代表逻辑时钟的最大位数,类似现实中的表盘,划分了最大的刻度,一个刻度是一个LRU大小。所以整个方法表示的含义为:当前时间是LRU的单位的多少倍,即已经过了多少个LRU,然后对最大刻度LRU_CLOCK_MAX取模。
unsigned int getLRUClock(void) {
return (mstime()/LRU_CLOCK_RESOLUTION) & LRU_CLOCK_MAX;
}
了解以上概念后,再看到创建object对象的时候,会给其lru属性赋值,下次被访问时也会更新。
robj *createObject(int type, void *ptr) {
robj *o = zmalloc(sizeof(*o));
o->type = type;
o->encoding = OBJ_ENCODING_RAW;
o->ptr = ptr;
o->refcount = ; /* Set the LRU to the current lruclock (minutes resolution). */
o->lru = LRU_CLOCK();
return o;
}
/* Low level key lookup API, not actually called directly from commands
* implementations that should instead rely on lookupKeyRead(),
* lookupKeyWrite() and lookupKeyReadWithFlags(). */
robj *lookupKey(redisDb *db, robj *key, int flags) {
dictEntry *de = dictFind(db->dict,key->ptr);
if (de) {
robj *val = dictGetVal(de); /* Update the access time for the ageing algorithm.
* Don't do it if we have a saving child, as this will trigger
* a copy on write madness. */
if (server.rdb_child_pid == - &&
server.aof_child_pid == - &&
!(flags & LOOKUP_NOTOUCH))
{
val->lru = LRU_CLOCK();
}
return val;
} else {
return NULL;
}
}
使用的方法是LRU_CLOCK,server.hz代表服务器刷新的频率,意思是如果服务器的时间更新精度值比LRU的精度值要小(精度值表示一次刷新的间隔时间,越小精度越高),说明服务器的精度更高,直接用服务器的时间。举例如果服务器精度是10ms, LRU精度是100ms,则在100ms内服务器进行10次刷新,得到的server.lrulock都是一样,既然如此,不必调用getLRUCLOCK()函数增加额外的开销。
/* Macro used to obtain the current LRU clock.
* If the current resolution is lower than the frequency we refresh the
* LRU clock (as it should be in production servers) we return the
* precomputed value, otherwise we need to resort to a system call. */
#define LRU_CLOCK() ((1000/server.hz <= LRU_CLOCK_RESOLUTION) ? server.lruclock : getLRUClock())
那么obj的lru值是如何使用的呢,判断一个key是否需要过期淘汰时,先计算其最近没有使用的时间,方法如下:获取当前时钟,如果obj的lru小于当前时钟,则获取obj到当前时钟间隔了多少个LRU单位时间,再乘以LRU_CLOCK_RESOLUTION即得到真实毫秒数。
/* Given an object returns the min number of milliseconds the object was never
* requested, using an approximated LRU algorithm. */
unsigned long long estimateObjectIdleTime(robj *o) {
unsigned long long lruclock = LRU_CLOCK();
if (lruclock >= o->lru) {
return (lruclock - o->lru) * LRU_CLOCK_RESOLUTION;
} else {
return (lruclock + (LRU_CLOCK_MAX - o->lru)) *
LRU_CLOCK_RESOLUTION;
}
}
redis的LRU策略理解的更多相关文章
- 设置Redis的LRU策略
概念 LRU(Least Recently Used)最近最少使用算法是众多置换算法中的一种. maxmemory Redis中有一个maxmemory概念,主要是为了将使用的内存限定在一个固定的大小 ...
- Redis的LRU算法
Redis的LRU算法 LRU算法背后的的思想在计算机科学中无处不在,它与程序的"局部性原理"很相似.在生产环境中,虽然有Redis内存使用告警,但是了解一下Redis的缓存使用策 ...
- 【Redis 设置Redis使用LRU算法】
转自:http://ifeve.com/redis-lru/ 本文将介绍Redis在生产环境中使用的Redis的LRU策略,以及自己动手实现的LRU算法(php) 1.设置Redis使用LRU算法 L ...
- 【redis前传】自己手写一个LRU策略 | redis淘汰策略
title: 自己手写一个LRU策略 date: 2021-06-18 12:00:30 tags: - [redis] - [lru] categories: - [redis] permalink ...
- LRU工程实现源码(一):Redis 内存淘汰策略
目录 内存淘汰是什么?什么时候内存淘汰 内存淘汰策略 Redis中的LRU淘汰算法 源码剖析 第一步:什么时候开始淘汰key 配置读取 检查时机 getMaxmemoryState 第二步:淘汰哪些k ...
- 搞定redis面试--Redis的过期策略?手写一个LRU?
1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ...
- 4.redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?
作者:中华石杉 面试题 redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现? 面试官心理分析 如果你连这个问题都不知道,上来就懵了,回答不出来,那线上你写代码的时候,想当 ...
- redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现?
redis的过期策略都有哪些? 设置过期时间: set key 的时候,使用expire time,就是过期时间.指定这个key比如说只能存活一个小时?10分钟?指定缓存到期就会失效. redis的过 ...
- Redis学习笔记2-使用 Redis 作为 LRU 缓存
当 Redis 作为缓存使用时,当你添加新的数据时,有时候很方便使 Redis 自动回收老的数据.LRU 实际上是被唯一支持的数据移除方法.Redis 的 maxmemory 指令,用于限制内存使用到 ...
随机推荐
- 基于Chromium的浏览器已上线通用“显示密码”按钮
基于Chromium的Edge在日前发布的Canary通道版本中,对用户界面进行了优化调整从而让InPrivate窗口变得更加简洁.在今天获得的版本更新中,微软继续带来了隐私相关的新内容--实现通用的 ...
- 小黄车ofo法人被限制出境,它究竟还能撑多久?
因为季节的原因,现在正是骑车的好时候,而且北京也开通了一条自行车的专用路.但就是在这么好的时候,我们发现,路边的小黄车却越来越少了,而且它的麻烦还不断! ofo法人被限制出境 6月12日消息,据上海市 ...
- 504错误解决办法 让你的浏览器强制在后端服务器执行而不用通过前端CDN服务器
因为后端执行时间过长,前端不等待,导致提示504错误的解决办法 504 错误是因为你的CDN服务器设置的延时有限, 超时导致的504 是前端不等待中止,是前端不行,后端应该正常 502 错误是后端 ...
- Vue多页面 按钮级别权限控制 directive指令控制
利用driective 构建自己的指令,实现按钮级别权限 项目结构如下: 修改router.js { path: 'schools', name: '列表', component: () => ...
- Mongodb中的js语法
定义一个变量 > var len = 10; For循环 这里的db和data都可以作为对象 save是方法 接收一个临时定义的对象 > for(var i = 0; i < len ...
- git最最最最...常用命令
使用git 也有一段时间了,但是一直没有好好的去学下:今天刚好有空,就把自己不足的地方补了一下:废话就不多说了,直接步入正题: 1:git 如何提交代码 以及 如何拉代码 git clone可以将远程 ...
- Spring 静态代理和动态代理
现在我们来模拟一下,某位学生去考试. 假设他(小明)正常的考试. 运行结果: 结果: 突然某一天,他睡过头了,来不急去考试,所有他打算叫另一个人(Cheater)去代替他考试. 运行结果 ...
- LightOJ-1104-birthday Paradox(概率)
链接: https://vjudge.net/problem/LightOJ-1104 题意: Sometimes some mathematical results are hard to beli ...
- python生成二维码图片
依赖Pillow库. import qrcode # 简单用法 img = qrcode.make('Hello World!') img.save('qr_code.png') # 高级用法 qr ...
- Python CGI编程Ⅳ
使用POST方法传递数据 使用POST方法向服务器传递数据是更安全可靠的,像一些敏感信息如用户密码等需要使用POST传输数据. 以下同样是hello_get.py ,它也可以处理浏览器提交的POST表 ...