redis为什么是单线程

原因一:redis本身就是基于内存操作的,所以每个操作执行速度都很快。

如果使用多线程,就需要解决多线程同步的问题,就会涉及到线程的频繁切换而消耗CPU。单线程的使用避免了不必要的上下文切换和竞争条件,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

原因二:redis中的数据结构比较简单,对数据的操作也就比较快。

原因三:使用多路复用IO,即非阻塞IO。这样提高了redis的吞吐量。多路是指可以处理多个网络连接产生的流,复用是指一个线程可以服务多条IO流。

传统的网络IO是阻塞式的,服务器线程会一直在监听数据传输的管道,一直阻塞在那里,直到有客户端发送数据。所以阻塞情况下,一个线程只能服务一个IO。为了提高效率,就产生了非阻塞IO。非阻塞IO分为三种:

①非阻塞(忙轮询):采用死循环方式轮询每一个流,如果有IO事件就处理,这样可以使得一个线程可以处理多个流,但是效率不高,容易导致CPU空转 。

②Select代理(无差别轮询):可以观察多个流的IO事件,如果所有流都没有IO事件,则将线程进入阻塞状态,如果有一个或多个发生了IO事件,则唤醒线程去处理。但是还是得遍历所有的流,才能找出哪些流需要处理。如果流个数为N,则时间复杂度为O(N)。

③Epoll代理:Select代理有一个缺点,线程要轮询所有的Stream,还是存在无效操作。 Epoll不会轮询所有的流,只轮询发出了事件的流,哪个流发生了怎样的IO事件会通知处理线程,因此对这些流的操作都是有意义的,复杂度降低到了O(1)。

缺点就是在多处理器情况下,不能充分利用其他CPU。可以的解决方法是开启多个redis服务实例,通过复制和修改配置文件,可以在多个端口上开启多个redis服务实例,这样就可以利用其他CPU来处理连接流。

猜你喜欢

转载自blog.csdn.net/wanderlustLee/article/details/81148840