前言
说到Redis的特点,很容易想到的就是属于Nosql,速度快。再说到Redis为什么速度快,你头脑中第一闪过的可能就是说Redis基于内存、单线程执行了。
基于内存这点不用过多解释,Redis将数据存在内存中,没有了磁盘I/O过程。但要说到单线程为什么快,不熟悉的人可能说不清楚。接下来就说说单线程的Redis为什么快,开发者是怎么设计的呢。
Redis只有单线程吗?
说到Redis是单线程的,意思是Redis只有单线程吗?显然不是,我们所说的单线程,指的是Redis处理网络IO及其使用最多的Redis数据读写都是由单线程来完成的,而Redis其他的功能如数据的持久化、主从数据同步等,都是由其他的线程来执行的。
Redis主要功能为什么要用单线程呢?按理来说多线程不应该更快嘛,这就需要知道多线程的开销问题。
多线程的开销
多线程如果能合理的进行资源分配,确实可以增加响应的吞吐。但是,如果没有协调好硬件资源,就可能出现事倍功半的结果。
因为在系统中经常有被很多线程同时访问的资源,多线程要访问这个资源,为了保证数据的准确性,就得用别的方法比如锁机制来控制。这样一来多线程的优势就没了,所以,Redis就直接采用了单线程。
单线程的优势
单线程的Redis有处理十万级qps的能力,这是为什么呢?原因总结有2点:
- redis在内存上执行主要操作,再加上使用了高效的底层数据结构如哈希表、压缩列表、跳表等。
- Redis采用的多路复用机制,在处理网络IO上发挥了巨大作用。
第一点大家估计比较熟悉,但第二点多路复用机制是什么呢?我们来了解看看。
多路复用机制
几个概念需要了解一下:
- select:当被监听的文件描述符就绪后就会通知系统,但是无法知道具体是哪个文件描述符,因此只能遍历所有的文件描述符来获取。遍历的这个动作就会造成性能损失,另外select最多可监听的描述符是有上限的。
- poll:和select机制一样,也得遍历去获取具体的文件描述符。
- epoll:就是熟知的多路复用。当有文件描述符就绪时,可以知道具体哪个描述符,省去了遍历的过程,因此性能远超select和poll。
Redis采用了多路复用机制,当监测到文件描述符的请求时,就会触发相应事件。而这些事件会进入一个队列,Redis单线程就对队列做处理就行了,这样一来Redis就不需要去轮询哪个请求,从而浪费资源了。
小结
Redis不仅仅有单线程,只不过主要读写操作是用单线程去处理的。Redis单线程快的原因,一部分是因为使用了优秀的底层数据结构,另一部分就是采用了IO多路复用机制来处理请求,避免了轮询耗时的动作。