首页 > 数据库 >Redis之线程IO模型

Redis之线程IO模型

时间:2024-06-13 22:33:11浏览次数:19  
标签:单线程 Redis 线程 事件 IO select 客户端

引言

Redis是个单线程程序!这点必须铭记。除了Redis之外,Node.js也是单线程,Nginx也是单线程,但是他们都是服务器高性能的典范。

Redis单线程为什么能够这么快! 因为他所有的数据都在内存中,所有的运算都是内存级别的运算。正因为Redis是单线程,所以要小心使用Redis指令,对于那些时间复杂度为O(n)级别的指令,一定要谨慎使用,一不小心可能就会导致Redis卡顿。

Redis单线程如何处理那么多的并发客户端连接! 其答案就是多路复用

非阻塞IO

Redis使用基于事件的非阻塞IO模型,这种模型使得Redis能够在不阻塞主线程的情况下,同时处理多个客户端连接。Redis使用IO多路复用技术,通常是select、epoll、kqueue,这取决于运行Redis的操作系统。这些技术允许单个线程监视多个文件描述符,以检测是否有IO操作成为可能,例如数据可读或者可写。

读写过程

  • 读操作:当客户端发送命令到Redis服务器时,服务器使用非阻塞socket读取命令。命令读取完成后,单线程执行命令并处理数据
  • 写操作:处理完客户端命令后,生成的输出将通过非阻塞socket发送回客户端,如果数据无法一次性发送完毕(例如,输出缓冲区已满),剩余的数据会被缓存,并在socket可写时继续发送。

事件轮询(多路复用)

非阻塞IO有个问题,那就是线程要读数据,结果读了一部分就返回了,线程如何知道何时才应该继续读。也就是当数据到来时,线程如何得到通知,写也是一样,如果缓冲区满了,写不完,剩下的数据何时才能继续写,线程也应该得到通知。
在这里插入图片描述

事件轮询API就是用来解决这个问题的,最简单的事件轮询API是select函数,他是操作系统提供给用户程序的API。输入是读写描述符列表read_fds&write_fds, 输出是与之对应的可读可写事件。同时还提供了一个timeout参数,如果没有任何事件到来,那么就最多等待timeout时间,线程处于阻塞状态。一旦期间有任何事件到来,就可以立即返回。时间过了之后还是没有任何事件到来,也会立即返回。拿到事件后,线程就可以继续挨个处理相应的事件。处理完了继续过来轮询。于是线程就进入了一个死循环,我们把这个死循环称为事件循环,一个循环为一个周期。

每个客户端套接字socket都有对应的读写文件描述符。

read_events, write_events = select(read_fds, write_fds, timeout) 
for event in read_events:
 handle_read(event.fd) 
for event in write_events:
 handle_write(event.fd)
handle_others() # 处理其它事情,如定时任务等

因为我们通过select系统调用同时处理多个通道描述符的读写事件,因此我们将这类系统调用称为多路复用API。现代操作系统的多路复用API已经不再使用select系统调用,而改用epoll(linux)和kqueue(freebsd&macosx),因为select系统调用的性能在描述符特别多时性能会非常差。他们使用起来可能在形式上略有差异,但是本质上差不多,都可以使用上面的伪代码进行理解。

服务器套接字serversocket对象的读操作指调用accept接受客户端新连接,何时有新连接到来,也是通过select系统调用的读事件来得到通知。

指令队列

Redis会将每个客户端套接字都关联一个指令队列,客户端的指令通过队列来排队进行顺序处理,先到先服务。

响应队列

Redis同样也为每个客户端套接字关联一个响应队列。Redis服务器通过响应队列来将指令的返回结果返回给客户端。如果队列为空,那么意味着连接暂时处于空闲状态,不需要去获取写事件,也就是可以将当前的客户端描述符从write_fds里面移除,等到队列有数据了,再将描述符放进去,避免select系统调用立即返回写事件,如果发现没什么数据可以写。出这种情况的线程会飙高CPU。

定时任务

服务器除了要响应IO事件外,还要处理其他事情。比如定时任务就是非常重要的一件事,如果线程阻塞在select系统调用上,定时任务将无法得到准时调度。那么Redis是如何解决的呢。

Redis的定时任务会记录在一个称为最小堆的数据结构中,这个堆中,最快要执行的任务排在堆的最上方,在每个循环周期,Redis都会将最小堆里面已经到点的任务立即进行处理。处理完毕后,将最快要执行的任务还需要的时间记录下来,这个时间就是select系统调用的timeout参数。因为Redis知道未来timeout时间内,没有其他定时任务需要处理,所以可以安心睡眠timeout时间。

总结

Redis单线程,利用IO多路复用技术,单线程监听多个文件描述符,并进行事件轮询(单线程循环),轮询期间如果发生可读事件,从缓冲区中读取事件并进行处理,处理完后再将数据发送到写缓冲区写回给客户端。轮询通过select(read_fds, write_fds, timeout) 函数进行,其中timeout为轮询阻塞时间。

标签:单线程,Redis,线程,事件,IO,select,客户端
From: https://blog.csdn.net/weixin_42824596/article/details/139656178

相关文章

  • VideoGeneration
    StableVideoDiffusion:ScalingLatentVideoDiffusionModelstoLargeDatasets主要贡献:设计了一套数据清洗策略来清洗大规模的低质量的数据,用于训练T2V的SOTA模型,并证明了此模型具有足够强的关于动作和3D的先验知识可以用于视频相关的下游任务。目前主要的T2V的模型都是......
  • 过渡属性transition
    *transition这个属性添加在谁的身上就在谁的身上发生变化!!!注意:不要加在hover上!!!*例如:在box盒子上就在box盒子上变化1、瞬间变长,看不到过程<!DOCTYPEhtml><!--文档类型--><htmllang="en"> <head> <metacharset="utf-8"> <metaname="viewport"c......
  • 显著性目标检测(弱监督):Mutual Information Regularization for Weakly-supervised
    文章地址:MutualInformationRegularizationforWeakly-SupervisedRGB-DSalientObjectDetection|IEEEJournals&Magazine|IEEEXplore摘要:1.引入一个信息上界和一个互信息最小化正则项,鼓励每个模态的解纠缠表示用于SOD;2.运用非对称的特征提取器;3.引入多模态的......
  • 【Python】成功解决UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x80 in p
    【Python】成功解决UnicodeDecodeError:‘gbk’codeccan’tdecodebyte0x80inposition45:illegalmultibytesequence 下滑即可查看博客内容......
  • 线程、进程、并发和并行的概念
    线程、进程、并发和并行的概念进程:是指一个在内存中正在运行的程序,是操作系统分配资源(文件、io、网络、内存等资源)的基本单位。一个程序文件(也就是我们编写、编译好的程序,是保存在磁盘中的,例如.exe程文件),当我们点击,程序文件就被加载到内存中,也就创建了一个进程。同一个程......
  • G. D-Function
    原题链接题解先不考虑k的限制,而是考虑对于任意一个数,存不存在一个k使得题目所给等式成立当\(n·k\)没有进位时,等式一定成立(赛时也许想到这就够了)假如有进位呢?对于任何一个位数大于1的数,必有\(D(n)\ltn\)(想想十进制是怎么表示数的)而对于位数为1的数,有\(D(n)=n\)所......
  • vivado HW_SIO_TX
    描述在硬件设备上,每个GT包括一个独立的发射机hw_sio_tx由一个PCS和一个PMA组成。并行数据从设备逻辑流入FPGATX接口,通过PCS和PMA,然后输出TX驱动器作为高速串行数据。相关对象有关HW_SIO_TX对象与与其他硬件对象具有。SIO_TX对象与HW_,hw_target、hw_device、hw_sio_ibe......
  • 文件IO,创建编号为ABC三个线程,三个线程循环打印自己的编号,要求打印出来的结果必须是ABC
    第二个,拷贝图片#include<myhead.h>typedefstruct{ constchar*srcfile; constchar*destfile; intlen;}info;void*task1(void*arg){ infobuf=*((info*)(arg)); //打开这两个文件,只读的形式 intfd=-1; if((fd=open(buf.srcfile,O_RDONLY))==-1) {......
  • EtherCAT主站SOEM -- 41 -- win-vs-soem-win10及win11系统VisualStudio-SOEM-控制电机
    EtherCAT主站SOEM--41--win-vs-soem-win10及win11系统VisualStudio-SOEM-控制电机走位置模式(PP模式)0QT-SOEM及STM32F767-SOEM视频欣赏及源代码链接:0.1Linux--Ubuntu系统之QT-SOEM博客、视频欣赏及源代码链接0.2STM32F767-SOEM博客、视频欣赏及源代码链接0......
  • 多线程与多进程
    1.进程和线程的定义进程线程的定义:进程可以理解为在操作系统中一个运行起来的程序(程序是指令、数据及其组织形式,进程是程序的实体),是操作系统进行资源分配的最小单位。线程是进程中的一个执行流,是操作系统进行系统调度的最小单位,一个进程由一个或多个线程组成。2.多进程和多线程......