linux redis客户端_为什么单线程Redis能那么快?

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

Redis 为什么用单线程?

多线程的开销

对于一个多线程的系统来说,在有合理的资源分配的情况下,可以增加系统中处理请求操作的资源实体,进而提升系统能够同时处理的请求数,即吞吐率。

87bfc4bce1049ce9bbc27223f5d5d148.png
线程数与系统吞吐率
  • 管理共享资源的开销

5bf96af6e8f0983e4f333ff037333f60.png
多线程并发访问Redis

采用多线程开发一般会引入同步原语来保护共享资源的并发访问,这也会降低系统代码的易调试性和可维护性。为了避免这些问题,Redis 直接采用了单线程模式。

单线程 Redis 为什么那么快?

  • Redis 的大部分操作在内存上完成
  • 采用了高效的数据结构
  • 采用了多路复用机制使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率

基本 IO 模型与阻塞点

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

c25f3466c86fdcf2112449ee11699b12.png
Redis基本IO模型

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

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

非阻塞模式

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

eb5d6a620e025bfca509e5f48422250c.png
Redis套接字类型与非阻塞设置

基于多路复用的高性能 I/O 模型

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

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

9a274cbbfc72548b92120885cd98d152.png
基于多路复用的Redis高性能IO模型

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

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

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

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

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

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

相关文章

servlet中文乱码处理

servlet中文乱码处理 如果是post设置req.setCharacterEncoding("utf-8");如果是get,不去修改服务器配置的情况下new String(name.getBytes("iso-8859-1"),"utf-8")数据库乱码?useUnicodetrue&characterEncodingUTF-8转载于:http…

C语言开发笔记(七)const和指针

const修饰变量是常用的&#xff0c;不容易犯错&#xff0c;而const和指针一起使用时很容易混淆。 (一)const int *p #include <stdio.h>int main(void) {int a 10;int b 20;const int *p &a;*p b;return 0; } const在int *的左侧&#xff0c;即指针指向内容为…

从JavaFX 1.3迁移到JavaFX 2.0

几天前&#xff0c;我完成了将Modellus的源代码从JavaFX 1.3脚本迁移到JavaFX 2.0 Java语言的过程。 因此&#xff0c;我认为写关于我在此过程中学到的知识会很好。 我想指出&#xff0c;如果您想继续在JavaFX 2.0中使用JavaFX脚本&#xff0c;则可以使用Visage&#xff1a; ht…

九度OJ 1034:寻找大富翁 (排序)

时间限制&#xff1a;1 秒 内存限制&#xff1a;32 兆 特殊判题&#xff1a;否 提交&#xff1a;5925 解决&#xff1a;2375 题目描述&#xff1a;浙江桐乡乌镇共有n个人,请找出该镇上的前m个大富翁.输入&#xff1a;输入包含多组测试用例.每个用例首先包含2个整数n&#xff08…

ubuntu php 无法执行exec_利用webhook使php项目自动部署

php中文网最新课程每日17点准时技术干货分享1.先来讲一下自动部署的原理&#xff0c;一般在我们push代码的时候&#xff0c;可以自动请求webhook中设置的url&#xff0c;完成一次请求与响应。那么只要我们设置的url地址请求的php文件内容是执行命令行git push命令&#xff0c;则…

android-verticalseekbar——Android可视化SeekBar类库

android-verticalseekbar——Android可视化SeekBar类库转载于:https://www.cnblogs.com/zhujiabin/p/5706246.html

C语言开发笔记(八)static

在C语言中&#xff0c;static有3个作用&#xff1a; &#xff08;1&#xff09;在函数体&#xff0c;一个被声明为静态的变量在这一函数体内被调用的过程中维持其值不变。 #include <stdio.h>void test(void) {static int i 0;printf("%d\n", i); }int main…

ppt修复无法读取_移动硬盘故障分析以及建议修复方法

移动硬盘中存储了大量的重要数据&#xff0c;一旦出现什么问题&#xff0c;会让人急得焦头烂额。换个硬盘倒是件小事&#xff0c;但其中资料、数据的丢失更令人懊恼。而在硬盘使用的过程中&#xff0c;由于使用者一时的不注意&#xff0c;往往就很容易造成意外的问题。接下来&a…

(原创)c#学习笔记04--流程控制01--布尔逻辑03--运算符优先级

转载于:https://www.cnblogs.com/wodehao0808/p/4896018.html

一些定义–测试技术9

我认为我即将结束有关测试技术的博客系列&#xff0c;感觉好像已经过去了。 对我来说更清楚的一件事是&#xff0c;测试方法仍处于起步阶段&#xff0c;因此是开发人员之间争执或讨论的明确来源&#xff0c;这是一件好事。 我怀疑我们正处于职业发展史上的某个时刻&#xff0c;…

百度谷歌面试题目

全新整理&#xff1a;微软、谷歌、百度等公司经典面试100题[第101-160题] 整理:July、二零一一年三月九日。应网友承诺与要求&#xff0c;全新整理。转载&#xff0c;请注明出处。博主说明&#xff1a;此100题V0.2版&#xff0c;本人不再保证&#xff0c;还会提供答案。-------…

C学习杂记(三)笔试题:字符串大小写字母切换

字符串大小写转换&#xff0c;大写转小写&#xff0c; 小写转大写 #include <stdio.h> #include <string.h>int tramsform(char str[]) {int i 0;int strLen strlen(str);for(i 0; i < strLen; i){if( (str[i] > A) && (str[i] < Z) ){str[i]…

m.2接口和nvme区别_NVMe/SATA SSD有啥不一样?萌新怎么选

随着NAND技术的升级迭代&#xff0c;堆栈层数不断提高使得SSD单位容量成本不断下降&#xff0c;消费级市场基本已经成为了SSD的天下。目前主流的SSD大致有两种接口&#xff0c;分别是M.2和SATA两种类型。NVMe/SATA有啥区别SATA接口的SSD执行的AHCI协议标准&#xff0c;是目前较…

javascript 高级特性探讨A4-A5(call和原型.对象复制)

在js中&#xff0c;call和apply是二个神奇的方法&#xff0c;但同时也是容易令人迷惑的二个方法&#xff0c;call和apply的功能是以不同的对象作为上下文来调用某个函数的&#xff0c;简而言之&#xff0c;就是允许一个对象去调用另一个对象的成员函数&#xff0c;咋一看似乎很…

带有NetBeans 7.1 RC 2的WebLogic 12c快速入门

WebLogic服务器12c停运了几天。 它是针对“裸露”的Java开发人员的–花哨的Fusion Middleware东西将继续沿线升至12c。 因此&#xff0c;这基本上是我要运行的版本。 今天&#xff0c;我为您提供了一个最新的NetBeans 7.1&#xff08;RC 2&#xff09;和WebLogic的快速入门 &am…

C学习杂记(四)sizeof计算联合体大小

#include <stdio.h>union u1 {char a[13];int b; };int main(void) {printf("%d\n", sizeof(u1));return 0; } 结果为16。 联合体的大小取决于它所有的成员中占用空间最大的一个成员的大小。u2最大的空间是char[13]&#xff0c;但是因为另一个成员int b的存在…

python爬虫反爬机制_Python Scrapy突破反爬虫机制(项目实践)

对于 BOSS 直聘这种网站&#xff0c;当程序请求网页后&#xff0c;服务器响应内容包含了整个页面的 HTML 源代码&#xff0c;这样就可以使用爬虫来爬取数据。但有些网站做了一些“反爬虫”处理&#xff0c;其网页内容不是静态的&#xff0c;而是使用 JavaScript 动态加载的&…

树的算法 已知二叉树的前序序列和中序序列求解树

题目: 已知二叉树的前序序列和中序序列求解树 比如 6 4    8 3  5   7 前序序列为6,4,3,5,8,7 中序序列为3,4,5,6,7,8 思路: 前序遍历序列的第一个元素必为根节点 则中序遍历序列中&#xff0c;该节点之前的为左子树&#xff0c;该节点之后的为右子树&#xff0c;若该节…

使用Spring配置LogBack日志记录

LogBack是由Log4j的同一作者创建的用于记录日志的API&#xff08;较新的实现&#xff0c;它类似于新版本&#xff09;&#xff0c;在本文中&#xff0c;我将展示如何在Spring项目中对其进行集成和使用。 在本教程中&#xff0c;我假设您正在使用一个简单的Spring ROO项目&…

自定义URL Scheme完全指南

iPhone / iOS SDK 最酷的特性之一就是应用将其自身”绑定”到一个自定义 URL scheme 上&#xff0c;该 scheme 用于从浏览器或其他应用中启动本应用。 注册自定义 URL Scheme 注册自定义 URL Scheme 的第一步是创建 URL Scheme — 在 Xcode Project Navigator 中找到并点击工程…