redis 单线程的理解

1. redis单线程问题

  单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。

2. 为什么说redis能够快速执行

(1) 绝大部分请求是纯粹的内存操作(非常快速)

(2) 采用单线程,避免了不必要的上下文切换和竞争条件

(3) 非阻塞IO - IO多路复用

3. redis的内部实现

  内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间 这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。

4. Redis关于线程安全问题

   redis实际上是采用了线程封闭的观念,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁。

另一篇对redis单线程的理解:Redis单线程理解

个人理解

redis分客户端和服务端,一次完整的redis请求事件有多个阶段(客户端到服务器的网络连接-->redis读写事件发生-->redis服务端的数据处理(单线程)-->数据返回)。平时所说的redis单线程模型,本质上指的是服务端的数据处理阶段,不牵扯网络连接和数据返回,这是理解redis单线程的第一步。接下来,针对不同阶段分别阐述个人的一些理解。

1:客户端到服务器的网络连接

首先,客户端和服务器是socket通信方式,socket服务端监听可同时接受多个客户端请求,这点很重要,如果不理解可先记住。注意这里可以理解为本质上与redis无关,这里仅仅做网络连接,或者可以理解为,为redis服务端提供网络交互api。

假设建立网络连接需要30秒(为了更容易理解,所以时间上扩大了N倍)

2:redis读写事件发生并向服务端发送请求数据

首先确定一点,redis的客户端与服务器端通信是基于TCP连接(不懂去看,基础很重要),第一阶段仅仅是建立了客户端到服务器的网络连接,然后才是发生第二阶段的读写事件。

完成了上一个阶段的网络连接,redis客户端开始真正向服务器发起读写事件,假设是set(写)事件,此时redis客户端开始向建立的网络流中送数据,服务端可以理解为给每一个网络连接创建一个线程同时接收客户端的请求数据。

假设从客户端发数据,到服务端接收完数据需要10秒。

3:redis服务端的数据处理

服务端完成了第二阶段的数据接收,接下来开始依据接收到的数据做逻辑处理,然后得到处理后的数据。数据处理可以理解为一次方法调用,带参调用方法,最终得到方法返回值。不要想复杂,重在理解流程。

假设redis服务端处理数据需要0.1秒

4:数据返回

这一阶段很简单,当reids服务端数据处理完后 就会立即返回处理后的数据,没什么特别需要强调的。

假设服务端把处理后的数据回送给客户端需要5秒。

那么什么是Reids的单线程

第一阶段说过,redis是以socket方式通信,socket服务端可同时接受多个客户端请求连接,也就是说,redis服务同时面对多个redis客户端连接请求,而redis服务本身是单线程运行。

假设,现在有A,B,C,D,E五个客户端同时发起redis请求,A优先稍微一点点第一个到达,然后是B,C,D,E依次到达,此时redis服务端开始处理A请求,建立连接需要30秒,获取请求数据需要10秒,然后处理数据需要0.1秒,回送数据给客户端需要5秒,总共大概需要45秒。也就是说,下一个B请求需要等待45秒,这里注意,也许这五个几乎同时请求,由于socket可以同时处理多个请求,所以建立网络连接阶段时间差可忽略,但是在第二阶段,服务端需要什么事都不干,坐等10秒中,对于CPU和客户端来说是无法忍受的。所以说单线程效率非常,非常低,但是正是因为这些类似问题,Redis单线程本质上并不是如此运行。接下来讨论redis真正的单线程运行方式。

客户端与服务端建立连接交由socket,可以同时建立多个连接(这里应该是多线程/多进程),建立的连接redis是知道的(为什么知道,去看socket编程,再次强调基础很重要),然后redis会基于这些建立的连接去探测哪个连接已经接收完了客户端的请求数据(注意:不是探测哪个连接建立好了,而是探测哪个接收完了请求数据),而且这里的探测动作就是单线程的开始,一旦探测到则基于接收到的数据开始数据处理阶段,然后返回数据,再继续探测下一个已经接收完请求数据的网络连接。注意,从探测到数据处理再到数据返回,全程单线程。这应该就是所谓的redis单线程。至于内部有多复杂我们无需关心,我们追求的是理解流程,苛求原理,但不能把内脏都挖出来。

从探测到接受完请求数据的网络连接到最终的数据返回,服务器只需要5.1秒,这个时间是我放大N倍后的数据,实际时间远远小于这个,可能是5.1的N万分之一时间,为什么这么说,因为数据的处理是在本地内存中,速度有多快任你想象,最终的返回数据虽然牵扯到网络,但是网络连接已经建立,这个速度也是非常非常快的,只是比数据处理阶段慢那么一点点。因此单线程方式在效率上其实并不需要担心。

原文地址:https://www.cnblogs.com/myseries/p/11733861.html

时间: 2024-11-09 04:03:58

redis 单线程的理解的相关文章

Redis单线程原理

redis是以socket方式通信,socket服务端可同时接受多个客户端请求连接,也就是说,redis服务同时面对多个redis客户端连接请求,而redis服务本身是单线程运行. 假设,现在有A,B,C,D,E五个客户端同时发起redis请求,A优先稍微一点点第一个到达,然后是B,C,D,E依次到达,此时redis服务端开始处理A请求,建立连接需要30秒,获取请求数据需要10秒,然后处理数据需要0.1秒,回送数据给客户端需要5秒,总共大概需要45秒.也就是说,下一个B请求需要等待45秒,这里注

2.redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?

作者:中华石杉 面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的问题吧,redis 最基本的一个内部原理和特点,就是 redis 实际上是个单线程工作模型,你要是这个都不知道,那后面玩儿 redis 的时候,出了问题岂不是什么都不知道? 还有可能面试官会问问你 redis 和 memcached 的区别,但是 memcached 是早些年各大互联网公司常用的缓存

redis单线程问题

1.redis的单线程指的是什么单线程?同一个时间点只处理一个客户端的连接,也就是redis网络模块的单线程. 2.redis为什么设计成单线程 具体作者怎么想的,我不知道,我说一下我的理解(1)redis用的是非阻塞IO,非阻塞I/O本身就可以是单线程处理多个请求(2)如果用多线程,就要考虑线程的上下文切换,和锁的请求和释放,这些操作也比较耗时,锁等待更容易把业务线程池占满(3)在我看来,Redis的设计理念就是短平快,在保证完全内存计算的情况下,能串行的地方就串行,在处理socket请求这块

为什么Redis 单线程却能支撑高并发?

作者:Draveness 原文:draveness.me/redis-io-multiplexing 推荐阅读 1. Java 性能优化:教你提高代码运行的效率 2. 基于token的多平台身份认证架构设计 3. Spring Boot整合JWT实现用户认证(附源码) 4. Springboot启动原理解析 最近在看 UNIX 网络编程并研究了一下 Redis 的实现,感觉 Redis 的源代码十分适合阅读和分析,其中 I/O 多路复用(mutiplexing)部分的实现非常干净和优雅,在这里想

为什么 Redis 单线程能支撑高并发?

阅读本文大概需要 4 分钟. 作者:Draveness 最近在看 UNIX 网络编程并研究了一下 Redis 的实现,感觉 Redis 的源代码十分适合阅读和分析,其中 I/O 多路复用(mutiplexing)部分的实现非常干净和优雅,在这里想对这部分的内容进行简单的整理. 几种 I/O 模型 为什么 Redis 中要使用 I/O 多路复用这种技术呢? 首先,Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情

redis单线程模型分析

redis原理 redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大. 不过,因为一般的内存操作都是简单存取操作,线程占用时间相对较短,主要问题在io上,因此,redis这种模型是合适的,但是如果某一个线程出现问题导致线程占用很长时间,那么reids的单线程模型效率可想而知. 引自网络: 总体来说快速的原因如下: 1)绝大部分请求是纯粹的内存操作(非常快速) 2)采用单线程,避免了不必要的上下文切换和竞争条件 3)非阻塞IO 内部实现采用epoll,采用了ep

Redis单线程解读

之前面试时被面试官问了一个问题,Redis是多线程还是单线程的?依稀记得Redis为单线程,其更深层次的技术原理完全懵逼.所以此篇文章旨在解读Redis为什么为单线程. 1.基本原理 采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) (1)为什么不采用多进程或多线程处理? 多线程处理可能涉及到锁 多线程处理会涉及到线程切换而消耗CPU (2)单线程处理的缺点? 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善 2.Redis不存在线

redis 单线程

redis快速的原因 1内存操作\ 2epoll模型 异步非阻塞io 3采用单线程,避免了不必要的上下文切换和竞态条件 客户端发出的命令是 串行执行的 也就是 数据库的最高隔离级别 串行化 redis 可以使用 watch multi/exec 做原子性命令组装 原文地址:https://www.cnblogs.com/zfzf1/p/8742916.html

(二)redis API的理解和使用

一.全局命令 1.keys * 查看所有键 时间复杂度为O(n),线上环境禁止使用 2.dbsize    查看键总数 3.rpush 插入一个列表类型的键值对 rpush  mylist  a b c d 4.exists key 查看键是否存在,如果存在返回1,不存在返回0 5.del  key [key ...]    删除键,返回成功删除键的个数 6.expire 设置键过期 expire  hello 10 设置键10s过期 7.ttl 返回键的剩余过期时间,大于等于0    -1(没