谈谈 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,因为该命令的删除过程是异步的,不会阻塞主线程。

相关推荐
Terra.K2 小时前
ThreadLocal解决一个线程里面跨层传递问题
java·开发语言·后端
泡海椒2 小时前
低代码规则开发:JQuick-Java声明式配置驱动开发落地教程
java·低代码·rxjava
数据库小学妹2 小时前
MySQL长事务复盘:Sleep连接、MDL排队与undo滞留
运维·数据库·mysql
吃饱了得干活2 小时前
Redis 从单机到集群:持久化、主从复制、哨兵与集群完全指南
redis·后端
weixin_440730502 小时前
socket解决多次输入问题-大数据接收问题-模块动态导入
java·开发语言·servlet
用户3126874877203 小时前
ReentrantLock 和 synchronized 到底选哪个?源码级对比与选型
java
计算机毕设定制辅导-无忧学长3 小时前
基于Spring Boot的玄幻小说个性化推荐平台设计与实现
java·vue.js·spring boot·后端·mysql·推荐算法
码路漫漫3 小时前
LRU 真的能解决日志按业务 Key 分文件的落地瓶颈吗?
java·后端
带刺的坐椅3 小时前
不只是 Token 流:Solon AI 4.1 的语义化聊天事件
java·stream·event·solon-ai
半摆烂日常3 小时前
自建WMS和买成品:三年成本对比
大数据·服务器·数据库·python·深度学习·低代码·numpy