Redis 单线程为什么那么快?

134 阅读4分钟

功夫熊猫里面的师傅说,只做自己能力范围内的事,是没有可能进步的。如果一直选择做能力范围内的事,我想就都是重复的劳动吧,没有做新的东西,没有冒险,收获也一定很平淡,《像狗一样奔跑》里面有一句话,对未知的道路失去勇气,才是青春真正的结束,年轻人总是有很多热血,敢于尝试,敢于面对未知的东西,这也是少年心的一种表现。

BB结束

现在说说单线程redis为啥还那么快?

之前有说线程池,为什么使用线程池,说了科特尔原则,反正就是一顿跨,就是说把串行改成并行,这样就没有了等待,程序执行也就更快了,cpu资源利用率也就上去了。

那redis怎么还用单线程呢,有了线程池这么牛逼的东西,这不是自讨苦吃吗?

因为凡事有好处就有坏处,现在就讲讲多线程的缺点

1 上下问切换

我们买电脑时都会看cpu的核数,单核的,双核的,四核的,常理来说都是一个线程对应一个核,也就是单核单线程,那线程池是怎么分配出一大堆线程的,说是同一时间执行多线程,其实并不是,打个比方,一个单核单线程的cpu他也可以跑多线程,怎么弄的呢,这个过程其实是这样的,服务器向cpu请求线程,cpu对每一个线程提供一个时间片,时间片一般都很短,一般是几十ms,然后cpu会在这些时间片之间不断的切换,切换的时候会记录当前任务的状态,切换回来之后根据状态继续执行任务,这个过程就是上下文切换,无疑,这种切换也是需要性能的。

2 阻塞

使用多线程,一定要注意的就是阻塞,我们通过加锁来保证数据的准确定,但是加锁也会让并行变成串行,使用多线程如果存在较多的情况下,系统的吞吐率其实不回再显著的增加了,以为一些锁会改变并行。

这里说一说吞吐率,他是指每秒传输的数量,如5kb/s,还有一个QPS,这个是指每分钟程序访问的数量

说完了,多线程的缺点,下面说说redis用单线程的优点

1 他是基于内存的,内存的io就非常快了

2 他的数据结构简单,HashMap,时间复杂度是O1

3 他有一个多路复用机制

说到这个多路复用机制,这个就是redis的亮点了,其实redis的多路复用机制是包装了操作系统的多路复用机制。

他有几种命令,select,poll,epoll

1)先说select的机制,他是从redis端,选出1024个socket,然后复制到内核里,然后遍历,如果遍历到的socet存在可以服务的数据,那么返回给redis服务端进行数据的写入。对于那些不能写入的socket,就进行监控,也就是不断的循环遍历,等待他们可以写入,然后在返回给redis。

2)poll就是不限制1024

3)epoll 这个就是另一个实现思路

增加一个中间层和改大块为小块,逐个击破,增加一个中间层其实就是在内核里面加一个ep对象,然后ep对象存储socket,这样socket就一直在内核里面不用复制了,这样解决了每次从redis复制到内核的过程,ep还有一个双向链表的队列,socket被触发时放在哪里,可以快速找到

另外要说的是redis6.0已经使用了多线程来处理io,所以说现在的redis是单线程是不准确的,redis的读写仍然使用单线程,但是网络io现在是多线程,因为select本身是阻塞的,所以会减低程序的执行效率。