Redis 为什么使用单线程?
官方解释:
因为 Redis 是基于内存的操作,CPU 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是 机器内存的大小 或者 网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。
Redis 真正的瓶颈问题并不是CPU ,而是内存,以及网络传输各种延迟。
使用单线程带来的好处?
- 使用单线程模型能带来更好的 可维护性,方便开发和调试;(相对于多线而言,程序执行顺序具有却行性,没有任何诡异的bug)
- 使用单线程模型也能 并发 的处理客户端的请求;(I/O 多路复用机制,并发处理多个客户端的连接请求)
- 减少了上下文的切换问题,且整个过程中没有任何加锁释放锁的从操作。
redis 为什么这么快?
- 纯内存操作:读取不需要进行磁盘 I/O,所以比传统数据库要快上不少;
- 单线程,无锁竞争:这保证了没有线程的上下文切换,不会因为多线程的一些操作而降低性能;
- 多路 I/O 复用模型,非阻塞 I/O:采用多路 I/O 复用技术可以让单个线程高效的处理多个网络连接请求(尽量减少网络 IO 的时间消耗);
- 高效的数据结构,Redis 对于底层的数据结构和内存占用做了大量的优化,例如不同长度的字符串使用不同的结构体表示,HyperLogLog 的密集型存储结构等等…
redis 4.0 以后部分操作开始支持多线程
在 Redis 4.0 之后的版本,情况就有了一些变动,新版的 Redis 服务在执行一些命令时就会使用『主处理线程』之外的其他线程,例如 UNLINK、FLUSHALL ASYNC、FLUSHDB ASYNC 等非阻塞的删除操作。
为什么部分操作开始支持多线程?
对于删除操作,如果键值对所占用的内存空间较小,单线程同步删除损耗也不会太大,如果键值对占用的内存空间较大,几十兆的文件,毫秒内是无法删除的,且释放内存也会有时间消耗,这些操作会阻塞其它操作,但是这些删除释放操作对其它操作并没有任何影响,所以可以异步执行,通过多线程非阻塞的释放内存空间,提高执行效率。
总结
无论是单线程还是多线程,都是为了性能考虑的。因为redis 的瓶颈问题并是不cpu 带来的,所以不需要考虑多线程,没有使用多线程的必要,使用反而会降低性能。使用多线程仅在部分删除操作上面,通过多线程非阻塞释放内存,减少对主线程的阻塞,提高执行效率。