• 谈谈 Redis 大 Key 会有什么影响?


    谈谈 Redis 大 Key 对持久化有什么影响?

    AOF 重写和生成 RDB 快照的影响
    AOF 重写机制和 RDB 快照(bgsave 命令)的过程,都会分别通过 fork() 函数创建一个子进程来处理任务。

    在通过 fork() 函数创建子进程的时候,虽然不会复制父进程的物理内存,但是内核会把父进程的页表复制一份给子进程,如果页表很大,那么这个复制过程是会很耗时的,那么在执行 fork 函数的时候就会发生阻塞现象。

    如果创建完子进程后,父进程对共享内存中的大 Key 进行了修改,那么内核就会发生写时复制,会把物理内存复制一份,由于大 Key 占用的物理内存是比较大的,那么在复制物理内存这一过程中,也是比较耗时的,于是父进程(主线程)就会发生阻塞。

    所以,有两个阶段会导致阻塞父进程:
    ● 创建子进程的途中,由于要复制父进程的页表等数据结构,阻塞的时间跟页表的大小有关,页表越大,阻塞的时间也越长;
    ● 创建完子进程后,如果子进程或者父进程修改了共享数据,就会发生写时复制,这期间会拷贝物理内存,如果内存越大,自然阻塞的时间也越长;

    大 key 除了会影响持久化之外,还会有以下的影响。

    ● 客户端超时阻塞。由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
    ● 引发网络阻塞。每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
    ● 阻塞工作线程。如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
    ● 内存分布不均。集群模型在 slot 分片均匀情况下,会出现数据和查询倾斜情况,部分有大 key 的 Redis 节点占用内存多,QPS 也会比较大。

    如何避免大 Key 呢?

    最好在设计阶段,就把大 key 拆分成一个一个小 key。或者,定时检查 Redis 是否存在大 key ,如果该大 key 是可以删除的,不要使用 DEL 命令删除,因为该命令删除过程会阻塞主线程,而是用 unlink 命令(Redis 4.0+)删除大 key,因为该命令的删除过程是异步的,不会阻塞主线程。

  • 相关阅读:
    Java泛型中的问号是什么意思
    多线程系列(十三) -一文带你搞懂阻塞队列
    将labelImg生成的指定xml标签中某一类的检测框复制给其他图片的xml
    android EventBus
    Redis02:企业架构介绍以及redis介绍
    MySQL数据库必会的增删查改操作(CRUD)
    超全整理,性能测试——数据库索引问题定位+分析(详细)
    中英文说明书丨CalBioreagents艾美捷肠病毒单克隆抗体
    kml或kmz文件用什么软件打开
    云备份客户端——数据管理模块
  • 原文地址:https://blog.csdn.net/Sherlook_Holmes/article/details/133870378