Redis简介
基本介绍
Redis 的英文全称为 Remote Dictionary Service,中文翻译为远程字典服务。它是一个开源的、支持网络的、基于内存的 Key-Value 数据库。Redis 可用于高速缓存、发布订阅模型等具体应用。
Redis一般的吞吐量
相比于普通数据库,基于内存的 Redis 有着非常恐怖的性能,例如,我们可以使用如下Redis命令测试吞吐量:
redis-benchmark -q -n 100000
该命令可对 Redis 的常用命令进行吞吐量测试,一般来说,Redis 的吞吐量都能达到几万次每秒。若通过socket连接的Redis客户端数量较少时,Redis 可达到10w+的吞吐量。
Redis的多线程问题
Redis到底是多线程还是单线程?这个问题不能简单一概而论。因为 Redis 对 I/O 的要求显著高于CPU的要求,所以CPU的运算速度并不能成为Redis的性能瓶颈。相反,如果使用多线程,线程的反复的上下文切换会增大I/O密集型的Redis的性能瓶颈。
所以 Redis 的前几个版本中,都是以单线程为主执行。但后来,一些计算密集型操作的数量增加,单线程的计算处理能力又受到了限制,所以多线程的 Redis 模块不断出现。无论单线程还是多线程,Redis 所有的 I/O 操作几乎都是异步执行,而命令的执行则是同步的。这种半同步、半异步的模式既保证了性能,又保证了数据的一致性。
I/O多路复用
既然 Redis 使用多线程,或者阻塞/非阻塞 I/O 以提高效率,那就不得不提 Redis 中的 I/O 多路复用机制。该机制的核心为将应用程序的监听连接的主动权交给服务器内核,应用程序将回调函数(callback function)的指针交于服务器,由服务器内核代替应用程序监听。
多路复用就是这其中较为重要的概念了, 多路指的是多 TCP 连接(如 Socket连接),复用指的是复用一个或多个线程。I/O
多路复用的核心原理就是不再由应用程序自己来监听连接,而是由服务器内核替应用程序监听。在多路复用的情景下,服务器端通过多线程提升并发的效率。
举例来说,客户端应用程序和服务器端有大致三种I/O机制:
1.阻塞型 I/O : 客户端向服务器端发送数据请求,在服务器端返回数据之前,客户端一直在等待服务器端的返回数据,即一直处于阻塞状态,这种效率极为低下。
2.非阻塞型 I/O:同样,客户端向服务器端发送数据请求,在服务器端返回数据之前,客户端不是一直等待,而是定时向服务器端发送确认请求来确定数据请求是否已经完成。
3.事件驱动:
(1)服务器端在返回数据时,向监听的所有客户端进行轮询——即多路复用的select模型。
(2)服务器端在返回数据时,使用回调函数向该客户端发送请求——即epoll模型。
Redis中的 I/O 多路复用的应用
Redis的多路复用主要应用于事件,因为Redis为事件驱动。
Redis的事件主要分为两种:文件时间和时间事件。
文件事件,顾名思义,就是Redis服务器端和客户端通讯时会产生一些文件,这构成了文件事件,服务器要监听并处理这些事件来完成通信操作。时间事件是要在Redis内部给定时间内进行一定操作。
时间事件,即在Redis的一段时间内发生了什么操作。
上图就是多路复用在文件事件的例子,面对多个Socket(多路),Redis同时监听,并把所监听的Socket都放入队列(即多路复用程序)之中。然后,通过该队列将文件事件依次传递给事件分派器进行处理。只有当一个 Socket 所对应的事件被处理完毕之后,复用程序才会继续向文件事件分派器传送下一个 Socket 所对应的事件。并且,处理客户端单线程请求时时单线程挨个处理;处理事件的处理器内部却是多线程的。
Redis速度快的总结
1. Redis 基于内存 无磁盘IO操作
2. Redis在处理各个命令,是单线程的
3. Redis 处理某个命令的事件内部时,使用多线程,即多路复用