Redis 缓存淘汰机制

导语

Redis是一款高效的K-V数据库,本文主要是对redis中淘汰数据的机制进行一个简单的介绍。在redis中淘汰数据有俩种,一种是过期淘汰,另外一种是基于LRU淘汰算法的数据淘汰。

因为最近项目需要,打算实现一个简单的LRU算法缓存,来用作服务器中缓存最新访问的图片。初期想造轮子的时候感觉还是挺简单的,但是后来细想发现需要考虑的东西还是很多的:

  • 多线程访问
  • 淘汰时机
  • 淘汰机制

不知如何实现,那就看已有轮子是如何造的,所以抽时间看了一下redis中lru。下面就给一个简单的记录。在讲解redis的缓存淘汰之前,先简单提一下redis的事件库—ae。

ae事件库

ae一个非常小巧而又精巧的事件库,它可以处理文件、定时俩种事件。细节和原理就不说了,发现km上有很多介绍的。

ae事件库是在main函数的最后进入,当然在进入ae事件库之前很多初始化工作已经做好。比如读取配置文件、创建定时事件、创建文件事件、初始化系统等。进入事件库即调用aeMain方法之后,就在该方法中一直循环处理各种事件,直到退出。在aeMain方法中可以看到每次循环会首先执行beforeSleep方法,然后调用aeProcessEvents处理定时事件和文件事件。

如下代码:

int main(int argc, char **argv) 
{
   //other code
   //init all kinds of things
    aeSetBeforeSleepProc(server.el,beforeSleep);
    aeMain(server.el);
    aeDeleteEventLoop(server.el);
    return 0;
}

void aeMain(aeEventLoop *eventLoop) 
{ 
    eventLoop->stop = 0; 
    while (!eventLoop->stop) 
    { 
         if (eventLoop->beforesleep != NULL) 
              eventLoop->beforesleep(eventLoop); 
          aeProcessEvents(eventLoop, AE_ALL_EVENTS); 
     } 
}

过期淘汰入口

如上代码所示,每次循环都会调用beforesleep,该方法会执行下面几个操作

  • 触发淘汰过期数据
  • 处理一些和客户端相应的操作
  • 处理aof

淘汰过期数据的触发除此之外还在定时事件中会被触发,定时事件的回调方法serverCron->databasesCron。该方法会被定期调用,主要执行了以下几个操作

  • 触发淘汰过期数据
  • rehash redis数据库
  • resizing数据库

俩个入口都会调用同样一个方法activeExpireCycle(int type),根据type来决定是快速执行还是慢速执行淘汰。在beforesleep方法中是快速的执行淘汰数据,而在databasesCron是慢速执行。快速简单理解就是需要快速执行完还要考虑上次执行的情况,来决定方法是否要直接返回。

LRU淘汰入口

LRU会在每次执行命令的时候进行检查,当发现超过了最大可用内存的时候就会执行释放内存的操作。

processCommond->freeMemoryIfNeeded

下一篇文章《Redis 缓存淘汰机制 -LRU 淘汰》就对过期淘汰数据和基于lru的淘汰机制进行详细的介绍。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JadePeng的技术博客

K8S集群安装

主要参考 https://github.com/opsnull/follow-me-install-kubernetes-cluster

3512
来自专栏大魏分享(微信公众号:david-share)

用Ansible自动供应vmware虚拟机--构建数据中心一体化运维平台第二篇

1.1 简述 一直以来,打开邮箱被ticket糊一脸的事情时有发生。我一直在想,能不能以一种简单的方案(不花老板的钱)来供应(provisioning)虚拟机呢...

6112
来自专栏较真的前端

客户端会话级存储:session Storage与session Cookie的区别

1984
来自专栏Debian社区

Debian 9.3上安装和配置 Observium 监控平台

Observium是一个免费的开源网络管理和监控工具,可用于监控所有的网络设备。 它是用PHP编写的,使用SNMP从连接的设备收集数据并使用Web界面监视它们。...

601
来自专栏程序员的SOD蜜

使用“消息服务框架”(MSF)实现分布式事务的三阶段提交协议(电商创建订单的示例)

1,示例解决方案介绍 在上一篇 《消息服务框架(MSF)应用实例之分布式事务三阶段提交协议的实现》中,我们分析了分布式事务的三阶段提交协议的原理,现在我们来看看...

3089
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (1)

本文内容基本完全来自于Identity Server 4官方文档: https://identityserver4.readthedocs.io/ 官方文档很详...

45910
来自专栏高性能服务器开发

+从零实现一款12306刷票软件1.2

当然,这里需要说明一下的就是,由于全国的火车站点信息文件比较大,我们程序解析起来时间较长,加上火车站编码信息并不是经常变动,所以,我们我们没必要每次都下载这个s...

1082
来自专栏别先生

一脸懵逼学习Nginx及其安装,Tomcat的安装

1:Nginx的相关概念知识:   1.1:反向代理:     反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然...

22510
来自专栏数据之美

使用 django-blog-zinnia 搭建个人博客

django-blog-zinnia 虽然小巧,但是具备了个人博客应用的全部基础功能,且具有很高的拓展性,并且开箱即用。以下是官方列出的一些特性: 评论 站...

2839
来自专栏张戈的专栏

MySQL主从、字典死锁、连接数的Python监控脚本

最近,公司的系统在天津增加了不少异地容灾,其中就有异地双主 MySQL。由于容灾环境一般只会在出现较大的网络故障或故障演习的时候用到,所以,容灾系统的可用性就只...

3827

扫码关注云+社区