首页 > 数据库 >(三)Redis 线程与IO模型

(三)Redis 线程与IO模型

时间:2024-06-05 09:22:52浏览次数:24  
标签:请求 单线程 Redis 线程 IO 客户端

1、Redis 单线程

通常说 Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,其他功能,比如持久化、异步删除、集群数据同步等,是由额外的线程执行的,所以严格来说,Redis 并不是单线程。

多线程开发会不可避免的带来并发控制和资源开销的问题,如果没有良好的系统设计往往会适得其反,为了避免这些问题,Redis 直接采用了单线程模式。

Redis 单线程模型能达到每秒数十万级别的处理能力,一方面是大部分操作在内存上完成 + 高效的数据结构,例如哈希表和跳表。另一方面,就是采用了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率。

在了解多路复用之前,要先明白网络操作的基本 IO 模型和潜在的阻塞点。如果单线程被阻塞了,就无法进行多路复用了。以 Get 请求为例如下图,bind/listen、accept、recv、parse 和 send 属于网络 IO 处理,get 属于键值数据操作。
这里的网络 IO 操作中,潜在的阻塞点分别是 accept() 和 recv()。当 Redis 监听到一个客户端有连接请求,但一直未能成功建立起连接时,会阻塞在 accept() 函数这里,导致其他客户端无法和 Redis 建立连接。类似的,当 Redis 通过 recv() 从一个客户端读取数据时,如果数据一直没有到达,Redis 也会一直阻塞在 recv(),这就导致 Redis 整个线程阻塞,无法处理其他客户端请求,效率很低。不过,Socket 网络模型可以设置非阻塞模式,基于此 Linux 中的 IO 多路复用机制就要登场了。

2、多路复用机制

Linux 中的 IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。
图中的多个 FD 就是指多个套接字,Redis 网络框架调用 epoll 机制,让内核监听这些套接字。此时,Redis 线程不会阻塞在某一个特定的监听或已连接套接字上,所以,Redis 可以同时和多个客户端连接并处理请求,从而提升并发性。

为了在请求到达时能通知到 Redis 线程,select/epoll 提供了基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数,select/epoll 一旦监测到 FD 上有请求到达时,就会触发相应的事件。这些事件会被放进一个事件队列,Redis 单线程对该事件队列不断进行处理。这样一来,Redis 无需一直轮询是否有请求实际发生,这就可以避免造成 CPU 资源浪费。同时,Redis 在对事件队列中的事件进行处理时,会调用相应的处理函数,这就实现了基于事件的回调。因为 Redis 一直在对事件队列进行处理,所以能及时响应客户端请求,提升 Redis 的响应性能。

3、Redis 6.0 多线程特性

Redis 6.0 之前,虽然有些命令操作可以用后台线程或子进程执行(比如数据删除、快照生成、AOF 重写),但是,从网络 IO 处理到实际的读写命令处理,都是由单个线程完成的,有时会成为 Redis 的性能瓶颈。Redis 6.0 之后采用多个 IO 线程来处理网络请求,提高网络请求处理的并行度,对于读写命令,仍然使用单线程来处理。

具体流程:
(1)主线程接收到客户端连接请求后创建连接,将 Socket 放入全局等待队列中,通过轮询分配给 IO 线程。
(2)分配后主线程就会进入阻塞状态,等待 IO 线程完成客户端请求读取和解析,多个 IO 线程在并行处理,嗖嗖嗖。
(3)IO 线程解析完请求,主线程还是会以单线程的方式执行这些命令操作。
(4)主线程执行完请求操作后,把返回结果写入缓冲区,主线程阻塞等待 IO 线程把这些结果回写到 Socket 中,并返回给客户端。
和 IO 线程读取和解析请求一样,IO 线程回写 Socket 时,也是有多个线程在并发执行,所以回写 Socket 的速度也很快。等到 IO 线程回写 Socket 完毕,主线程会清空全局队列,等待客户端的后续请求。

4、IO 多线程配置

在实际应用中,如果 Redis 实例的 CPU 开销不大,吞吐量却没有提升,可以考虑使用多线程机制提升吞吐量,redis.conf 中设置:
1. 设置 io-thread-do-reads 配置项为 yes,表示启用多线程

io-threads-do-reads yes

2. 设置线程个数要小于 Redis 实例所在机器的 CPU 核个数,例如,对于一个 8 核的机器来说,Redis 官方建议配置 6 个 IO 线程

io-threads  6

标签:请求,单线程,Redis,线程,IO,客户端
From: https://www.cnblogs.com/WinterSir/p/17944862

相关文章

  • ASP.NET Web应用程序升级最新的MSBuild格式后,Visual Studio 2022中如何调试?
    摘要把ASP.NET的Web应用程序,Project文件从<ProjectToolsVersion="12.0"DefaultTargets="Build"xmlns="http://schemas.microsoft.com/developer/msbuild/2003">改为<ProjectSdk="Microsoft.NET.Sdk.Web">之后,升级成了最新的格式之后,如......
  • 重写学习 localStorage 与 sessionStorage
    localStorage与sessionStoragelocalStorage与sessionStorage很多小伙伴对它们俩都很熟悉了;最熟悉的莫过下面这2条1,localStorage存储的数据没有时间限制,理论上永久有效;除非手动清除。sessionStorage存储的数据在关闭当前页面后失效;2,有存储大小限制,两者存储大......
  • 简单4步,带你用华为云MetaStudio制作数字人短片
    本文分享自华为云社区《使用MetaStudio生产线四步制作数字人视频》,作者:yd_298097624。随着AIGC新技术尤其是大模型技术的发展,音视频行业、数字内容生产行业正在经历这从生产方式和生产效率上的一个巨大变化。预测到2030年有AI大模型生成的数字内容比例将高达90%,包括通过AIGC来生......
  • ASP.NET Web应用程序升级最新的MSBuild格式后,Visual Studio 2022中如何调试?
    摘要把ASP.NET的Web应用程序,Project文件从<ProjectToolsVersion="12.0"DefaultTargets="Build"xmlns="http://schemas.microsoft.com/developer/msbuild/2003">改为<ProjectSdk="Microsoft.NET.Sdk.Web">之后,升级成了最新的格式之后,如......
  • 线程与进程的实现
    目录1.线程的实现方式1.用户级线程(User-LevelThreads,ULTs)2.内核级线程(Kernel-LevelThreads,KLTs)2.线程的具体实现2.1用户级线程的实现2.2内核级线程的实现3.线程的创建与终止4.进程的创建与终止5.进程同步与互斥6.进程通信总结1.线程的实现方式 ......
  • 基于双向长短时记忆神经网络结合多头注意力机制BiLSTM-Mutilhead-Attention实现柴油机
    %加载数据集和标签load(‘diesel_dataset.mat’);%假设数据集存储在diesel_dataset.mat文件中data=diesel_dataset.data;labels=diesel_dataset.labels;%数据预处理%这里假设你已经完成了数据的预处理,包括特征提取、归一化等步骤%划分训练集和测试集[tra......
  • Redis 结合 Docker 搭建集群,并整合SpringBoot
    软件版本Redis7.2.5Docker26.1.3 准备工作由于docker直接拉取运行了,所以需要提前准备配置文件Indexof/releases/(redis.io)下载后,把redis-7.2.5.tar.gz\redis-7.2.5.tar\redis-7.2.5\里的redis.conf复制出来 概览结构如上图所示,准备6个服务器。 配置各节点......
  • Redis之zset
    Zset(有序集合)序集合Zset与普通集合Set类似,都是没有重复元素的集合;有序集合Zset中的元素排序,是根据评分进行排序,每个成员都关联了一个评分,在该有序集合中,根据评分由低到高进行排序;Zset中的元素是不可重复的,但是元素关联的评分......
  • IO进程线程(五)库的制作、进程
    文章目录一、库(一)静态库1.概念2.制作3.使用(编译)(1)生成可执行文件(2)运行(二)动态库(共享库)1.概念2.制作3.生成可执行文件4.基于动态库的可执行文件的执行过程二、进程(一)概念1.进程2.进程和程序的区别3.进程的组成4.进程的种类(1)交互进程(2)批处理进程(3)守护进程5.......
  • Z.ExtensionMethods安装
    C#开源实用的工具类库,集成超过1000多种扩展方法 前言今天大姚给大家分享一个C#开源(MITLicense)、免费、实用且强大的工具类库,集成超过1000多种扩展方法增强.NETFramework和.NETCore的使用效率:Z.ExtensionMethods。直接项目引入类库使用在你的对应项目中NuGet包管理器......