Redis 只使用一个线程,处理所有的命令请求。不是说一个 Redis 服务器进程内部只有一个线程,其实也有多个线程,多个线程是在处理网络IO
假设有多个客户端,要同时操作 Redis
服务器
incr
是 increase
,作用是把 key
的 value
进行 +1
操作[!quote] 线程安全问题
当前这两个客户端,也相当于“并发”的发起了上述的请求,此时是否就意味着服务器这边也会存在类似的线程安全问题呢?
Redis
服务器实际上是单线程模型,保证了当前收到的这多个请求是串行执行的Redis
能够使用单线程模型很好的工作,主要原因在于 Redis
的核心业务逻辑,都是短平快的,不太消耗 CPU
资源,也就不太吃多核了
弊端:
Redis
必须要特别小心,某个操作占用时间长,就会阻塞其他命令的执行(前面的 keys *
)#高频面试
Redis
虽然是单线程模型,但是为什么效率这么高,速度这么快呢?
Redis
的操作访问内存;数据库是访问硬盘Redis
核心功能,比数据库的核心功能更简单 Redis
每个基本操作都是短平快,就是简单操作一下内存数据,不是什么特别消耗 CPU 的操作,就算搞多个线程,提升也不大epoll
这样的 IO多路复用本质上是让我们一个线程,管理多个 socket
针对 TCP
来说,服务器这边每次要服务一个客户端,都需要给这个客户端安排一个 socket
,通过这个 socket
来和客户端进行通信
一个服务器要服务多个客户端,同时就有很多个 socket
。这些 socket 上都是无时无刻都在传输数据吗?还是大部分时间都是闲置的?
socket
大部分时间都是静默的,上面是没有数据需要传输的。socket
是活跃的,这就是我们使用 IO复用的重大前提最开始介绍 TCP 服务器的时候,有一个版本就是每个客户端都分配一个线程==>客户端多了,线程就多了,系统开销就大了
基于上述的这些原因,就搞了“IO多路复用”,一个线程来处理多个 socket
Linux
上提供的 IO多路复用,主要是三套 API:select
、poll
、epoll
比如你今晚,你想吃烧烤,你妈想吃饺子,你爸想吃炒菜
epoll
epoll
相当于时间通知/回调机制
select
是你自己再几个摊位之间不停地问,没人提醒你
如果这三件事都是交互特别频繁的,还是老老实实多搞几个线程靠谱,一个线程容易忙不过来
C++
可以直接使用 Linux 原生的 epoll
API
Java
可以使用 NIO
(标准库提供的一组类,底层就是封装了 epoll
)