官网的说法



我们先来认真看一下官网的说法。翻译过来大意如下:

CPU并不是您使用Redis的瓶颈,因为通常Redis要么受内存限制,要么受网络限制。例如,使用在一般Linux系统上运行的流水线Redis每秒可以发送一百万个请求,因此,如果您的应用程序主要使用O(N)或O(log(N))命令,则几乎不会使用过多的CPU 。

但是,为了最大程度地利用CPU,您可以在同一服务器上启动多个Redis实例,并将它们视为不同的服务器。在某个时候,单个实例可能还不够,因此,如果您要使用多个CPU,则可以开始考虑更早地分片的某种方法。

但是,在Redis 4.0中,我们开始使Redis具有更多线程。目前,这仅限于在后台删除对象,以及阻止通过Redis模块实现的命令。对于将来的版本,计划是使Redis越来越线程化。

既然redis的瓶颈不是cpu,那么在单线程可以实现的情况下,自然就使用单线程了。

自己的解读

我们知道redis是基于内存的。那么我们接下来要了解一个问题多线程cpu和内存直接操作差多少?

多线程操作就是使用多个cpu模拟多个线程,对redis进行操作。这样会造成一个巨大的问题,就是cpu的上下文切换问题。cpu的上下文切换的效率比直接在内存中进行读取差的很多。redis使用单个cpu绑定一个内存,针对内存的处理就是单线程的,这样避免了上下文的切换,所以非常的快。

一次cpu的切换时间大约是1500ns。从内存中读取1mb的连续数据,耗时大约是250us。如果1mb的数据被多个线程读取了1000次。那么就是有1000次时间的上下文切换。于是就是1500ns*1000=1500us。结果显而易见。1500us和250us差的还是很多的。

那么redis采取单线程还避免了很多问题。如果redis使用多线程来进行,那么就要考虑多线程带来的数据安全问题,如果我们在操作redis的list,hash等数据结构的时候。多线程就可能存在数据不安全的情况,这是就要加锁。一旦加锁就影响了程序的执行速度。

磁盘读取和内存读取的区别

【IOPS(Input/Output Operations Per Second)是一个用于计算机存储设备(如硬盘(HDD)、固态硬盘(SSD)或存储区域网络(SAN))性能测试的量测方式】

【吞吐量是指对网络、设备、端口、虚电路或其他设施,单位时间内成功地传送数据的数量(以比特、字节、分组等测量)】

内存是一个 IOPS 非常高的系统,因为我想申请一块内存就申请一块内存,销毁一块内存我就销毁一块内存,内存的申请和销毁是很容易的。而且内存是可以动态的申请大小的。

磁盘的特性是:IPOS很低很低,但吞吐量很高。这就意味着,大量的读写操作都必须攒到一起,再提交到磁盘的时候,性能最高。为什么呢?

如果我有一个事务组的操作(就是几个已经分开了的事务请求,比如写读写读写,这么五个操作在一起),在内存中,因为IOPS非常高,我可以一个一个的完成,但是如果在磁盘中也有这种请求方式的话,

我第一个写操作是这样完成的:我先在硬盘中寻址,大概花费10ms,然后我读一个数据可能花费1ms然后我再运算(忽略不计),再写回硬盘又是10ms ,总共21ms

第二个操作去读花了10ms, 第三个又是写花费了21ms ,然后我再读10ms, 写21ms ,五个请求总共花费83ms,这还是最理想的情况下,这如果在内存中,大概1ms不到。

所以对于磁盘来说,它吞吐量这么大,那最好的方案肯定是我将N个请求一起放在一个buff里,然后一起去提交。

方法就是用异步:将请求和处理的线程不绑定,请求的线程将请求放在一个buff里,然后等buff快满了,处理的线程再去处理这个buff。然后由这个buff 统一的去写入磁盘,或者读磁盘,这样效率就是最高。

对于慢速设备,这种处理方式就是最佳的,慢速设备有磁盘,网络 ,SSD 等等。

为什么单核cpu绑定一块线程内存效率最高

我们不能任由操作系统负载均衡,因为我们自己更了解自己的程序,所以我们可以手动地为其分配CPU核,而不会过多地占用CPU”,默认情况下单线程在进行系统调用的时候会随机使用CPU内核,为了优化Redis,我们可以使用工具为单线程绑定固定的CPU内核,减少不必要的性能损耗!

redis作为单进程模型的程序,为了充分利用多核CPU,常常在一台server上会启动多个实例。而为了减少切换的开销,有必要为每个实例指定其所运行的CPU。

Linux 上 taskset 可以将某个进程绑定到一个特定的CPU。你比操作系统更了解自己的程序,为了避免调度器愚蠢的调度你的程序,或是为了在多线程程序中避免缓存失效造成的开销。

redis的多线程情况

一个redisserver运行的时候,不是单线程的,比如进行rdb备份的时候,就是fork出了一个子进程来进行实现。

可以通过 ps -ef | grep redis 来查看到redis的进程pid。

再使用ps -T -p pid 来查看当前pid下面的线程数。



ps命令的“-T”参数表示显示线程(Show threads, possibly with SPID column.)“SPID”栏表示线程ID,而“CMD”栏则显示了线程名称。

redis的内存模式为什么比数据库磁盘块

磁盘数据库的形式,当我们找数据的时候,先找到索引,通过索引然后关联到磁盘的数据。如果使用内存的方式,可以直接从内存中读取数据。减少了硬盘的io。不受硬盘的读取速度影响。

redis的单线程到底有多快



redis的每秒查询次数可以达到10w+。但是随着连接数的增加,每秒的查询数会进行减少。通一个服务器多个连接数导致。

为什么内存读取比硬盘快

两种的方式不同。内存是一种半导体的存储器,是ram。内存中的数据是电,一旦断电内存中的数据就会消失。内存没有机械结构。

硬盘是一种机械结构。查找数据的时候,磁盘要运动到想应的位置。磁头读取磁盘里的数据。

redis单线程的优势和劣势

优势

代码更清晰,处理逻辑更简单。

不用去考虑各种锁的问题,不存在加锁、释放锁操作,没有因为可能出现死锁而导致的性能消耗。

不存在“多进程或者多线程导致的切换”而消耗CPU。

劣势

无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善。

redis的多路io复用

redis 采用网络IO多路复用技术,来保证在多连接的时候系统的高吞吐量。

多路-指的是多个socket网络连接,复用-指的是复用一个线程。多路复用主要有三种技术:select,poll,epoll。epoll是最新的、也是目前最好的多路复用技术。

采用多路I/O复用技术:其一,可以让单个线程高效处理多个连接请求(尽量减少网络IO的时间消耗)。其二,Redis在内存中操作数据的速度非常快(内存里的操作不会成为这里的性能瓶颈)。主要以上两点造就了Redis具有很高的吞吐量。

采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求。

redis为什么是单线程及为什么快的总结

1、Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。

2、Redis使用的是非阻塞IO、IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。

3、Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。

4、Redis避免了多线程的锁的消耗。

5、Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

为什么redis是单线程的以及为什么这么快?的更多相关文章

  1. 为什么redis是单线程的?速度还这么快

    为什么说Redis是单线程的? 为什么redis是单线程的?速度还这么快

  2. 为什么说Redis是单线程的以及Redis为什么这么快!(转)

    文章转自https://blog.csdn.net/chenyao1994/article/details/79491337 一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到 ...

  3. 面试之二:Redis是单线程还是多线程?以及处理模型。

      Redis是单线程还是多线程?以及处理模型. 线程:单线程 处理模型:参考书<Redis 设计与实现>P151-152 ![](https://ws1.sinaimg.cn/large ...

  4. Redis是单线程的

    Redis是单线程的 学习了: http://blog.csdn.net/liupeng_qwert/article/details/77263187 https://www.cnblogs.com/ ...

  5. Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  6. 理解Redis的单线程模式

    0.概述 本文基于的Redis版本为4.0以下,在Redis更高版本中并不是完全的单线程了,增加了BIO线程,本文主要讲述主工作线程的单线程模式. 通过本文将了解到以下内容: Redis服务器采用单线 ...

  7. 《为什么说Redis是单线程的以及Redis为什么这么快!》

    为什么说Redis是单线程的以及Redis为什么这么快!   一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓 ...

  8. redis为何单线程 效率还这么高 为何使用跳表不使用B+树做索引(阿里)

    如果想了解 redis 与Memcache的区别参考:Redis和Memcache的区别总结 阿里的面试官问问我为何redis 使用跳表做索引,却不是用B+树做索引 因为B+树的原理是 叶子节点存储数 ...

  9. redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?

    1.redis和memcached有什么区别? 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcache ...

随机推荐

  1. [POJ2533]Longest Ordered Subsequence<dp>

    题目链接:http://poj.org/problem?id=2533 描述: A numeric sequence of ai is ordered if a1 < a2 < ... & ...

  2. Day13 流程控制

    Linux中的流程控制语句 一.if语句 1.单分支if条件语句 格式:if [ 条件判断式 ] then 程序     fi 注意:1.在Linux中是以if开头,fi结尾.其他地方一般是{开头,} ...

  3. Unix 下 使用 RVM 管理 Ruby 和 gem

    转载:http://www.ibm.com/developerworks/cn/aix/library/au-aix-manage-ruby/   尽管 Internet Relay Chat.论坛和 ...

  4. Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty messa

    1.git提交的时候遇到: # Please enter the commit message for your changes. Lines starting with '#' will be ig ...

  5. jenkins 脱机下 安装插件失败

    1.首次进入,提示离线 2.网上给出了绝大部分答案是进入Manage Plugins 中在高级下将升级站点的https换成http,但是都没解决我的问题  还是报错,用了大部分时间查阅 最终才发现问题 ...

  6. Taro Next H5 跨框架组件库实践

    作者:凹凸曼 - JJ Taro 是一款多端开发框架.开发者只需编写一份代码,即可生成各小程序端.H5 以及 React Native 的应用. Taro Next 近期已发布 beta 版本,全面完 ...

  7. Docker基础修炼2--Docker镜像原理及常用命令

    通过前文的讲解对Docker有了基本认识之后,我们开始进入实战操作,本文先演示Docker三要素之镜像原理和相关命令. 本文的演示环境仍然沿用上一篇文章在本地Centos7中安装的环境,如果你本地没有 ...

  8. Linux基础篇,磁盘及文件使用管理

    在windows系统下,我们可以使用图形化界面很明了的看出当前硬盘使用量与某个文件的占用空间大小和文件数量.但是在linux系统中,我们应该如何得到这些信息呢? 当然是功能强大的df与du了. 一.d ...

  9. Exercise 1测试

    此篇博客旨在测试Exercise 1,发现其中问题并解决. 首先,我们使用codeblocks对Exercise 1进行编译.结果如下: 可以发现经编译后的Exercise 1并无编译错误,只有两个w ...

  10. vscode如何安装eslint插件 代码自动修复

    ESlint:是用来统一JavaScript代码风格的工具,不包含css.html等. 方法和步骤: 通常情况下vue项目都会添加eslint组件,我们可以查看webpack的配置文件package. ...