当前位置: 首页 > backend >正文

Day18

1. 讲一下IO多路复用?

IO 多路复用是一种在单个线程中同时监听多个文件描述符(fd)是否就绪(可读、可写)的技术。当某个 fd 准备好后再进行实际的 IO 操作,从而避免阻塞等待。

  1. select:底层使用位图(bitmap)结构来表示文件描述符集合,比如一个 fd_set 可以用一个 1024 位的数组来表示 0~1023 的 fd 是否监听。每次系统调用时,用户态将整个位图拷贝到内核态,内核遍历所有 fd,通过轮询判断每个 fd 是否就绪。就绪后修改位图,并将其返回给用户。由于每次都要重新构建 fd_set 并全量拷贝,加上线性扫描O(n),在高并发场景下效率低、性能差。
  2. poll:底层使用数组(或者链表)结构来保存多个 pollfd 结构体,每个结构体包含一个 fd、监听事件和返回时间。调用poll()时,用户态数组被拷贝到内核态,内核遍历这个数组中所有 fd,检查状态是否就绪,然后将结果通过 revents 字段返回给用户。虽然 poll 支持更多 fd,不再受位图限制,但仍然是全量遍历和每次拷贝,导致性能瓶颈依旧存在。
  3. epoll:epoll 在内核中使用两个关键的数据结构:红黑树和就绪链表。当调用epoll_ctl()注册 fd 时,内核将 fd 插入红黑树中管理,时间复杂度为 O(logn)。当某个 fd 上的事件发生时,内核将该 fd 加入就绪链表。调用epoll_wait()时,直接从就绪链表返回事件(事件驱动(触发式),只处理就绪事件),避免全量扫描与频繁拷贝,效率极高。此外,内核和用户空间通过 mmap 实现共享内存结构,避免频繁内存复制。

2. epoll 边缘触发和水平触发

  1. 水平触发(LT):水平触发是 epoll 的默认工作模式,表示只要某个 fd 的事件条件满足(比如缓冲区有数据未读),每次调用epoll_wait时都会返回这个 fd。它实现简单,即使一次没有读完数据,系统仍会持续提醒你处理,但也因此可能重复触发、性能较低,适用于普通网络应用开发。
  2. 边缘触发(ET):边缘触发是 epoll 的高效模式,仅在 fd 状态发生变化时(例如从无数据变为有数据)才触发一次事件通知;这要求程序必须使用非阻塞 IO,并在事件发生时一次性读/写干净所有数据,否则可能收不到后续通知。虽然实现复杂,但能显著减少系统调用次数,提高高并发处理能力,常用于高性能服务器如 Nginx。

3. redis怎么实现IO多路复用?

Redis 采用 I/O 多路复用技术的原因是:它本身是单线程架构,为了避免在处理客户端请求时因某个连接的阻塞 I/O 操作(如读/写)导致整个线程停顿,Redis 使用多路复用来同时监听多个连接的就绪状态,从而在一个线程内高效地管理大量并发客户端,保证系统高性能和低延迟。
Redis 的 I/O 多路复用模型基于操作系统的多路复用机制(如 epoll),每个客户端连接对应一个 socket,也就是一个文件描述符(fd)。Redis 会将所有客户端的 fd 注册到多路复用程序中,监听它们的读写事件。当客户端有数据可读或可写时,多路复用程序会触发对应的事件,通知 Redis 的文件事件处理器。文件事件处理器在单线程内依次调用各个就绪 fd 绑定的事件处理函数,执行 accept、read、write 等操作。这样,Redis 在一个线程中就能高效监控和处理大量客户端连接,避免了单个 I/O 操作阻塞导致的整个进程停顿。Redis 采用的 I/O 多路复用模式属于 Reactor 设计模式,实现了非阻塞、高并发的网络通信处理。

4. redis的网络模型是怎样的?

Redis 6.0 之前采用单 Reactor 单进程的网络模型,整个模型基于一个进程运行。Reactor 通过 I/O 多路复用技术,如 epoll,监听客户端连接与数据读写事件。当有请求到来,Reactor 直接在该进程内处理业务逻辑,像读写内存中的键值对数据结构。这种方案优势明显,代码实现简单,无进程间通信和竞争问题,且 Redis 基于内存操作,速度快,性能不受 CPU 限制。但它也存在短板,无法利用多核 CPU 性能,若业务处理耗时,如对大型集合排序,会阻塞整个进程,导致其他请求响应延迟,仅适用于业务处理快速的场景。
Redis 6.0 及之后对网络 I/O 处理进行多线程优化,但命令执行依旧单线程。主线程作为 Reactor,持续监听套接字事件,当有新连接或数据到达,会将请求分配给工作线程池。工作线程默认数量与 CPU 核数相关,可配置,它们专门负责网络数据读取和解析,通过批量读取多个客户端数据,利用多线程并行处理,减少 I/O 等待时间。解析后的命令任务传递给主线程,主线程按顺序执行具体操作,确保原子性和顺序性。这样设计主要是因为网络硬件性能提升后,Redis 性能瓶颈转移到网络 I/O,优化后能提升网络吞吐量,适应高并发场景。

5. redis哪些地方使用了多线程?

  1. Redis 从 6.0 版本开始对网络 I/O 处理引入多线程机制,以应对高并发场景下的性能瓶颈。在该机制下,主线程作为 Reactor,持续监听客户端连接与数据读写事件,当检测到事件发生时,不再像旧版本那样单线程处理,而是将套接字分配给预先设定的工作线程池。工作线程池默认线程数量与服务器 CPU 核数相关(通常为 CPU 核数的一半,也可通过 io-threads 参数灵活配置,最大支持 16 个线程)。这些工作线程会采用 readv 等系统调用批量读取多个客户端数据,并行解析命令参数,比如将 SET key value 拆解为对应参数数组。完成解析后,工作线程将命令任务提交给主线程,主线程再按顺序执行具体命令逻辑并返回结果。通过这种方式,Redis 在百万级并发连接场景下,网络吞吐量显著提升 30% - 50%,有效满足了秒杀、实时计数等高频小数据包交互的业务需求。
  2. 在数据持久化方面,Redis 支持 RDB 和 AOF 两种方式,从 6.0 版本起,其持久化操作也融入了多线程设计理念。对于 RDB 持久化,传统模式下会 fork 子进程进行全量快照生成,这个过程可能会阻塞主线程。而改进后,在数据量较大时,RDB 快照的生成过程可以通过后台线程并行处理,减少对主线程的影响;AOF 持久化主要负责将写命令追加到日志文件,在多线程模式下,AOF 的写入操作同样能在后台线程异步执行,主线程只需将写命令传递给后台线程,无需等待日志落盘即可继续处理后续请求,避免了因持久化操作导致的响应延迟,极大提升了 Redis 在数据持久化过程中的整体性能与响应速度。
  3. Redis 还会利用多线程卸载一些耗时任务,以此保障主线程的高效运行。在 Redis 集群模式中,节点间的通信、故障转移检测等操作通常较为耗时,若由主线程处理会阻塞其他请求。因此,这些任务会被分配给后台线程执行,使其在不影响主线程处理客户端请求的情况下,完成集群状态维护;另外,UNLINK 命令用于删除键值对时,若数据量庞大,删除操作可能会占用较长时间,此时 Redis 会将该删除任务交由后台线程异步处理,主线程接收命令后立即返回,告知客户端删除操作已在处理中,从而避免了因长时间删除操作导致的请求阻塞,降低客户端请求延迟,让主线程能迅速响应其他新的客户端请求。
  4. Redis 所采用的 jemalloc 内存分配器也与多线程机制紧密配合。jemalloc 可配置一个后台线程专门负责内存释放与整理工作。当 Redis 释放内存时,若采用单线程操作,在释放大量内存块时可能会产生阻塞,影响系统性能。而借助后台线程,内存释放操作可以在后台异步进行,与主线程的内存分配操作并行,这不仅提高了内存管理效率,还减少了内存碎片化问题,使得 Redis 在频繁进行内存分配与释放的场景下,依然能够保持高效稳定的运行状态 。
http://www.xdnf.cn/news/13427.html

相关文章:

  • python 中线程、进程、协程
  • RED:用于低剂量 PET 正弦图重建的残差估计扩散模型|文献速递-深度学习医疗AI最新文献
  • 上门服务类App开发全流程:从需求分析到部署上线
  • 【16】牵绳遛狗数据集(有v5/v8模型)/YOLO牵绳遛狗检测
  • 前馈神经网络
  • Vim 撤销 / 重做 / 操作历史命令汇总
  • 【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
  • 【大模型】解耦大语言模型中的记忆与推理能力
  • 【大模型RAG】识别-检索-生成:拍照搜题给出答案原理讲解
  • IP地址可视化:从现网监控到合规检测、准入控制全面管理
  • 【单片机期末】接口及应用
  • 算法第12天|继续学习二叉树:翻转二叉树、对称二叉树、二叉树最大深度、二叉树的最小深度
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第十六讲)
  • DnSpy调试基础
  • gRPC、WebSocket 与 HTTP 的核心区别对比
  • 将两个变量a,b的值进行交换,不使用任何中间变量
  • Cursor 工具项目构建指南:让 AI 审查 AI 生产的内容,确保生产的内容质量和提前发现问题
  • Vim 翻页与滚动命令总览
  • 新能源知识库(35)AutoML在用电负荷预测中如何应用?
  • 【杂谈】-递归进化:人工智能的自我改进与监管挑战
  • Linux基础指令大全
  • SpringCloud微服务入门
  • Day50 Python打卡训练营
  • Vim 修改(change)命令完整学习笔记
  • [原创]X86C++反汇编02.算术指令
  • 闪回还能导致OGG同步失败
  • 生成xcframework
  • 一个获取极简风格动画素材的网站
  • Day11_刷题niuke20250610
  • CppCon 2015 学习:C++ Requests