Redis 为什么这么快,你知道 I/O 多路复用吗?

news2025/1/14 18:41:29

今天我们讨论一下面试高频题,为什么 Redis 那么快?
首先,你可以先想一下答案,我先说下大家普遍的答案:

  • 单线程
  • 基于内存操作,速度快
  • I/O 多路复用

相信很多人第一时间回答出来上面这些,那么面试官一般会接着问,所有的操作都是单线程吗?单线程为什么快呢,什么是 I/O 多路复用?很多人这个时候就会 G 了。

今天我们好好聊聊,首先我们要知道,我们常说的 Redis 是单线程,主要是指 Redis 在网络 I/O 和 键值的读写操作是有一个线程来完成的,但是其他的一些功能是由其他的线程来执行的,如:

  • 持久化数据落盘
  • 集群主从同步
  • 异步数据删除

所以严格来说,Redis 并不是单线程的。但是在面试中,我们可以先铺垫一下,如果面试官刨根问底,显然是不够的。

1. Redis 为什么用单线程

日常开发中,我们接触都更多是多线程,为了能够提升系统的请求数或者是吞吐率,我们会采用多线程来实现。看下图:

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

所以大家应该知道为啥 Redis 要用单线程了吧,我们接着来说说为什么单线程的 Redis 为啥能获得高性能的原因。

2. 单线程 Redis 为什么那么快

我们正常理解下,多线程在处理能力上是要高于单线程的,但是为啥 Redis 的单线程模型却能达到惊人的每秒 10 万级别的处理能力呢?(采用百度百科)

这就是 Redis 在设计上的优秀之处。

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

接下来就说说本文最重要的一个 I/O 多路复用机制。

3. I/O 多路复用模型

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

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

3.1 select

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

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

3.2 epoll

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

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

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

3.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 函数进行数据处理。

4. 总结

现在,我们知道啦,Redis 为什么快了吧。 Redis 单线程是指在网络 I/O 和 键值的读写操作是有一个线程来完成的,采用单线程的好处是避免了多线程并发需要竞争获取锁。单线程之所以性能高效是因为其选择了 I/O 多路复用模型。搞懂了 select/epoll 这这些,慢慢会发现自己会逐渐比身边的伙伴优秀一些。

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

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

相关文章

从开发角度读懂公司卫生间一直有人窜稀的原理

不知道你有没有这样的经历,一直忙忙碌碌,需求不断,当你终于解决完手头的事情,突然特别着急想要去卫生间的时候,仅有的几个门总是关着的,于是怀疑,可能其他人更需要这次机会,他们也一…

最基础的协同过滤介绍

文章目录1.到底什么是协同过滤2.协同过滤的一般步骤3.基于用户的CF (User-CF)3.1 基本介绍3.2 用户相似度3.2.1 用户相似度基本介绍3.2.2 用户相似度改进:ICU3.3 User-CF的缺点4.基于项目的CF (Item-CF)4.1 基本介绍4.2 用户相似度4.2.1 用户相似度基本介绍4.2.2 用…

xss-labs/level6

我们输入平常的payload如下 <script>alert(xss)</script> 界面回显如下 源代码如下所示 可以发现后台服务器对特殊字符进行插入操作 我们寄希望于后台不要插入下划线到onxxx关键字中 所以构造如下 " onclickjavascript:alert(xss)>// 由于界面没有回…

教程七 在Go中使用Energy创建跨平台GUI - Cookies

教程-示例-文档 介绍 本文介绍在energy中的cookie操作 在energy中可以对cookie的增加、修改和删除以达到某种目的 对cookie操作时&#xff0c;是以调用功能函数后触发事件的方式返回调用功能函数的结果 运行此示例&#xff0c;需要安装好Go和Energy开发环境&#xff1a;教…

有问题直接说问题,问什么在不在???

有什么问题可以直接说&#xff0c; 比如把你的项目地址、需求、错误复现步骤通过任何方式告诉我 比如&#xff1a; CSDN&#xff1a;发送消息&#xff0c;博客评论等&#xff0c;禁止发"在吗" 发邮件&#xff1a;xuxiaoweixuxiaowei.com.cn。 微信群&#xff1a; 禁…

麦芽糖-紫杉醇maltose-Paclitaxel

麦芽糖-紫杉醇maltose-Paclitaxel 中文名称&#xff1a;麦芽糖-紫杉醇 英文名称&#xff1a;maltose-Paclitaxel 别称&#xff1a;紫杉醇修饰麦芽糖&#xff0c;PTX-麦芽糖 还可以提供PEG接枝修饰麦芽糖&#xff0c;麦芽糖-聚乙二醇-紫杉醇,Paclitaxel-PEG-maltose,紫杉…

redis配置文件详解

一、概述 redis的配置文件中&#xff0c;有着许多说明和可配置项&#xff0c;了解它们能够更好的使用redis去解决开发中遇到的困难。 此配置文件基于linux下的redis-6.2.4版本。 二、单位换算描述-units 在配置文件开头就有这么一段&#xff1a; 这里描述了一些基本的度量…

信息流广告投放的技巧

随着互联网的发展&#xff0c;信息时代已经到来&#xff0c;信息流广告逐渐受到众多广告主的青睐。 做广告&#xff0c;不仅需要投入大量的精力&#xff0c;还需要一定的资金&#xff0c;花这么多&#xff0c;自然是要收获不错的收益。广告主在广告信息流的时候都追求高ROI&am…

蓝牙耳机什么牌子好?安卓蓝牙耳机性价比推荐

戴耳机所听到的音效是完全不同的&#xff0c;体验感也是完全不一样&#xff01;而有线的耳机戴起来一点也不方便&#xff0c;因此更多的人选择无线蓝牙耳机&#xff0c;但是很多新手发帖不知道蓝牙耳机啥牌子好&#xff1f;安卓手机的配置越来越好&#xff0c;深受大众的欢迎&a…

Python中的dump() 、load()和dumps()、loads()使用及示例

Python中的dump() 、load()和dumps()、loads() 结论&#xff1a; 1.不加s的标识对json文件的读写&#xff0c;将内存中值读取写入到json后缀文件&#xff0c;或者将json后缀文件中内容读取到内存 2.加了s的主要是字符串类型和其他数据类型的互转 JSON(JavaScript Object No…

KubeSphere 社区双周报 | KubeKey v3.0.2 发布 | 2022-11-24

KubeSphere 从诞生的第一天起便秉持着开源、开放的理念&#xff0c;并且以社区的方式成长&#xff0c;如今 KubeSphere 已经成为全球最受欢迎的开源容器平台之一。这些都离不开社区小伙伴的共同努力&#xff0c;你们为 KubeSphere 提出了很多建设性意见&#xff0c;也贡献了很多…

扫除知识共享障碍,天翎知识文档管理系统+群晖NAS一体化解决方案

编者按&#xff1a;知识共享是企业知识管理的重要模块&#xff0c;本文阐述了企业知识共享中常遇到的障碍&#xff0c;并指出知识文档管理系统可以帮助解决这些问题&#xff0c;而NAS与知识文档系统的结合更是锦上添花。 关键词&#xff1a;文档分类&#xff0c;版本管理&…

你想要知道的“全电发票接口”

老规矩&#xff0c;即使你看到此文前&#xff0c;你多少知道点“全电发票”的一些知识&#xff0c;这里方便那些还没得空抢先获取的知友小伙伴们梳理下相关知识点。 ** 一、全电发票具体的定义 ** 全电发票是国家税务总局随着金税四期推出的全国统一的电子发票服务平台&…

护眼台灯该怎么样选择?2022如何选择一款好的护眼台灯

随着社会的高度发展&#xff0c;人们的生活水平也渐渐得到提高&#xff0c;大家也慢慢开始在意平时生活中的健康问题了&#xff0c;比如眼睛健康就是一个很重要的点。现在的年轻人&#xff0c;尤其是青少年儿童&#xff0c;走在大街上普遍都能看见带着眼睛&#xff0c;近视情况…

B2B电子商务网站方案:为专用设备行业注入新动力,加快产业数字化转型升级

专用设备是指设备的结构、性能专门针对某一种或一类对象&#xff0c;实现一项或几项功能的工业&#xff0c;包括工程机械、光伏设备、锂电设备、3C设备、半导体设备等。近年来&#xff0c;受市场对专用设备的应用需求不断扩大、产业技术升级趋势加快等影响&#xff0c;我国专用…

段错误,虚拟内存,内存映射 CSAPP

相信写代码的或多或少都会遇到段错误&#xff0c;segmentation fault. 今天终于看到这里面的底层原理 参考&#xff1a; https://greenhathg.github.io/2022/05/18/CMU213-CSAPP-Virtual-Memory-Systems/18-Virtual-Memory-SystemsSimple memory system exampleAddress Trans…

Las Vegas 与回溯组合法解八皇后问题

八皇后问题&#xff0c;是一个古老而著名的问题&#xff0c;是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯贝瑟尔于1848年提出&#xff1a;在88格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上…

刷爆力扣之卡牌分组

刷爆力扣之卡牌分组 HELLO&#xff0c;各位看官大大好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天阿呆继续记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标签进行刷题&#xff0c;每个…

DDOS防护如何建设?

数字化转型发展也推动了云计算、人工智能、大数据、物联网等新一代信息技术应用普及&#xff0c;与此同时&#xff0c;新时代的发展也带来了新的网络威胁和新的安全需求。我们不难发现&#xff0c;近年网络攻击时间层出不穷&#xff0c;全球范围来看&#xff0c;企业因遭受网络…

quilt基本使用

一、简介 quilt是制作补丁和管理的工具。比如想用开源代码做一些项目&#xff0c;我们如果直接在开源代码里进行修改&#xff0c;等到下次开源代码升级后&#xff0c;我们再将我们修改的部分转移到新版本的开源代码中就需要进行大量的新旧版本对比工作。那如果我们将这些改动使…