Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务。
引出单线程模型
开启三个redis-cli客户端同时执行命令:
1、客户端1设置一个字符串键值对:
2、客户端2对counter自增操作:
3、客户端3对counter自增操作:
redis客户端与服务端的模型可以简化成图(如下图所示),每次客户端调用都经历了发送命令、执行命令和返回结果三个过程。
其中第2步执行命令是重点。因为redis是单线程来处理命令的,所以一条命令从客户端到到服务端不会立刻被执行,所有命令都回进入到一个队列中,然后逐个执行。所以以上三个客户端的命令执行顺序是不确定的。
但是可以确定的是绝对不会像下图所示有两条命令被同时执行:
所以两条incr命令是无论怎么执行最终结果都是2,不会产生并发的问题,这就是单线程的基本模型。当然排队机制不想我写的这么简单,redis使用了I/O多路复用技术来解决I/O的问题,感兴趣的可以深入研究下。
为什么单线程还这么快
现在的CPU都是多线程了,可为什么redis使用了单线程速度还这么快。
一般来说,单线程的处理能力要比多线程差,这是毋庸置疑的。比如有10000斤货物,每辆车运载能力每次200斤,那么就要50次来完成,但是如果有50辆车,只要遵循一定的“队列机制”,就可以一次完成,哪为什么redis使用单线程模型还会达到每秒万级的处理能力,大致分为如下三点:
1、redis是基于内存来存储的,然而内存的读取/响应市场大约为100纳秒,这一点也就是redis能打到每秒万级的重要基础。
2、非阻塞I/O,redis使用epoll作为I/O多路复用技术的实现,再加上redis的自身的时间处理模型将epoll中的连接,读写,关闭都转换为事件,不在网络I/O上浪费时间。如下图所示。
3、单线程避免了线程切换和竟态产生的消耗。
单线程带来的好处及问题
单线程带来的好处:
1、单线程可以简化数据结构和算法的实现
2、单线程避免了线程切换和竟态产生的消耗,对于服务端来说,锁和线程切换通常是性能杀手。
单线程的问题:对于每个命令的执行时间是有要求的。(如果某个命令执行时间过长,就会造成其他命令的阻塞,对于redis这种高性能服务来说是致命的。所以redis是面向快速执行场景的数据库)
原文地址:https://blog.51cto.com/14416052/2416214