当前位置: 首页 > news >正文

高性能IO模型:为什么单线程Redis能那么快?

        我们通常说Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的。这也是Redis对外提供键值存储服务的主要流程。

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

Redis为什么用单线程?

  1. 多线程的开销会比较大,针对一些复杂的操作,需要考虑:多线程编程模式面临的共享资源并发访问控制问题
  2. 对于并发访问控制,如果只是采用粗粒度的互斥锁,那么即时增大了线程,也会导致大部分线程在等待获取访问共享资源的互斥锁,并行边串行,系统吞吐率并没有随着线程的增加而增加。
  3. 而且采用多线程开发一般会引入原语来保护共享资源的并发访问,这也会降低代码的易调试性和可维护性。

为了避免这些问题。redis直接采用了单线程模式。

单线程Redis为什么那么快

redis能使用单线程模型达到每秒数十万级别的处理能力,这是因为Redis多方面设计选择的一个综合结果:

  • redis大部分操作在内存上完成
  • 采用高效的数据结构,例如哈希表和跳表,他是实现高性能的一个重要原因。
  • 采用多路复用机制,使其在网络IO操作中能并发处理大量的客户端请求,实现高吞吐率。

在学习多路复用之前,要弄明白网络操作的基本IO模型和潜在的阻塞点。毕竟redis是采用单线程进行IO,如果线程被阻塞了,就无法进行多路复用了。

基本IO模型与阻塞点

simpleKV,最基本的一种实现是在一个线程中依次执行一系列操作。

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

redis基本IO模型

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

        这就导致redis整个线程阻塞,无法处理其他客户端请求,效率很低。幸运的是,socket网络模型本身支持非阻塞模式

非阻塞模式

        想要使用socket的非阻塞模式,就必须要了解三个函数的调用返回类型和设置模式。

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

 redis套接字类型与非阻塞设置

         针对监听套接字,可以设置非阻塞模式:当redis调用accept()但一直未有连接请求到达时,redis线程可以返回处理其他操作,而不用一直等待。但要注意的是,调用accept()时,已经存在监听套接字了。

        虽然redis线程可以不用一直等待,但是总得有机制继续在监听套接字上等待后续连接请求,并在有请求是通知redis。

        类似的我们可以针对已连接套接字设置非阻塞模式:redis调用recv()后,如果已连接套接字上一直没有数据到达,redis同样可以返回处理其他操作。我们也需要有机制继续监听该已连接套接字,并在有数据达到时通知redis。

        这样才会保证redis线程,既不会像基本IO模型中一直在阻塞点等待,也不会导致redis无法处理实际到达的连接请求或数据。

        到此,可以继续了解linux上的IO多路复用机制。

基于多路复用的高性能IO模型

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

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

基于多路复用的Redis高性能IO模型

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

        那么回调机制是怎么工作的呢?select/epoll一旦检测到FD上有请求到达时,就会触发响应的事件。

        这些事件会被放入到一个事件队列,redis单线程对这个事件队列不断进行处理。这样一来,redis无需轮询是否有请求实际发生,这就可以避免造成CPU资源浪费。同时,redis在对事件队列中的时间处理时,会调用相应的处理函数,这就实现了基于事件的回调。因为redis一直在对事件队列进行处理,所以能及时响应客户端请求,提升redis的响应性能。

以连接请求和读数据请求为例,具体解释:

        这两个请求分别对应accept事件和read事件,redis分别对这两个事件注册accept和get回调函数。当Linux内核监听到连接请求或者读数据请求时, 就会触发Accept事件和Read事件,此时,内核就会回调Redis响应的accept和get函数进行处理。

        这就像病人去医院看病。在医生实际诊断前,每个病人(等同于请求)都需要先分诊、测体温、登记等。如果这些工作都由医生来完成,医生的工作效率就会很低。所以,医院都设置了分诊台,分诊台会一直处理这些诊断前的工作(类似于Linux内核监听请求),然后再转交给医生做实际诊断。这样即使一个医生(相当于redis单线程),效率也能提升。

        需要注意的是,即使你的应用场景中部署了不同的操作系统,多路复用机制也是适用的。因为这个机制的实现有很多种,既有基于Linux 系统下的 select 和 epoll 实现,也有基于 FreeBSD 的 kqueue 实现,以及基于 Solaris 的 evport 实现,这样,你可以根据 Redis 实际运行的操作系统,选择相应的多路复用实现。

小结

        重点三个问题:redis真的只有单线程吗?、为什么用单线程?、单线程为什么这么快?

        现在我们知道了,redis单线程是指它对网络IO和数据读写的操作采用了单线程,而采用单线程的一个核心原因是避免多线程开发的并发控制问题。单线程的redis能高性能,跟多路复用的IO模型密切相关,因为这避免了accept()和send()/resc()潜在的网络IO操作阻塞点。

        另外redis的单线程是针对redis 5.0版本之前的。redis6.0中提出了多线程模型。

资料:03 高性能IO模型:为什么单线程Redis能那么快?.md

相关文章:

高性能IO模型:为什么单线程Redis能那么快?

我们通常说Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的。这也是Redis对外提供键值存储服务的主要流程。 但redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。 Redis为什么用单线…...

【数据集】中国各类水文专业常用数据集合集

1 水文气象数据 1.1 中国站点尺度天然径流量估算数据集(1961~2018年) 论文: J2022-High-quality reconstruction of China’s natural streamflow-缪驰远(北京师范大学地理科学学部) 研究内容&#xff1a…...

落枕、肩颈酸痛,用磁疗就可缓解!

睡觉之前还是好好的,一觉醒来脖子莫名疼痛,转都转不了,有时候连肩膀和上肢都难受,很可能是“落枕”了。 落枕引起的肩颈疼痛与多种因素有关,如颈肩部肌肉的过度使用、不良的睡眠姿势或颈肩部受寒湿空气的侵袭&#xff…...

一文教会你如何选择远程桌面(五大主流远程软件全面讲解)

写在前面 作为程序员的我们,随时随地写代码改代码是我们的日常。刚回到家,就被老板、产品经理cue是常有的事。基于这种情况,一般都会随身携带电脑,随时备战,不过每天背着电脑上下班非常不方便。因此资深程序员的解决方…...

【yolov5】yolov5训练自己的数据集全流程----包含本人设计的快速数据处理脚本

关于yolo应用时能用到的脚本集合,推荐收藏: https://chenlinwei.blog.csdn.net/article/details/127299428 1. 工程化快速yolo训练流程指定版(无讲解) 1.1 抽样数据集xml转txt输出量化分析 python make_dataset.pymake_dataset…...

leaflet 加载CSV数据,显示图形(代码示例046)

第046个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载CSV文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共74…...

百趣代谢组学资讯:槟榔的基因组为雌雄同株植物的性别决定提供见解

文章标题:The genome of Areca catechu provides insights into sex determination of monoecious plants 发表期刊:New Phytologist 影响因子:10.323 作者单位:海南大学 百趣生物提供服务:植物激素高通量靶标定…...

SSO单点登录 - 多系统,单一位置登录,实现多系统同时登录 学习笔记

(1)单点登录 多系统的前提下,单一位置的登录,会实现多系统同时登录的一种技术。 常出现在互联网应用和企业级平台中 如:京东 单点登录一般是用于互相授信的系统,实现单一位置登录,全系统有效的。 注意&#xff1a…...

图解LeetCode——剑指 Offer 32 - III. 从上到下打印二叉树 III

一、题目 请实现一个函数按照之字形顺序打印二叉树,即:第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。 二、示例 2.1> 示例1 提示: …...

【快排与归并排序算法】

作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下🐾 文章目录一、快速排序 ( Quick Sort )二、归并排序 ( Merge Sort )总结一、快速排序 ( Quick Sort ) 1.思路 找出一个分界点,随机的调整区间…...

面试官问我:说说你对JMM内存模型的理解?为什么需要JMM?

点个关注,必回关 随着CPU和内存的发展速度差异的问题,导致CPU的速度远快于内存,所以现在的CPU加入了高速 缓存,高速缓存一般可以分为L1、L2、L3三级缓存。基于上面的例子我们知道了这导致了缓存一致 性的问题,所以加入…...

工程管理系统源码之提高工程项目管理软件的效率

高效的工程项目管理软件不仅能够提高效率还应可以帮你节省成本提升利润 在工程行业中,管理不畅以及不良的项目执行,往往会导致项目延期、成本上升、回款拖后,最终导致项目整体盈利下降。企企管理云业财一体化的项目管理系统,确保…...

SpringBoot集成xxl-job实现

SpringBoot集成xxl-job实现 一、xxl-job介绍 xxl-job是一个分布式任务调度平台,核心设计目标是开发迅速、学习简单、轻量级、易扩展。源码:下载地址编译环境:Maven3、Jdk1.8、MySQL5.7 二、调度中心 初始化调度数据库,执行指定…...

欧几里得度量和余弦度量的可取消生物识别方案

欧几里得度量和余弦度量的可取消生物识别方案 便捷的生物识别数据是一把双刃剑,在为生物识别认证系统的繁荣铺平道路的同时,也带来了个人隐私问题。为了缓解这种担忧,提出了各种生物特征模板保护方案来保护生物特征模板免于信息泄露。现有提案…...

平板作为主机扩展屏的实现

网上有许多教程使用平板作为电脑的拓展屏,但是多数都是需要在电脑和平板上都装上服务器和客户端的软件才行,而且有些系统还没有对应的软件。 那有没有一种方法只需要在主机上运行一个软件,而平板上只需要扫个码就行呢? 答案是当然…...

HTTP和HTTPS有什么区别?如何实现网站的HTTPS?

细心的朋友会发现,我们在浏览网站时,有的网址以http开头,而有的网站却以https开头,那这两者之间有什么区别吗?http的网站如何能变成https呢?本文中科三方针对这个问题做下简单介绍。 什么是http&#xff1…...

Rockstar Games遭黑客攻击,《侠盗猎车手6》90个开发视频外泄

当地时间9月19日,视频游戏开发商Rockstar Games证实,其 热门游戏《侠盗猎车手6》(Grand Theft Auto)开发片段遭到黑客大规模窃取 ,这一泄露事件立即在游戏圈迅速传播。 据报道, 上周末黑客至少泄露了90个游…...

RabbitMQ-客户端源码之AMQPImpl+Method

AMQPImpl类包括AMQP接口(public class AMQImpl implements AMQP)主要囊括了AMQP协议中的通信帧的类别。 这里以Connection.Start帧做一个例子。 public static class Connection {public static final int INDEX 10;public static class Startextends…...

雅思经验(7)

我发现雅思阅读要命的不是难度,而是时间的把控。考试时间是总共一小时,但是要写三篇文章,之后总共40道题目,也就是说每篇文章平均是13.3道。但是他们很多人说,如果誊写答案需要花掉3、4分钟每篇,也就是说真…...

Ubuntu20.04 用 `hwclock` 或 `timedatectl` 设置RTC硬件时钟为本地时区

Ubuntu20.04用 hwclock 或 timedatectl 设置硬件时区为本地时区 可以用hwclock命令 sudo hwclock --localtime --systohc👆效果等同👇 , --localtime的简写是-l ; --systohc的简写是-w sudo hwclock -l -w也可以用timedatectl命令 👆效果等…...

大学物理·第15章【量子物理】

黑体 斯特藩玻耳兹曼定律 维恩定律 光电效应 在光照射下 ,电子从金属表面逸出的现象,叫光电效应. 逸出的电子,叫光电子 经典理论: 光电流值与入射光强成正比截止频率(红限)v0对某种金属来说,只有…...

2010-2019年290个地级市经济发展与城市绿化数据

2010-2019年290个地级市经济发展与城市绿化数据 1、时间:2010-2019年 2、来源:城市统计NJ,缺失情况与NJ一致 3、范围:290个地级市 4、指标: 综合经济:地区生产总值、人均地区生产总值、地区生产总值增…...

【CSS 布局】-多列布局

一、两列布局 两列布局&#xff1a;一列定宽(也有可能由子元素决定宽度)&#xff0c;一列自适应的布局。 创建一个父盒子&#xff0c;和子盒子 <div class"container clearfix"><div class"left ">定宽</div><div class"right…...

从C语言向C++过渡

文章目录前言1.命名空间1.域的概念2.命名空间的使用2.C输入&输出3.缺省参数1.概念2.分类3.注意事项4.函数重载5.引用1.概念2.使用注意事项3.引用使用场景4.指针和引用的区别6.内联函数7.auto关键字8.nullptr前言 C被成为带类的C,本文由C语言向C过度&#xff0c;将会初步介…...

Matter 研讨会回顾(第三期)|乐鑫 Matter 免开发方案与证书服务介绍

1 月 17 日&#xff0c;乐鑫举办了以“乐鑫 Matter 免开发方案与证书服务介绍”为主题的第三期 Matter 线上研讨会&#xff0c;介绍乐鑫开箱即用的 ESP-ZeroCode 模组及其免开发 Matter 方案&#xff0c;以及证书生成和预配置相关服务。欢迎观看研讨会的视频回放了解详情。&…...

函数栈帧的创建和销毁——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰来为大家介绍一个知识点——函数栈帧的创建和销毁。其实这个知识点&#xff0c;我们很早之前就要讲&#xff0c;但是因为我的一系列原因&#xff0c;才一直拖到了现在&#xff0c;那么&#xff0c;话不多说&#xff0c;让我们一起…...

腾讯云对象存储+企业网盘 打通数据链“最后一公里

对云厂商和企业用户来说&#xff0c;随着数据规模的快速增长&#xff0c;企业除了对存储功能和性能的要求不断增加&#xff0c;也越来越注重数据分发的效率。在传统数据分发的过程中&#xff0c;数据管理员往往需要先在存储桶下载对应的客户方案/交付资料&#xff0c;再使用微信…...

在浏览器输入url到发起http请求,这过程发生了什么

当用户输入url&#xff0c;操作系统会将输入事件传递到浏览器中&#xff0c;在这过程中&#xff0c;浏览器可能会做一些预处理&#xff0c;比如 Chrome 会根据历史统计来预估所输入字符对应的网站&#xff0c;例如输入goog&#xff0c;根据之前的历史发现 90% 的概率会访问「ww…...

PyTorch学习笔记:nn.ReLU——ReLU激活函数

PyTorch学习笔记&#xff1a;nn.ReLU——ReLU激活函数 torch.nn.ReLU(inplaceFalse)功能&#xff1a;逐元素应用ReLU函数对数据进行激活 函数方程&#xff1a; ReLU(x)(x)max⁡(0,x)ReLU(x)(x)^\max(0,x) ReLU(x)(x)max(0,x) 输入&#xff1a; inplace&#xff1a;是否改变输…...

同步线程

↵ 由于这节内容资料比较少&#xff0c;所以以下内容总结自Qt官方文献&#xff0c;在文章最后会给出相应链接。 线程的目的是允许并行运行&#xff0c;但有时线程必须停止等待其他线程。例如&#xff0c;如果两个线程尝试访问同一个变量&#xff0c;这样的话结果是未定义的。强…...

WordPress企业显示/江苏seo和网络推广

"""1.三级菜单 注册 登陆 注销2.进入每一个一级菜单&#xff0c;都会有下一级的菜单"""user_item dict()try:while True:print(-------Welcome sir-------)input_choice int(input(Please enter your choice:1:Registration 2:login 3:logout:…...

个人装修队/武汉排名seo公司

这是一道区间贪心的题目&#xff0c;对于这道题&#xff0c;由于岛屿的位置在坐标轴上是确定的&#xff0c;而雷达的位置及数量则无法确定&#xff0c;因此我们可以根据岛屿来确定雷达的位置及数量。首先&#xff0c;我们可以根据岛屿的位置以及雷达的半径来确定覆盖该岛屿的雷…...

兼职做页面的网站/谷歌排名优化

InnoDB中的多版本并发控制&#xff08;MVCC&#xff09; MVCC (Multiversion Concurrency Control),多版本并发控制。 顾名思义, MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之,就是为了查询一…...

禹州做网站/互动营销的方式有哪些

Go语言连接Oracle首先交代一下运行环境和工具版本&#xff1a;WIN10MINGW64ORACLEINSTANCCLIENT_18_3 x64Jetbrins Goland编译阶段:1. exec: "gcc": executable file not found in %PATH%2. exec: "pkg-config": executable file not found in %PATH%3. ca…...

成都免费建站/万网的app叫什么

&#x1f447;&#x1f447;关注后回复 “进群” &#xff0c;拉你进程序员交流群&#x1f447;&#x1f447;来源丨新智元https://mp.weixin.qq.com/s/IXpWSnbNczpACoJ8JVxEPQ新智元报道 编辑&#xff1a;袁榭 好困【新智元导读】苹果的产品发布会将近&#xff0c;从果粉顾客…...

芜湖网站建设推广/网络推广网站有哪些

有序数组的 Two Sum两数平方和反转字符串中的元音字符回文字符串归并两个有序数组判断链表是否存在环最长子序列 双指针主要用于遍历数组&#xff0c;两个指针指向不同的元素&#xff0c;从而协同完成任务。 有序数组的 Two Sum Leetcode &#xff1a;167. Two Sum II - Inpu…...