4.Redis单线程和多线程

1.Redis的单线程

Redis的单线程主要是指Redis的网络IO和键值对读写是由一个线程完成的,Redis在处理客户端的请求时包括获取(Socket读)、解析、执行、内容返回(Socket写)等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。

但Redis的其他功能,比如持久化RDB、AOF、异步删除、集群数据同步等等,其实是由额外的线程执行的。

2.Redis的多线程

从redis6.x开始采用多线程,让多个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),将最耗时的Socket的读取、请求解析、写入外包出去,剩下的命令执行仍然由主线程串行执行并和内存的数据交互。

也就是说就新增了多线程的功能来提高 I/O 的读写性能,使多个 socket 的读写可以并行化

3.Redis快的原因

1.基于内存

2.简单的数据结构

3.单线程,避免上下文切换;

4.IO多路复用

4.IO多路复用

一种同步的IO模型,实现一个线程监视多个文件句柄,一旦某个文件句柄就绪就能够通知到对应应用程序进行相应的读写操作,没有文件句柄就绪时,就会阻塞应用程序,从而释放cpu资源。一个专家大夫和多个病人之间的关系。

Io多路复用:单个进程能够实现处理多个客户端的连接请求。或者一个服务进程能够可以同时处理多个套接字描述符

epoll的原理:将用户socket对应的文件描述符注册进epoll,然后epoll帮你监听哪些socket上有消息到达。此时的socket应该采用非阻塞模式。这样,整个过程只有在调用select、poll、epoll这些调用的时候才会阻塞,收发客户信息是不会阻塞的,整个进程或者线程就被充分利用起来。这就是事件驱动,所谓的Reactor反应模式。

4.1Redis的事件处理器

Redis基于Reactor模式开发了自己的网络事件处理器-文件事件处理器(fiel event handler, FEH),该处理器是单线程的,所以redis就是单线程模式。

采用I/O多路复用同时监听多个socket,根据socket当前执行的事件来为 socket 选择对应的事件处理器

当被监听的socket准备好执行accept、read、write、close等操作时,和操作对应的文件事件就会产生,这时FEH就会调用socket之前关联好的事件处理器来处理对应事件。

所以虽然FEH是单线程运行,但通过I/O多路复用监听多个socket,不仅实现高性能的网络通信模型,又能和Redis 服务器中其它同样单线程运行的模块交互,保证了Redis内部单线程模型的简洁设计。

下面来看文件事件处理器的几个组成部分。

I/O 多路复用程序会将所有产生事件的socket放入队列, 通过该队列以有序、同步且每次一个socket的方式向文件事件分派器传送socket。

4.1.1文件事件分派器

文件事件分派器接收IO多路复用程序传来的socket,并根据socket产生的事件类型,调用相应的事件处理器

4.1.2文件事件处理器

服务器会为执行不同任务的套接字关联不同的事件处理器, 这些处理器是一个个函数, 它们定义了某个事件发生时, 服务器应该执行的动作。

Redis 为各种文件事件需求编写了多个处理器,若客户端连接Redis,对连接服务器的各个客户端进行应答,就需要将socket映射到连接应答处理器,写数据到Redis,接收客户端传来的命令请求,就需要映射到命令请求处理器,从Redis读数据,向客户端返回命令的执行结果,就需要映射到命令回复处理器,当主服务器和从服务器进行复制操作时, 主从服务器都需要映射到特别为复制功能编写的复制处理器。

5.Reactor模式

5.1单线程Reactor模式

服务器端的Reactor是一个线程对象,该线程会启动事件循环,并使用Acceptor事件处理器关注ACCEPT事件,这样Reactor会监听客户端向服务器端发起的连接请求事件(ACCEPT事件)

客户端向服务器端发起一个连接请求,Reactor监听到了该ACCEPT事件的发生并将该ACCEPT事件派发给相应的Acceptor处理器来进行处理建立连接后关注的READ事件,这样一来Reactor就会监听该连接的READ事件了。

Reactor监听到有读READ事件发生时,将相关的事件派发给对应的处理器进行处理。比如,读处理器会通过读取数据,此时read()操作可以直接读取到数据,而不会堵塞与等待可读的数据到来。

在目前的单线程Reactor模式中,不仅I/O操作在该Reactor线程上,连非I/O的业务操作也在该线程上进行处理了,这可能会大大延迟I/O请求的响应。所以我们应该将非I/O的业务逻辑操作从Reactor线程上卸载,以此来加速Reactor线程对I/O请求的响应。

6.Redis6.0为什么要引入多线程呢?

从Redis自身角度来说,因为读写网络的read/write系统调用占用了Redis执行期间大部分CPU时间,瓶

颈主要在于网络的 IO 消耗,多线程任务可以分摊 Redis 同步 IO 读写负荷

7.Redis6.0多线程的实现机制

流程简述如下:

1、主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列

2、主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程

3、主线程阻塞等待 IO 线程读取 socket 完毕

4、主线程通过单线程的方式执行请求命令,请求数据读取并解析完成,但并不执行回写 socket

5、主线程阻塞等待 IO 线程将数据回写 socket 完毕

6、解除绑定,清空等待队列

该设计有如下特点:

1、IO 线程要么同时在读 socket,要么同时在写,不会同时读或写

2、IO 线程只负责读写 socket 解析命令,不负责命令处理

注意:Redis的多线程不存在线程并发安全问题。Redis的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行。所以我们不需要去考虑控制 key、lua、事务,LPUSH/LPOP 等等的并发及线程安全问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/877784.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ProxySQL 读写分离配置

ProxySQL 是一个高性能、高可用的 MySQL 代理软件,旨在提升 MySQL 数据库的可扩展性和性能。它可以在应用程序和 MySQL 服务器之间充当中间层,提供强大的路由、负载均衡和查询优化功能。 ProxySQL 的主要功能: 查询路由: ProxySQ…

MySQL DDL详细讲解和常见问题案例示范

MySQL 删除操作和连接类型详细讲解和案例示范 DDL(Data Definition Language,数据定义语言)是用于创建和修改数据库结构的语句,包括创建表、索引、视图,以及修改这些结构。本文将详细介绍MySQL DDL语句的常见用法&…

stm32hal库can使用记录

一、单片机最小系统板使用can 资料:https://blog.csdn.net/yoie01/article/details/136921034 https://blog.csdn.net/qq_36561846/article/details/117431769 这里面有一个问题,最小系统板没有can收发器,所以没法直接用,只能测…

市盈率的概念

写篇有关市盈率的【不务正业】的内容。 重要公式 市盈率 官方的定义 平均市盈率=∑(收盘价发行数量)/∑(每股收益发行数量),统计时剔除亏损及暂停上市的上市公司。 静态市盈率 滚动市盈率(TTM) 股票市盈率的意义 如果某股票有较…

培训第三十四天(初步了解Docker与套接字的应用)

上午 回顾 1、主从复制(高可用) 2、传统的主从复制 3、gtids事务型的主从复制 4、注意 1)server_id唯一 2)8.X版本需要get_ssl_pub_key 3)5.X不需要 4)change master to 5)stop | sta…

项目服务器登录部分

从连接池中获取上下文&#xff0c;接受连接。 async_accept 这个函数本质上是监听和接受客户端连接的结合操作。 void CServer::StartAccept() {auto& io_context AsioIOServicePool::GetInstance()->GetIOService();std::shared_ptr<CSession> new_session mak…

JS中encodeURIComponent和encodeURI函数的区别

1、encodeURIComponent函数用于对完整的URL组件进行编码&#xff0c;包括查询参数、路径片段等。 它会对所有非字母数字字符进行编码&#xff0c;并将其替换为相应的URL编码形式。这包括对特殊字符&#xff08;如冒号、斜杠、问号、等号、加号等&#xff09;的编码。encodeURI…

拍抖音在哪里去水印,三招教你快速掌握去水印技巧

在抖音上&#xff0c;我们经常会看到一些精彩的内容&#xff0c;想要保存下来&#xff0c;但往往视频上会有水印。本文将分享五个免费且高效的去除抖音视频水印的技巧&#xff0c;帮助你轻松保存无水印的视频。 技巧一&#xff1a;奈斯水印助手(小程序) 奈斯水印助手是一款专…

GIS空间数据库,基本概念

文章目录 一、前言二、空间概念三、地理空间四、空间数据五、数据库六、空间数据库七、空间数据库与传统数据库的差异7.1 信息描述差异7.2 数据管理差异7.3 数据操作差异7.3 数据更新差异7.3 服务应用差异 一、前言 数据是指客观事物的属性、数量、位置及其相互关系等的符号描…

JavaScript(30)——解构

数组解构 数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法 基本语法&#xff1a; 赋值运算符左侧的[]用于批量声明变量&#xff0c;右侧数组的单元值将被赋值给左侧变量变量的顺序对应数组单元值的位置依次进行赋值操作 const arr [1, 2, 3, 4, 5]const [a, b…

云渲染的三个条件是指什么!哪三点最重要!

云渲染技术以其灵活性和效率&#xff0c;让创意人士和企业无论身处何地&#xff0c;都能通过网络接入强大的远程服务器&#xff0c;轻松完成复杂的图形渲染任务&#xff0c;但要发挥其魔力&#xff0c;我们得满足一些关键条件。 一、网络连接&#xff1a;云渲染的桥梁 首先&am…

PHP伪协议漏洞详解(附案例讲解)

文章目录 引言什么是PHP伪协议常见的PHP伪协议PHP伪协议漏洞原理实际案例分析案例一&#xff1a;利用php://filter读取敏感文件源码案例二&#xff1a;利用zip://协议执行压缩包中的恶意代码案例三&#xff1a;利用data://协议执行任意代码 引言 PHP伪协议是PHP中一种用于访问…

Go RPC 和 gRPC 技术详解

引言 在分布式系统中&#xff0c;服务之间的通信是非常重要的组成部分。远程过程调用 (RPC) 是一种广泛使用的通信方式&#xff0c;它允许程序在不同的计算机上执行函数或过程&#xff0c;就像调用本地函数一样。随着微服务架构的流行&#xff0c;RPC 成为了连接各个服务的重要…

协作新选择:即时白板在线白板软件分享

在团队合作中&#xff0c;产品经理扮演着至关重要的角色&#xff0c;他们不仅是产品与用户之间的纽带&#xff0c;更是产品性能和用户需求的桥梁。他们需要深入参与产品的研发过程&#xff0c;并与研发团队保持紧密的沟通。因此&#xff0c;产品经理需要一款高效的协作工具来提…

arthas源码刨析:arthas 命令粗谈(3)

文章目录 dashboardwatchretransform 前面介绍了 arthas 启动相关的代码并聊了聊怎么到一个 shellserver 的建立。 本篇我们来探讨一下几个使用频次非常高的命令是如何实现的。 dashboard 想看这个命令的主要原因是编程这些年来从来没有开发过 terminal 的这种比较花哨的界面&a…

php生成json字符串,python解析json字符串

<?php $nodes []; $_tmp[title] 标题1; $_tmp[titlekey] actt; $_tmp[child] [acww.zip, acww21.zip, tta.zip]; $nodes[] $_tmp;$_tmp2[title] 标题2; $_tmp2[titlekey] kfij; $_tmp2[child] [KL7SHR47.zip, fdgfdg.zip, qweqw.zip]; $nodes[] $_tmp2;// 构建调用…

SpringBoot集成kafka-获取生产者发送的消息(阻塞式和非阻塞式获取)

说明 CompletableFuture对象需要的SpringBoot版本为3.X.X以上&#xff0c;需要的kafka依赖版本为3.X.X以上&#xff0c;需要的jdk版本17以上。 1、阻塞式&#xff08;等待式&#xff09;获取生产者发送的消息 生产者&#xff1a; package com.power.producer;import org.ap…

【html+css 绚丽Loading】 000014 三元波动盘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

JVM系列--初始JVM

根据《黑马程序员JVM虚拟机入门到实战全套视频教程》整理 1 什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 Java源代码执行流程如下&#xff1a; 分为三个步…

代码随想录day52 101孤岛的总面积 102沉没孤岛 103水流问题 104建造最大岛屿

代码随想录day52 101孤岛的总面积 102沉没孤岛 103水流问题 104建造最大岛屿 101孤岛的总面积 代码随想录 #include <iostream> #include <vector>using namespace std; int count 0; int dir[4][2] {{1, 0}, {0, 1}, {-1 ,0}, {0, -1}};void dfs(vector<v…