面试官:说一下Redis中有哪些阻塞点以及如何解决?






面试官:JDK1.8 创建线程池有哪几种方式?

以下正文:

Redis 中的优秀设计有很多,今天我们一起来聊聊群友刷题遇到的:“Redis的异步机制 —— redis有哪些阻塞点以及如何解决?”

前言

说到 Redis,大家自然而然的会想到基于内存、单线程执行等。话说回来,Redis 真的只有单线程吗?这篇文章来说说 Redis 的异步机制。


有哪些影响redis性能的因素

我们从 Redis 内部及外部因素总结一下,主要有:

  1. redis 内部的阻塞式操作
  2. CPU 核和 NUMA 架构的影响
  3. Redis 关键系统配置
  4. Redis 内存碎片
  5. Redis 缓冲区

首先说说 Redis 实例的阻塞点:

  • 客户端:网络 IO,键值对的增删改查操作,数据库操作;
  • 磁盘:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;
  • 主从节点:主库生成、传输 RDB 文件,从库接收 RDB 文件、清空数据库、加载 RDB 文件;
  • 切片集群实例:向其他实例传输哈希槽信息,数据迁移。


客户端的阻塞


因 Redis 使用了 IO 多路复用机制,能避免主线程一直处于等待状态,网络 IO 不是导致 Redis 阻塞的因素。


而键值对的增删改查是主线程的主要工作,复杂度高的操作当然会阻塞Redis了。我们去判断复杂度高不高的标准就是看操作的复杂度是否为O(N),也就是否要全表扫描。比如hgetall, smembers等操作就属于复杂度高的了。


然后还要注意的一个点就是数据的删除。删除本质上来说就是对键值对的内存空间进行释放。在释放内存时,操作系统需要将释放掉的内存块插入一个空闲内存块的链表,以便后续管理和再分配。这个过程会阻塞当前释放内存的应用程序。


如果这个键值对数据很大,比如一个 zset 包含大量元素,就会释放大量的内存。有测试过删除 100 万个元素的集合时,删除时间会达到 2s,要知道 Redis 的响应是毫秒级别的。所以这种 bigkey 的删除也会成为 Redis 的阻塞点。


清空数据库(flushdb、flushall)也涉及到删除和释放所有的键值对,也是 Redis 的阻塞点。


磁盘带来的阻塞


AOF重写和RDB快照,Redis都用了子进程的方式操作,所以不会阻塞主线程。但Redis直接记录AOF日志,若有大量的写操作,并且配置的是同步写回的话,就会阻塞主线程了。


主从节点带来的阻塞


在主从集群中,主库生成 RDB 文件,并传输给从库。主从复制过程的创建和传输 RDB 都是子进程处理的,不会阻塞主线程。但是从库在接收了 RDB 文件后,需要使用 FLUSHDB 命令清空当前数据库,这又是一个阻塞点。而且,在从库清空数据库后,需要将 RDB 文件加载到内存,快慢和 rdb 文件大小相关。加载 RDB 文件又是一个阻塞点。


切片集群的阻塞


片集群的实例在负载均衡或者实例增加删除时,数据迁移是渐进式操作的,所以不会阻塞主线程。

总结一下,Redis 就有 5 个阻塞点:

  • 集合全量查询和聚合操作;
  • bigkey 删除;
  • 清空数据库;
  • AOF 日志同步写;
  • 从库加载 RDB 文件。


异步机制解决阻塞


我们通过异步的方式,去解决可能阻塞的场景。但也不是每个操作都能用异步的方式去解决。如果一个操作能够异步执行,说明客户端不需要马上得到具体值,在Redis中描述为「若一个操作能异步执行,就意味着它不是主线程的关键路径的操作。」


对于第一个阻塞点,因为读操作需要等待数据的返回,所以「第一个阻塞点不能异步执行。」 第二个阻塞点和第三个阻塞点,因为删除不需要返回具体的结果,因此都可以用子线程去异步执行。「第四个阻塞点“AOF日志同步写”,也可启动子线程操作,不用让主线程等待AOF日志的写完成。」 第五个阻塞点 「“从库加载 RDB 文件”,从库要想对客户端提供数据存取服务,就必须把RDB文件加载完成,不能启用子进程。」


异步是如何进行的


Redis 主线程启动后,会使用操作系统提供的 pthread_create 函数创建 3 个子线程,分别由它们负责 AOF 日志写操作、键值对删除以及文件关闭的异步执行。


异步删除lazy-free


lazy-free 机制是 Redis 收到删除指令后,主线程会将这个操作放入队列,然后马上给客户端返回一个完成信息。实际上删除还没执行呢。lazy-free 是 Redis4.0 之后才有的功能,需要手动开启。需要注意的是,即使开启了 lazy-free,如果直接使用 DEL 命令还是会同步删除 key,只有使用 UNLINK 命令才会可能异步删除 key。而且 Redis 在删除一个 key 时,首先会评估删除的时间成本,如果成本小,也不会异步执行,直接用主线程就完成返回了。


小结


本文总结 Redis 有哪些阻塞点,以及这些阻塞点是否可用异步机制去解决。但我们在使用 Redis 时,还是要避免 bigkey 的使用。







END

1.Redis 不再开源??2.Redis大key多key拆分:优化性能,释放潜能!3.4 种策略让 MySQL 和 Redis 数据保持一致4.细说 redis 十种数据类型及底层原理

我是技术程管家,专心做内容,不割韭菜

分享技术成长之路,不忘初心,惠泽他人终身学习,与时俱进,点赞关注不迷路

相关推荐

  • 面试官: 美团外卖的分库分表怎么设计?
  • 22年北京买房子430万,首付190,月供17000,今年房子320万,亏了110,基本这几年白干,压根不敢离职,啥工作都得干。
  • 大模型做时序预测也很强!华人团队激活LLM新能力,超越一众传统模型实现SOTA
  • “梗王”大模型,靠讲笑话登上CVPR | 中山大学
  • 刚刚,图灵奖揭晓!史上首位数学和计算机最高奖“双料王”出现了
  • 中国最fashion的AIGC应用都在这里了 | 中国AIGC产业峰会
  • 评测通知 | NLPCC2024评测任务:大语言模型监管
  • AI Agent 应该更有趣还是更有用?
  • 华盛顿大学撰文反驳微软,我们无法删除大模型关于哈利波特的记忆
  • [开源]一个微前端架构系统,可能是你见过最完善的微前端解决方案
  • 聊聊微服务中的 BFF 架构
  • 还不会免费将PDF转为Word?你可以试试这3种工具!
  • 春天,关于人生发展的 24 条心得
  • 微软前全球副总裁入局AGI:左手效率神器、右手AI开放世界,实测好用!
  • 对话国产“算力黑马”:27亿元大单背后,英博数科周韡韡的AGI探索之路
  • 街边的普通茶室也能赚600万,靠的不只是喝茶
  • 探探各个微前端框架
  • 前端代码规范 - 代码注释
  • 从商品图到海报生成 京东广告AIGC创意技术应用
  • 工科博士毕业去高校还是去研究所?