一、为什么Redis是单线程的

1️⃣官方答案
因为 Redis 是基于内存的操作,CPU不是 Redis 的瓶颈。Redis 的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。

2️⃣性能指标
关于 Redis 的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求。

3️⃣详细原因

  1. 不需要各种锁的性能消耗
    Redis 的数据结构并不全是简单的 Key-Value,还有 list,hash 等复杂的结构。这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在 hash 当中添加或者删除一个对象。这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加。
    总之,在单线程的情况下,代码更清晰,处理逻辑更简单,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗,不存在多进程或者多线程导致的切换而消耗 CPU。
  2. 单线程多进程的集群方案
    单线程的威力实际上非常强大,每核效率也非常高。多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的。所以单线程、多进程的集群不失为一个时髦的解决方案。
  3. CPU 消耗
    采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。但是如果 CPU 成为 Redis 瓶颈,或者不想让服务器其他 CPU 核闲置,那怎么办?
    可以考虑多起几个 Redis 进程,Redis 是 key-value 数据库,不是关系数据库,数据之间没有约束。只要客户端分清哪些 key 放在哪个 Redis 进程上就可以了。

二、Redis的单线程理解

Redis 客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于 Redis 是单线程来处理命令的,所有到达服务端的命令都不会立刻执行,所有的命令都会进入一个队列中,然后逐个执行,并且多个客户端发送的命令的执行顺序是不确定的,但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是 Redis 的单线程基本模型。

Redis 服务器通过 socket (套接字)与客户端或其他 Redis 服务器进行连接,而文件事件就是服务器对 socket 操作的抽象。服务器与客户端或其他服务器的通信会产生相应的文件事件,而服务器通过监听并处理这些事件来完成一系列网络通信操作。

Redis 基于 Reactor 模式开发了自己的网络事件处理器——文件事件处理器,文件事件处理器使用 I/O 多路复用程序来同时监听多个 socket,并根据 socket 目前执行的任务来为 socket 关联不同的事件处理器。当被监听的 socket 准备好执行连接应答、读取、写入、关闭等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用 socket 之前已关联好的事件处理器来处理这些事件。文件事件处理器的构成:

注意:其中 I/O 多路复用程序通过队列向文件事件分派器传送 socket。

I/O多路复用技术

Redis 采用网络 I/O 多路复用技术,来保证在多连接的时候系统的高吞吐量。关于 I/O 多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个 socket 可读或者可写的时候,它可以给你一个通知。这样当配合非阻塞的 socket 使用时,只有当系统通知我哪个描述符可读了,我才去执行 read 操作,可以保证每次 read 都能读到有效数据而不做纯返回 -1 和 EAGAIN 的无用功,写操作类似。

操作系统的这个功能是通过 select/poll/epoll/kqueue 之类的系统调用函数来实现,这些函数都可以同时监视多个描述符的读写就绪状况,这样,多个描述符的 I/O 操作都能在一个线程内并发交替地顺序完成,这就叫 I/O 多路复用。多路—指的是多个 socket 连接,复用—指的是复用同一个 Redis 处理线程。多路复用主要有三种技术:select,poll,epoll。epoll 是最新的也是目前最好的多路复用技术。

采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 I/O 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响 Redis 性能的瓶颈,基于这两点 Redis 具有很高的吞吐量。

三、单线程的 Redis 为何高并发快

Redis 利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。

1️⃣Redis 的高并发和快速原因

  1. Redis 是基于内存的,内存的读写速度非常快。
  2. Redis 是单线程的,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。
  3. Redis 使用多路复用技术,可以处理并发的连接。非阻塞 IO 部实现采用 epoll,采用了 epoll+自己实现的简单的事件框架。epoll 中的读、写、关闭、连接都转化成了事件,然后利用 epoll 的多路复用特性,绝不在 IO 上浪费一点时间。
  4. 数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的。
  5. Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

2️⃣单进程单线程弊端
无法发挥多核 CPU 性能,不过可以通过在单机开多个 Redis 实例来完善。

3️⃣Redis高并发总结

  1. Redis 是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在 IO 上,所以读取速度快。
  2. Redis 使用的是非阻塞 IO。IO 多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。
  3. Redis 采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。
  4. Redis 全程使用 hash 结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
  5. Redis 采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

四、常见疑问解答

1️⃣为什么不采用多进程或多线程处理?

①多线程处理可能涉及到锁。
②多线程处理会涉及到线程切换而消耗 CPU。

2️⃣单线程处理的缺点?

①耗时的命令会导致并发的下降,不只是读并发,写并发也会下降。
②无法发挥多核 CPU 性能,不过可以通过在单机开多个 Redis 实例来完善。

3️⃣Redis 不存在线程安全问题

Redis 采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个 Redis 操作(即多个 Redis 操作命令)的复合操作来说,依然需要锁,而且有可能是分布式锁。

Redis 是单线程的正确理解相关推荐

  1. Redis是单线程的以及Redis为什么这么快

    2019独角兽企业重金招聘Python工程师标准>>> 一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是"二八定律".什么是&qu ...

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

    一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是"二八定律".什么是"热数据和冷数据",复杂一点的会问到缓存雪崩.缓存穿透.缓存 ...

  3. java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part6(Redis的应用场景、Redis是单线程的速度还快、Redis线程模型:Reactor模式、事件、发布订阅、管道)~整起

    PART1-1:为什么Redis是单线程的 Redis单线程是指: Redis的网络IO和键值对读写是由一个线程来完成的.这也是 Redis 对外提供键值存储服务的主要流程.Redis的其他功能,比如 ...

  4. Redis是单线程的,但Redis为什么这么快?

    近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是"二八定律".什么是"热数据和冷数据",复杂一点的会问到缓存雪崩.缓存穿透.缓存预热.缓存 ...

  5. linux单线程处理多个请求,redis是单线程的,如何处理并发请求?

    疑问: redis是单线程的,如何并发处理多个请求? 下面是我个人的理解. 答案是:使用操作系统的多进程机制.也就是我们常说的,多路复用API,多路复用API本质上是对操作系统多路复用功能的封装. 什 ...

  6. Redis是单线程为什么还那么快?

    Redis为什么还那么快 基于内存   Redis完全基于内存,绝大部分请求是纯粹的内存操作,Redis将数据存储在内存中,读写数据的时候不会受到硬盘I/O速度的限制(内存速度为什么比硬盘快?),类似 ...

  7. Redis 属于单线程还是多线程?不同的版本有什么区别?

    Redis 是普及率最高的技术之一,同时也是面试中必问的一个技术模块,所以从今天开始我们将从最热门的 Redis 面试题入手,更加深入的学习和了解一下 Redis. 我们本文的面试题是 Redis 属 ...

  8. Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析Redis分布式锁的正确使用姿势!...

    Redis分布式锁基本原理 采用 redis 实现分布式锁,主要是利用其单线程命令执行的特性,一般是 setnx, 只会有一个线程会执行成功,也就是只有一个线程能成功获取锁:看着很完美. 然而-- 看 ...

  9. Redis新版本发布,你还认为Redis是单线程?

    Redis从单线程到多线程的转变 Redis简介 Redis单线程时代 `"单线程"`的Redis为什么会这么快? Redis的瓶颈 6.0版本后的Redis线程问题 redis的 ...

最新文章

  1. Android Handler 异步消息处理机制的妙用 创建强大的图片载入类
  2. 我为什么弃用GAN?
  3. Linux进程间通信分类 以及 pipe的原理实现
  4. 3.4.1 变量初始化
  5. SAP CRM my task 6个roundtrip的原理讲解
  6. vue的鼠标移入和移出
  7. 【完美】mac word2016 安装 endnote x9
  8. Redis学习笔记~Redis并发锁机制
  9. java怎么把程序写入持久化_如何将DataFrame持久化到Hive表?
  10. 前端点击按钮下载图片
  11. 蚂蚁课堂视频笔记思维导图-4期 三、消息中间件
  12. 计算机科学的研究方法,计算机科学与技术课题研究的方法论
  13. nodejs、express下载和配置
  14. 两年工作经验,三面拼多多,最终获得offer!(面经总结)
  15. 转:以Delphi Package架构多人开发应用程序环境
  16. linux git rabit,Linux 安装 RabbitMQ
  17. 三种算法求解最大公约数和最小公倍数
  18. NCN8025 TDA8035 智能卡接口IC读卡器芯片的替代解决方案
  19. 联想g400从u盘启动计算机,联想g400笔记本设置U盘启动的图文步骤
  20. 网络对抗技术_实验四_恶意代码技术

热门文章

  1. 相机像素和显示分辨率
  2. CSS3 【display: flex;】与【align-self: 可覆盖父元素设置algin-items;】的使用
  3. idea,webstorm插件推荐(新手向)1.7版本
  4. 使用HTTP的GET请求做一个简单的天气预报
  5. iOS13.1.1你更新了吗?果iPhoneXR升级之后屏幕失灵、耗电更快
  6. 那些创业致富了的人,都看清了酷雷曼这4点优势
  7. Blender 使用中遇到的问题和解决方法
  8. gis插入的文本怎么搞成两行_办公小技巧:Powerpoint文本框的另类应用
  9. leapmotion使用之一-如何用leapmotion代替鼠标简单操作
  10. Fedora29 安装/配置 小狼毫输入法(RIME | 中州韵输入法引擎)