首页 > 数据库 >【redis学习】Redis-IO多路复用

【redis学习】Redis-IO多路复用

时间:2024-05-10 16:22:21浏览次数:24  
标签:请求 Redis redis 线程 IO 接字 客户端

为什么要有IO多路复用

大家印象中的redis都是单线程的,没有加锁的操作,因此才会是redis这么快的原因其中之一。先暂且不说redis究竟是不是单线程,即便是单线程的,作为服务提供方,面对成百上千的客户端连接请求,读写操作,单线程是怎么做到高效的处理这些请求?单线程处理socket连接,面对客户端发送的指令如何处理?一个个轮询吗?明显是比较低效的操作,作为高效著称的redis肯定是不会用这么简单粗暴的方式去处理的。这里就引出一个解决方式IO多路复用

在redis6/7中,非常受关注的第一个新特性就是多线程。
redis一直被大家熟知的就是它的单线程架构,虽然有的命令操作可以用后台线程或者子进程执行(比如数据删除,快照生成,AOF重写)。但是,从网络IO处理到实际的读写命令处理,都是由单个线程完成的

为了应对这个问题,采用多个IO线程来处理网络请求,提高网络请求处理的并行度,Redis6/7就是采用的这种方法。
但是redis的多IO线程只是用来处理网络请求的,对于读写操作命令Redis仍然使用单线程来处理。这是因为redis处理请求时,网络处理经常是瓶颈,通过多个IO线程并行处理网络操作,可以提升实例的整体处理性能。而继续使用单线程执行命令操作,就不用为了保证Lua脚本,事务的原子性,额外开发多线程互斥加锁机制了,这样一来redis线程模型实现就简单了。

什么是IO多路复用

网络IO在系统层面上指的是数据从用户态到内核态的读写操作,多路是指多个socket连接。在UNIX网络编程中写道为了执行网络IO,一个进程必须要做的第一件事就是调用socket函数。复用是指一个或多个连接处理。
一个服务端进程可以同时处理多个套接字描述符。
redis使用IO多路复用简单来说就是,单线程处理多个客户端连接的网络读写请求,并且能够保证不会阻塞主流程的一种机制。
实现IO多路复用的模型有3种:可以分select->poll->epoll三个阶段来描述。

基本IO模型与阻塞点

以Get请求为例,服务端为了处理一个Get请求,需要监听客户端请求(bind/listen),和客户端建立连接(accept),从scoket中读取请求(recv),解析客户端发送请求(parse),根据请求类型读取键值数据(get),最后客户端返回结果,即向socket中写回数据(send)。

下图显示了这一过程,其中,bind/listen、accept、recv、parse和send属于网络IO处理,而get属于键值数据操作。既然Redis是单线程,那么,最基本的一种实现是在一个线程中依次执行上面说的这些操作。

但是,在这里的网络IO操作中,有潜在的阻塞点,分别是accept()和recv()。当Redis监听到一个客户端有连接请求,但一直未能成功建立起连接时,会阻塞在accept()函数这里,导致其他客户端无法和Redis建立连接。类似的,当Redis通过recv()从一个客户端读取数据时,如果数据一直没有到达,Redis也会一直阻塞在recv()。这就导致Redis整个线程阻塞,无法处理其他客户端请求,效率很低。

以上描述的就是在阻塞式socket可能会出现的阻塞点。假设一个socket被阻塞在其中某一个步骤,那么其他的socket也将会被阻塞住。这种情况肯定是不能容忍的。幸运的是socket网络模型本身支持非阻塞式。

非阻塞模式

Socket网络型的非阻塞式模式设置,主要体现在三个关键的函数调用上,如果想使用socket非阻塞模式,就必须要了解这三个函数的调用返回类型和设置模式。

在socket模型中,不同操作调用后返回不同的套接字类型。socket()方法会返回主动套接字,然后调用listen()方法,将主动套接字转换为监听套接字,此时,可以监听来自客户端的请求连接。最后调用accpet()方法接受到的客户端连接,并返回已连接套接字。

针对监听套接字,可以设置非阻塞模式:当redis调用accpet()单一直未有连接请求到达时,redis线程可以返回处理其他操作,而不用一直等待。
虽然redis线程可以不用继续等待,但是总得有机制继续在监听套接字上等待后续连接请求并且在有请求时通知redis。
同样也可以针对已连接套接字设置非阻塞模式:在redis调用recv()后,如果已连接套接字上一直没有数据到达,redis线程同样可以返回处理其他操作。也需要有机制继续监听已连接套接字,并在有数据到达时通知redis。
这样才能保证redis线程,既不会像基本IO模型中一直在阻塞点等待,也不会导致redis无法处理实际到达的连接请求或数据。
那么这个机制究竟是什么来实现的?

简述多路复用模型

将用户socket对应的文件描述符注册进epoll,然后epoll监听哪些scoket上有消息到达,这样就避免了大量的无用操作。设置sokcet模型为非阻塞模式,这样整个过程只在调用epoll这些的时候才会阻塞。收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件驱动,所谓的reactor响应模式。至此我们明白了用于监听事件拉起通知的机制是通过epoll这些来实现管理的。

Linux中的IO多路复用机制是指一个线程处理多个IO流,就是我们经常听到的select/epoll机制。简单来说在redis只运行单线程的情况下,该机制允许内核中同事存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给redis线程处理,这就是实现了一个redis线程处理多个IO流的效果。

下图就是基于多路复用的redis IO模型。图中的多个FD就是刚才所说的多个套接字。Redis网络框架调用epoll机制,让内核监听这些套接字。此时Redis线程不会阻塞在某一个特定的监听或者已连接套接字上,也就是说,不会阻塞在某一个特定的客户端请求处理上。正因为此,redis可以同时和多个客户端连接并处理请求,从而提升并发性。

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

标签:请求,Redis,redis,线程,IO,接字,客户端
From: https://www.cnblogs.com/qianbendan/p/18184717

相关文章

  • Android Studio简单入门教程
    1.建立项目首先点击new——newproject新建项目选择想要创建的Android的模板,建议选择emptyactivity(空模板),然后nextName:给你的项目起一个名字APIlevel:选择Android虚拟机的版本,版本越低运行起来越快剩下的就按默认的就行,点击finish(由于版本不一样,步骤2和步骤3的顺序......
  • vue3 vite项目H5页面 ios13进入页面出现白屏问题
    项目中碰见IOS系统进入页面出现白屏问题,记录一下问题排查过程一、页面可能报错进入页面是白屏,页面的 vconsole 也没有显示,首先想到的是页面是不是有什么报错,然后查看了别的机型,都没有问题,定位到只有IOS13有问题,想着会不会是什么语法在IOS13不兼容(这个问题之前出现过一个......
  • 理解 iOS 中的多线程编程
    在iOS应用开发中,多线程编程是一项关键技术,可以帮助应用实现更好的性能和响应性。本文将详细解释iOS中的多线程编程,并讨论如何在应用中正确地使用多线程以提高性能和响应性。1.什么是多线程编程?多线程编程是指在一个应用程序中同时执行多个线程(线程是进程中的执行单元),从而实......
  • 探讨:Grand Central Dispatch(GCD)与 Operation 和 OperationQueue 的使用
    在iOS开发中,GrandCentralDispatch(GCD)和Operation和OperationQueue是两种常用的多线程编程技术,它们各有优劣,适用于不同的场景。本文将详细讲解它们在不同情况下的具体使用,并提供Swift和Objective-C语言的示例。1.GrandCentralDispatch(GCD)Swift示例://在后台队列......
  • Dapr IoT Architecture是一个基于.NET平台的物联网系统架构
    DaprinIoT.UnderstandingofconceptbuildingdistributedapplicationinIoThttps://docs.dapr.io 在构建一个网联网系统(InternetofThings,IoT)或数字化系统的C#开源系统架构中,通常需要考虑以下关键方面:1.设备连接和数据采集:使用C#编写设备连接模块,支持多种通信协......
  • Connecting to github.com (github.com)|20.205.243.166|:443... failed: Connection
    今天使用ubuntu虚拟机编译buidroot代码时出现一些压缩包无法从github下载,如下图: 可是拷贝上图log中的下载链接到windows浏览器进行打开会自动进行下载成功,如粘贴该链接 https://github.com/winshining/nginx-http-flv-module/archive/v1.2.8/nginx-http-flv-......
  • MinIO对象存储 安装和java调用
    1、参考MinIO对象存储介绍和使用【备忘录】JAVASDK连接MinIO,附完整代码2、packageorg.j****g.common.util.io;importcn.hutool.core.io.FileUtil;importio.minio.*;importio.minio.errors.MinioException;importio.minio.http.Method;importio.minio.messages.Buc......
  • 解析 iOS 中的响应链(Responder Chain)
    在iOS应用程序中,响应链(ResponderChain)是一种重要的事件传递机制,用于处理用户输入和触摸事件。本文将详细讲解什么是响应链,以及它在iOS中的作用和原理。1.什么是响应链?响应链是iOS应用程序中用于处理用户输入和触摸事件的一种事件传递机制。在响应链中,事件会从发生事件的......
  • THUSC & APIO 2024 游记
    前言我应该算年龄很小的,这次旅途我没很多追求,具体的签约我也没弄清楚是什么回事,只知道我就是去那边考个试,但是还是蛮兴奋的,因为上次去集训面基到了0人,看这次能不能撞见几个大佬。至于APIO,我翻了翻去年的APIO成绩,发现Cu好像并不是那么难。说不定我rp++了就Cu了。我以......
  • Redis高可用架构
    redis架构的演进单机、主从、集群特性/配置Redis主从复制Redis哨兵Redis集群主要目的数据备份与读写分离高可用性和故障自动切换高并发和数据分散处理架构一个主节点和多个从节点监控主从结构并自动切换多个主节点,数据分片数据复制主节点到从节点监控并管......