目录
redis学习🥳
一、单线程架构
Redis 使用了单线程架构来实现高性能的内存数据库服务,本节首先通过多个客户端命令调用的例子说
明 Redis 单线程命令处理机制,接着分析 Redis 单线程模型为什么性能如此之高,最终给出为什么理
解单线程模型是使用和运维 Redis 的关键。
1.1 引出单线程模型
现在开启了三个 redis-cli 客户端同时执行命令。
客户端 1 设置一个字符串键值对:
127.0.0.1:6379> set hello world
客户端 2 对 counter 做自增操作:
127.0.0.1:6379> incr counter
客户端 3 对 counter 做自增操作:
127.0.0.1:6379> incr counter
们已经知道从客户端发送的命令经历了:发送命令、执行命令、返回结果三个阶段,其中我们重点关
注第 2 步。我们所谓的 Redis 是采用单线程模型执行命令的是指:虽然三个客户端看起来是同时要求
Redis 去执行命令的,但微观角度,这些命令还是采用线性方式去执行的,只是原则上命令的执行顺序
是不确定的,但一定不会有两条命令被同步执行,如图 2-3、2-4、2-5 所示,可以想象 Redis内部只
有一个服务窗口,多个客户端按照他没达到的先后顺序被排队在窗口前,依次接受 Redis 的服务,所
以两条 incr 命令无论执行顺序,结果一定是 2,不会发生并发问题,这个就是 Redis 的单线程执行模
型。
图 2-3 宏观上同时要求服务的客户端

图 2-4 微观上客户端发送命令的时间有先后次序的

图 2-5 Redis 的单线程模型

二、为什么单线程还能这么快
通常来讲,单线程处理能力要比多线程差,例如有 10000 公斤货物,每辆车的运载能力是每次 200 公
斤,那么要 50 次才能完成;但是如果有 50 辆车,只要安排合理,只需要依次就可以完成任务。那么
为什么 Redis 使用单线程模型会达到每秒万级别的处理能力呢?可以将其归结为三点:
a. 纯内存访问:Redis 将所有数据放在内存中,内存的响应时长大约为 100 纳秒,这是 Redis 达
到每秒万级别访问的重要基础。
b. 非阻塞 IO:Redis 使用 epoll 作为 I/O 多路复用技术的实现,再加上 Redis 自身的事件处理模型将
epoll 中的连接、读写、关闭都转换为事件,不在网络 I/O 上浪费过多的时间,如图 2-6 所示。
c. 单线程避免了线程切换和竞态产生的消耗:单线程可以简化数据结构和算法的实现,让程序模型更
简单;其次多线程避免了在线程竞争同一份共享数据时带来的切换和等待消耗。
图 2-6 Redis 使用 I/O 多路复用模型

虽然单线程给 Redis 带来很多好处,但还是有一个致命的问题:对于单个命令的执行时间都是有要求
的。如果某个命令执行过长,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成客户端的
阻塞,对于 Redis 这种高性能的服务来说是非常严重的,所以 Redis 是面向快速执行场景的数据库。
三、经典面试题
redis 虽然是单线程模型,为什么效率这么高?速度这么快呢?
答:redis 的上述优点是以 数据库( mysql、oracle、sql、server ) 为参照物的;
1. redis 是访问内存的,数据库 则是访问硬盘的;
2. redis 核心功能比 数据库 的核心功能更简单:
数据库对于数据的插入、删除、查询等都有更复杂的功能支持,这样的功能势必要花费更多的开销。
比如:针对插入、删除,数据库中的各种约束,都会使数据库做额外的工作;
3. 单线程模型,避免了一些不必要的线程竞争开销:
redis 每个基本操作,都是短平快的,就是简单操作一下内存数据,不是什么特别消耗 cpu 的操作,就算搞多个线程,也提升不大;
4. 处理网络 IO 的时候,使用了 epoll 这样的 IO 多路复用机制;
IO 多路复用:一个线程可以管理多个 socket ,针对 tcp 来说,服务器这边每次要服务一个客户端,
都需要给这个客户端安排一个 socket 文件描述符,一个服务器服务多个客户端,同时就有很多个
socket ,这些 socket 上都是无时无刻都在传输数据吗?很多情况下,每个客户端和服务器之间的通
信也没有那么频繁,此时这么多 socket 大部分时间都是静默的,上面是没有数据需要传输的,同一时
刻只有少数 socket 是活跃的,io 多路复用,就是一个线程来处理多个 socket ,os 给开发者提供了一
套 api :select、poll、epoll 机制来使用;
redis学习打卡🥳

6346

被折叠的 条评论
为什么被折叠?



