redis 突然大量逐出导致读写请求block

redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请求,导致 redis 短时间不可用;

redis 中的LRU是如何实现的?

逐出qps突增非常大的原因:一次需要逐出释放太多的空间会导致阻塞;具体的原因是 mem_tofree 的计算逻辑有问题;
mem_tofree 统计的是:实际已分配的内存总量 – AOF 缓冲区相关的内存;
如果这时候有rehash,会临时分配一个桶来做rehash,这部分内存未排除,所以在rehash阶段,算出来的mem_tofree 就会很大,造成一个时刻需要逐出大量的key,逐出的loop是阻塞的,这个阶段会block redis的请求;

逐出qps的计算:

freeMemoryIfNeeded(...)
    // 计算出 Redis 目前占用的内存总数,但有两个方面的内存不会计算在内:
    // 1)从服务器的输出缓冲区的内存
    // 2)AOF 缓冲区的内存
    // 3)AOF 重写缓冲区中的内存
    mem_used = zmalloc_used_memory();
    if (slaves) {
        listIter li;
        listNode *ln;

        listRewind(server.slaves,&li);
        while((ln = listNext(&li))) {
            redisClient *slave = listNodeValue(ln);
            unsigned long obuf_bytes = getClientOutputBufferMemoryUsage(slave);
            if (obuf_bytes > mem_used)
                mem_used = 0;
            else
                mem_used -= obuf_bytes;
        }
    }
    if (server.aof_state != REDIS_AOF_OFF) {
        mem_used -= sdslen(server.aof_buf);
        mem_used -= aofRewriteBufferSize();
    }
    // 计算需要释放多少字节的内存
    mem_tofree = mem_used - server.maxmemory;
    propagateExpire(db,keyobj);
    // 计算删除键所释放的内存数量
    delta = (long long) zmalloc_used_memory();
    dbDelete(db,keyobj);
    delta -= (long long) zmalloc_used_memory();
    mem_freed += delta;
    // 对淘汰键的计数器增一
    server.stat_evictedkeys++;

解决方案

github上 @Rosanta 给出的解决方案:释放内存的循环逻辑中最多执行一定次数,达到阈值了就不再逐出,到下个请求来时再释放一点空间;这个方案的好处是不会 block 整个进程,正常的业务读写请求无影响;潜在问题是可能单次写入的数据比释放的空间还大,导致总的内存是一直上升,而不是下降;

ref

Original: https://www.cnblogs.com/me115/p/8516838.html
Author: 大CC
Title: redis 突然大量逐出导致读写请求block

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529110/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • LDD3第三章学习笔记

    思维导图 需求 实现一个设备/dev/scull,这个设备能用dd, cp, cat和Shell的IO重定向功能操作。 设备号 Linux用主次两个设备号去唯一的表示一个设备。其中…

    Linux 2023年6月7日
    0105
  • redis cli命令

    redis安装后,在src和/usr/local/bin下有几个以redis开头的可执行文件,称为redis shell,这些可执行文件可做很多事情。 可执行文件 作用 redis…

    Linux 2023年5月28日
    078
  • 写shell,运行出错:syntax error near unexpected token `$’dor”

    【解决过程】 1.网上搜了下,参考:linux shell脚本报错:syntax error near unexpected token </a></p> …

    Linux 2023年5月28日
    094
  • Windows 常用 Dos PowerShell 命令

    Dos #^.^ dir /a/s/p PowerShell #批量重命名文件 dir -Recurse *.png | foreach {Rename-Item $_ -NewN…

    Linux 2023年5月28日
    095
  • 进程与fork

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程…

    Linux 2023年6月7日
    0104
  • Forms组件;cookie与session

    Forms组件 需求 如果需要编写一个校验用户名和密码是否合法的功能,那么 前端需要自己编写获取用户数据的各种标签 前端需要自己想方设法的展示错误的提示信息 后端需要自己想方设法的…

    Linux 2023年6月7日
    089
  • tp5,把耗时操作转为队列,queue + redis + supervisor消息推送(队列的执行异步不异步不知道,workman,swoole可以异步)

    添加队列 /** * 发送一个推送 * @param mixed client_id 设备号(字符串/数组) 1 * @param int group 分组(如:1=用户端2=骑手…

    Linux 2023年5月28日
    086
  • gcc/g++与动静库以及gdb

    gcc/g++ 程序转换为二进制 总共需要经过4个大步骤:1.预处理,2.编译,3.汇编,4.链接。 想要更深刻的了解它,可以通过Linux去深刻的了解他们。 先创建.C文件 并且…

    Linux 2023年6月13日
    091
  • Django中信号的使用

    信号种类及用法 Django中提供了”信号调度”,用于在框架执行操作时解耦. 一些动作发生的时候,系统会根据信号定义的函数执行相应的操作 Django中内置…

    Linux 2023年6月14日
    0103
  • Redis从入门到精通:中级篇

    原文链接:http://www.cnblogs.com/xrq730/p/8944539.html,转载请注明出处,谢谢 本文目录 上一篇文章以认识Redis为主,写了Redis系…

    Linux 2023年5月28日
    0100
  • 线程

    一、线程概念的引入 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区…

    Linux 2023年6月14日
    094
  • Linux 文件查看命令

    文件查看命令 1、cat:从第一行开始显示文件内容 使用方式:cat 文件 或 文件路径 例如:cat ifcfg-eth0 或 cat /etc/sysconfig/networ…

    Linux 2023年6月14日
    0105
  • docker安装详细过程

    ubuntu安装docker 我这里用mobaxterm远程连接安装的,如何远程连接在上一篇文章 1、解压tar -zxvf docker-19.03.5.tgz 拷贝文件至bin…

    Linux 2023年6月7日
    0112
  • VMware ESXi 7.0 Update 3c SLIC 2.6 & Unlocker (2022 U3 Refresh)

    提供标准版和 Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科) 定制版镜像 请访问原文链接:VMware ESXi 7.0…

    Linux 2023年5月27日
    096
  • Question05-查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩

    * SELECT a.SID, a.Sname, COUNT(b.CID) 选课总数, SUM(score) 总成绩 FROM Student a , SC b WHERE a.S…

    Linux 2023年6月7日
    0142
  • 域控制器所需的DNS SRV记录没有在DNS中注册的解决方法

    搭建完AD和DNS之后,发现在DNS的正向查找区域没有SRV记录,并且客户端无法加入到AD中,如下 解决方法 删除正向查找区域下的目录 然后选择”正向查找区域&#822…

    Linux 2023年6月14日
    0112
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球