redis为什么那么快?结论有三点,大家都知道,这里主要是分析。

首先第一点

redis是内存访问的,所以快

当然这个大家都知道,所以不是重点

io密集型和cpu密集型

一般我们把任务分为io密集型和cpu密集型

io密集型

  • IO密集型指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高。
  • 对于io密集型的任务,它的主要时间都在磁盘io上,而io本身在发出中断告知cpu后,cpu只需要短暂的处理一下,之后就由DMA(详见附录)负责数据传输,整个过程对cpu的利用率很低。因此我们需要开更多的线程去充分利用cpu。即一般线程数 = cpu核心数 * 2,如数据库连接池

cpu密集型

  • CPU密集型也叫计算密集型,指的是系统的硬盘、内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高。
  • 对于cpu密集型的任务,它对cpu的利用率很高,所以不需要开更多的线程去提高cpu利用率。假如增加线程,只会引起线程的频繁切换导致本来就不够用的cpu更加不够用。所以一般是线程数 = cpu核心数 + 1

redis的瓶颈在哪里

redis基本都在进行内存io,那它的瓶颈在io上吗?

redis在网络io上使用epoll实现了一个io多路复用的reactor模型,epoll是非阻塞io,所以避免了cpu阻塞在io上,所以它不是io密集型,瓶颈不在于等待io导致cpu利用率不高,不需要多个线程来屏蔽等待io执行完成的时间。当然redis的io利用率很高,但是io利用率高并不代表它是io密集型,因为它瓶颈不在等待io上。

所以第二点

redis在网络io上使用epoll实现了一个io多路复用的reactor模型使得cpu利用率更高,浪费在io上的时间更少

redis并不需要多线程来提高cpu利用率减少io等待时间,并且单线程架构也比较容易实现,所以顺理成章就采用了单线程架构。

关于epoll可以看我的这篇文章:https://www.cnblogs.com/fatmanhappycode/p/12362423.html

第三点

由于采用了单线程架构,避免了线程线程切换产生的消耗

因为一次CPU上下文的切换大概在 1500ns 左右。

从内存中读取 1MB 的连续数据,耗时大约为 250us,假设1MB的数据由多个线程读取了1000次,那么就有1000次时间上下文的切换,

那么就有1500ns * 1000 = 1500us ,我单线程的读完1MB数据才250us ,你光时间上下文的切换就用了1500us了,我还不算你每次读一点数据 的时间

那么redis是cpu密集型吗?答案是否定的。

redis也不是cpu密集型。大多数情况下redis机器上的cpu是很够用的。

redis的瓶颈在于内存大小和网络带宽。

如果想要更充分的利用多核cpu,可以采用多个redis实例的方法,同时为了减少线程争用,可以将实例和cpu绑定的方法。

但是如果做了CPU绑定,在rdb和aof时子进程会与父进程共享使用一个CPU。子进程重写时对单核CPU使用率通常在90%以上,父进程与子进程将产生激烈CPU竞争,极大影响Redis稳定性。(解决方法不清楚,也许多绑定一个CPU会好点?)

附录

DMA

DMA 传输将数据从一个地址空间复制到另外一个地址空间。当CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成。

典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。例如内存移到磁盘。

最后惯例附一图:

关于redis单线程的分析的更多相关文章

  1. Redis时延问题分析及应对

    Redis时延问题分析及应对 Redis的事件循环在一个线程中处理,作为一个单线程程序,重要的是要保证事件处理的时延短,这样,事件循环中的后续任务才不会阻塞: 当redis的数据量达到一定级别后(比如 ...

  2. Redis单线程架构以及工作方式

    一.单线程模型 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程.其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的每一条到达服务端的命令都不会 ...

  3. 理解Redis单线程运行模式

    本文首发于:https://mp.weixin.qq.com/s/je4nqCIq6ARhSV2V5Ymmtg 微信公众号:后端技术指南针 0.概述 通过本文将了解到以下内容: Redis服务器采用单 ...

  4. Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

    小结: 1.在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况:2.Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一 ...

  5. ELK_elk+redis 搭建日志分析平台

    这个是最新的elk+redis搭建日志分析平台,今年时间是2015年9月11日. Elk分别为 elasticsearch,logstash, kibana 官网为:https://www.elast ...

  6. linux下利用elk+redis 搭建日志分析平台教程

    linux下利用elk+redis 搭建日志分析平台教程 http://www.alliedjeep.com/18084.htm   elk 日志分析+redis数据库可以创建一个不错的日志分析平台了 ...

  7. Redis事务的分析及改进

    Redis事务的分析及改进 Redis的事务特性 数据ACID特性满足了几条? 为了保持简单,redis事务保证了其中的一致性和隔离性: 不满足原子性和持久性: 原子性 redis事务在执行的中途遇到 ...

  8. redis超时问题分析

    redis超时问题分析 06/04. 2014 Redis在分布式应用中占据着越来越重要的地位,短短的几万行代码,实现了一个高性能的数据存储服务.最近dump中心的cm8集群出现过 几次redis超时 ...

  9. Redis事务原理分析

    Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...

随机推荐

  1. MySQL InnoDB表的碎片量化和整理(data free能否用来衡量碎片?)

    网络上有很多MySQL表碎片整理的问题,大多数是通过demo一个表然后参考data free来进行碎片整理,这种方式对myisam引擎或者其他引擎可能有效(本人没有做详细的测试).对Innodb引擎是 ...

  2. 使用WireShark进行网络流量安全分析

    WireShark的过滤规则 伯克利包过滤(BPF)(应用在wireshark的捕获过滤器上) ** 伯克利包过滤中的限定符有下面的三种:** Type:这种限定符表示指代的对象,例如IP地址,子网或 ...

  3. iOS开发:十六进制颜色转UIColor

    Objective-C UIColor * __nullable UIColorFromHexValue(NSUInteger hexValue) { CGFloat red = (hexValue ...

  4. C# 在DataGridView中,点击单元格调出 TreeView控件 或 ListBox控件

    1.调出 TreeView控件 或  ListBox控件 private void deductGrid1_CellClick(object sender, DataGridViewCellEvent ...

  5. Java第十三周实验作业

    实验十三  图形界面事件处理技术 实验时间 2018-11-22 1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: 事件源:能够产生事件的对象都可以成为事件源,如文本框.按钮等,一个事 ...

  6. NDCG的理解

    2019-05-29 14:15:44

  7. java基本数据类型和引用数据类型的调用传递的区别

    (1)基本数据类型:就是进行了值的传递把一份数据拷贝了之后传递过去 (2)引用数据类型:实际上也是进行了数据拷贝然后传过去,实际上也是值传递,只不过传递过去的值和原有的值指向了同一个对象 所以在调用的 ...

  8. Java网络编程——Socket

    网络是连接不同计算机的媒介,不同的计算机依靠网络来互相通信,即传递数据. Java中与网络编程相关的部分主要是Socket(套接字),它作为一种抽象的结构,实现了与通信相关的各类方法,构成一套完整的通 ...

  9. shell脚本介绍以及常用命令

    Shell脚本 Shell Script,Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的 ...

  10. pywin32解析office文档

    from win32com.client import Dispatch xlApp = Dispatch("Excel.Application") xlApp.Visible = ...