Redis到底是不是单线程的?一个直击灵魂的问题,其实当你问出这个问题的时候就说明你对线程和IO没有基本的认识。
让我们回到操作系统来讨论一下线程和IO到底是什么。我很喜欢很多教线程的老师举的例子说 在计算机里,线程相当于一个工人,CPU相当于工具。众所周知的是现代计算机都是多核CPU的,相当于有多把工具,多雇佣几个工人就可以充分发挥效率。
在上述理论下也就是说几个核心对应几个线程是最合适的。但是事实是这样的吗?我们可能忘了还有IO等耗时操作的影响,这相当于什么呢。相当于工人拿着工具却在做装卸货这种简单,但是麻烦的事情,这就浪费了工人和工具的价值。那这种IO这种脏活累活CPU线程不去做谁做呢,有个东西DMA他很像CPU但是只能搞一些简单麻烦的活。
因此实际的情况每当线程遇到IO操作都会,当前的线程都会放弃CPU,让给其他线程,当DMA把IO这种脏活累活干好了,再恢复。这也就是CPU中断向量和线程的上下文切换。
也因为这些机制,线程并不是越多越好,太多会造成切换时保存线程的状态所需要的内存变多,耗时变长,从而影响性能。
回到Redis。Redis在IO线程模型这里使用了大名鼎鼎的IO多路复用。一个线程处理多个 IO 流。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听套接字和已连接套接字
而Redis使用单线程是这样几方面的考虑
1、简单。哈哈,这个理由似乎有点搞笑,难道是Redis那个头发多的家伙能力不行吗?不是的,首先Redis本身操作的是内存,速度快。多线程虽然能加速处理速度,但是也引入了锁各种同步的复杂度。可是确实能提升吗,实际情况是Redis单线程已经足够快了,而接入命令却跟不上,简单来说就是网络跟不上。所以不选择多线程,但是新版本6.0增加了多线程的选项,是因为在CPU多核的发展下,多核也许会带来更好的性能,另一方面为了发挥性能我们可能还需要加大网络这个水管的宽度。
2、单线程没有上下文切换的开销。笔者认为这点其实很扯,为什么呢?因为这是选择单线程的附加好处,并不是决定选择的因素。