关于redis单线程和IO多路复用的理解

首先,Redis是一个高性能的分布式缓存中间件。其复杂性不言而喻,对于Redis整体而言肯定不是只有一个线程。

我们常说的Redis 是单线程,主要是指 Redis 在网络 IO和键值对读写是采用一个线程来完成的,这也是 Redis 对外提供键值存储服务的核心流程。但对于 Redis 的其他功能来说,比如持久化、异步删除、集群数据同步等,其实都是由额外的线程执行的。
关于redis有几个基本的说辞:

 - 单线程
 - 基于内存操作,速度快
 - I/O 多路复用
 这里简单分析一下

单线程

单线程的优势:

  • 使用单线程可以避免频繁的上下文切换
  • Redis 中有各种类型的数据操作,甚至包括一些事务处理,如果采用多线程,还可能因为加锁导致软件复杂度提升,更有可能会因为加解锁,甚至出现死锁,造成的性能损耗,所以使用单线程反而性能会更好

其实是当出现多线程同时在操作一个共享的资源时,我们为了保证结果的正确性,我们需要有额外的开销来保证,如锁。当有锁出现了,我们就需要在考虑在什么时候需要获取锁,释放锁,其中就需要记录锁的状态,可想而知,性能就会下降。这就是多线程模式在面临高并发场景下共享资源的访问问题。

单线程为什么还可以这么快

 实现高性能的一个方面是 Redis 是基于内存操作,它内部高效的数据结构,如跳表,quicklist,listpack,哈希表等,还有就是 Redis 采用了 I/O多路复用机制,从而保障在网络 I/O 中能够高效的处理并发请求,实现高吞吐率。包括高版本中实行的网络IO异步化。这些都是是实现高性能的重要原因。

 I/O 多路复用模型

在 Linux 中,我们都知道 Linux 对文件的操作实际上就是通过文件描述符(fd),通过一个进程监听多个文件描述符,一旦某个文件描述符准备就绪,就会通知对应的程序响应并处理,这种通知的方式优势在于在单个时间内能够处理更多的链接。

Linux 中的 I/O 多路复用机制是指一个线程处理多个 IO 流,也就是我们通常说的 select/epoll。 在 Redis 单线中,允许在内核中同时存在多个监听文件描述符,内核会去监听在这上面的链接请求,一但有请求就会交给 Redis 线程处理,从而实现一个Redis 线程可以处理多个 IO 流。那么什么是 select、epoll?

1、 select

select 是一个函数,它支持最大的连接数是 1024 或者 2048,因为在 select 函数需要传入fd_set 参数,这个 fd_set 的长度取决于操作系统的位数 1024 或者 2048。

其中 fd_set 是一个 bitmap,当数据没有到缓冲区那么就是 0, 反之到了缓冲区就是 1。select 函数的功能是将 fd_set 遍历,判断标识位是否存在变化,若发生变化就发起中断处理。

2 、epoll

epoll 的首次提出是在 Linux 2.6 内核中,他是为了解决 select 的缺点。

它定义了 epoll_event 结构体来处理,解决 select 存在最大链接数的限制。epoll 不会遍历所有的文件描述符(fd),epoll 会将准备就绪的文件描述符维护在一块指定的空间内,每次从其中取出已经准备就绪的文件描述符进行处理,大大提高了性能。

这就是 select 和 epoll 的区别,想看具体的源码可以自行了解,这里只是简单的描述一下。

3 、Redis I/O 多路复用模型

在 Redis 中,其网络框架调用采用的是复用机制中的 epoll 机制,让内核监听文件描述符,此时 Redis 线程不会阻塞在某一个特定的监听或已连接的文件描述符,从而可以达到同时处理多个链接请求,提高并发性能。如下图,Redis I/O 多路复用模型:

 

为了当请求到达时会通知 Redis 线程, select/epoll 提供了基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数。

说说回调机制时如何高效的工作的。当 select/epoll 监测到有文件描述符请求到达时,会发出对应的事件处理,这些事件会被放到一个事件处理队列中,然后 Redis 会对事件进行处理。通过对队列进行轮询,可以提高 CPU 利用率。同时,Redis 在处理事件时,会调用其相应的事件处理函数,实现基于事件的回调。最终使得请求能够第一时间及时响应,再一步提升 Redis 的相应性能。

举个发起读数据的例子,更好的理解上面 Redis I/O 多路复用模型。

当程序发起 Accept 和 Read 事件时, Redis 线程会注册这 Accept 和 Get 事件 对应的回调函数。当 Linux 内核监听到有链接请求或者读数据的请求时,会触发 Accept 和 Read 事件,与此同时调用 Redis 的 Accept 和 Get 函数进行数据处理。

 事件处理流程的更新

Redis 4.0之前的事件处理流程

我们通过IO多路复用器监听来自客户端的socket网络连接,然后由主线程进行IO请求的处理以及命令的处理,所有操作都是线性的

Redis 4.0 之后加入Lazy Free机制

Redis 4.0 之前在处理客户端命令和IO操作时都是以单线程形式运行,期间不会响应其他客户端请求,但若客户端向Redis发送一条耗时较长的命令,比如删除一个含有上百万对象的Set键,或者执行flushdb,flushall操作,Redis服务器需要回收大量的内存空间,这事就会导致Redis服务阻塞,对于负载较高的缓存系统来说将会是个灾难。为了解决这个问题,在Redis 4.0版本引入了Lazy Free,目的是将慢操作异步化,这也是在事件处理上向多线程迈进了一步

Redis 6.0 之后将网络IO异步化

从以上的发展历程中,我们也能看出Redis 的瓶颈并不在CPU上,即使是单线程Redis也能做到很快的响应,除非是遇到个别极其耗时的命令,这一块我们的Redis也在4.0版本做出了优化,但是我们是不是能更进一步优化Redis呢?从上图中我们可以看出主线程不光处理大量的命令,还需要处理大量的网络IO,Redis6.0就是基于此,将IO操作交由其他线程处理

Redis6.0的多线程默认是禁用的,只使用主线程。如需开启需要修改redis.conf配置文件:io-threads-do-reads yes

开启多线程后,还需要设置线程数,否则是不生效的。

线程数一定要小于机器核数。线程数并不是越大越好,官方认为超过了 8 个基本就没什么意义了。

设置线程数,修改redis.conf配置文件: io-threads 6

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Zabbix6 使用Agent2实现证书监控的详细步骤

目标 我们的目标是通过获取网站的证书信息来实现网站证书监控。 使用agent2的key 只需使用其中的key,就能实现我们的目标功能。然而,由于它返回的是json格式的数据,我们需要根据数据来配置监控项目(item)和触发器&am…

从功能测试到测试开发,薪资翻倍,我整理的全网最全学习指南!

在这个吃技术的IT行业来说,我刚入行的时候每天做的也是最基础的工作,但是随着时间的消磨,我产生了对自我和岗位价值和意义的困惑。 一是感觉自己在浪费时间,另一个就是做了快2年的测试,感觉每天过得浑浑噩噩&#xff…

Mac查询本机ip地址

Mac系统版本和网络配置不同,可能会有一些细微差别。 一、 使用系统偏好设置 1、点击屏幕左上角的Apple图标,选择“系统偏好设置”。 2、点击“网络”。 3、 在左侧选择当前连接的网络(如Wi-Fi或以太网),在右侧界面&a…

Leetcode—73.矩阵置零【中等】

2023每日刷题&#xff08;六十六&#xff09; Leetcode—73.矩阵置零 空间复杂度为O(mn)版实现代码 class Solution { public:void setZeroes(vector<vector<int>>& matrix) {int rowLen matrix.size();int colLen matrix[0].size();vector<int> row…

【第七在线】可持续时尚与商品计划:减少库存浪费的方法

随着可持续时尚的崭露头角&#xff0c;服装企业越来越重视减少库存浪费。库存浪费不仅对环境造成负面影响&#xff0c;还对企业的经济可持续性产生负面影响。本文将深入探讨可持续时尚与商品计划之间的关系&#xff0c;以及一些减少库存浪费的方法&#xff0c;有助于改进商品计…

BearPi Std 板从入门到放弃 - 引气入体篇(11)(SPI驱动 TFT LCD(ST7789))

简介 SPI 驱动 ST7789V2 进行字符显示, 并且使用中文库显示中文信息。主芯片: STM32L431RCT6LED : PC13 \ 推挽输出即可 \ 高电平点亮串口: Usart1 / LPUARTSPI(与LCD数据传输) : SPI2LCD_RESET&#xff08;复位引脚&#xff09;: PC7 \ 推挽输出即可 LCD_POWER&#xff08;…

Java自动化测试系列[v1.0.0][常见页面操作处理]

[控制滚动] package util; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement;public class ScrollBarUtil {/*** 控制滚动条向下拉到底* param driver 浏览器驱动*/public static void toBottom…

简单了解一下当前火热的大数据 -- Kylin

神兽麒麟 一、Apache Kylin 是什么&#xff1f;二、Kylin架构结语 一、Apache Kylin 是什么&#xff1f; 由eBay公司中国团队研发&#xff0c;是一个免费开源的OLAP多维数据分析引擎优点 超快的响应速度&#xff0c;亚秒级支持超大数据集&#xff08;PB以上&#xff0c;千亿记…

这样使用云渲染又快又省钱

我们都知道使用云渲染是要钱的&#xff0c;而且渲染的时间越久&#xff0c;需要的渲染费越多&#xff0c;哪么如何又快又省钱的拿到效果图呢&#xff1f;用炫云的渲染质量&#xff0c;保准让你使用云渲染渲染效果图又快又省钱。 我们使用炫云的时候&#xff0c;根据自己的需求…

互联网加竞赛 python图像检索系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python图像检索系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c…

PIC单片机项目(7)——基于PIC16F877A的智能灯光设计

1.功能设计 使用PIC16F877A单片机&#xff0c;检测环境关照&#xff0c;当光照比阈值低的时候&#xff0c;开灯。光照阈值可以通过按键进行设置&#xff0c;同时阈值可以保存在EEPROM中&#xff0c;断电不丢失。使用LCD1602进行显示&#xff0c;第一行显示测到的实时光照强度&a…

BUUCTF-Linux Labs

Linux Labs 根据题目给出的内容&#xff0c;在kali中连接靶机&#xff0c;输入密码进入命令行模式 ls发现什么都没有&#xff0c;有可能进入到了一个空文件夹 cd .. 切换到上一层目录&#xff0c;ls查看此目录下的内容&#xff0c;发现flag.txt文件&#xff0c;查看文件是flag …

听GPT 讲Rust源代码--src/tools(22)

File: rust/src/tools/tidy/src/lib.rs rust/src/tools/tidy/src/lib.rs是Rust编译器源代码中tidy工具的实现文件之一。tidy工具是Rust项目中的一项静态检查工具&#xff0c;用于确保代码质量和一致性。 tidy工具主要有以下几个作用&#xff1a; 格式化代码&#xff1a;tidy工具…

Lang–Kobayashi方程实现混沌python实现混沌序列图像

Lang–Kobayashi方程描述为&#xff1a; 第一部分&#xff08;Drive laser&#xff09;是描述的驱动激光器&#xff0c;第二部分&#xff08;Response laser&#xff09;描述的是响应激光器。实验结构图如下&#xff1a; 虚线框表示响应激光器中的闭环配置。开环中响应激光器无…

beaglebone black狗板,交叉编译Qt5(eglfs)

1. 下载buildroot-2023.023.7版本 make beaglebone_qt5_defconfig 然后编译&#xff0c;出现错误大多数是因为下载不了包&#xff0c;用bing搜索找到放到对应的dl目录下&#xff0c;最终完成编译。 备注&#xff1a;用系统默认配置&#xff0c;不要参考网上的&#xff0c;网…

天津web前端就业培训班,Web机构选择重点

Web前端培训是目前非常热门的培训领域之一。很多领域都会涉及到web前端开发&#xff0c;比如传统互联网、房地产、金融、游戏、影视传媒等行业都需要web前端技术的支持。越来越多的企业和个人也需要建立自己的网站和移动应用程序&#xff0c;因此市场对web前端工程师的需求是非…

Docker 学习总结(80)—— 轻松驾驭容器,玩转 LazyDocker

前言 LazyDocker 是一个用户友好的命令行工具,简化了 Docker 的管理。它能够通过单一命令执行常见的 Docker 任务,如启动、停止、重启和移除容器。LazyDocker 还能轻松查看日志、清理未使用的容器和镜像,并自定义指标。 简绍 LazyDocker 是一个用户友好的 CLI 工具,可以轻…

Linux基本内容学习

Linux 命令 文件命令 命令释义语法格式lslist&#xff0c;用于显示目录中文件及其属性信息ls [参数名] [文件名]cdchange directory&#xff0c;用于更改当前所处的工作目录&#xff0c;路径可以是绝对路径&#xff0c;也可以是相对路径&#xff0c;若省略不写则会跳转至当前…

使用GitZip下载GitHub指定文件

目录 一、GitZip二、安装GitZip三、链接GitHub四、检验是否安装成功五、总结 一、GitZip GitZip是一个非常实用的浏览器插件&#xff0c;它主要有以下几个优点&#xff1a; 下载指定文件&#xff1a;在我们浏览Github时&#xff0c;如果只想下载某个子目录的内容&#xff0c;…

【爬虫软件】孔夫子二手书采集

项目演示 孔网爬取图书信息 目录结构 [ |-- api-ms-win-core-synch-l1-2-0.dll, |-- api-ms-win-core-sysinfo-l1-1-0.dll, |-- api-ms-win-core-timezone-l1-1-0.dll, |-- api-ms-win-core-util-l1-1-0.dll, |-- api-ms-win-crt-conio-l1-1-0.dll, |-- api…