内存: 1. 寻址时间:纳秒级别ns 2. 带宽:很大 磁盘: 1. 寻址时间:毫秒级别ms 2. 带宽:G/M 磁盘比内存寻址慢了10W倍以上,因此单机Redis能支持每秒10W以上的请求
可能不少人认为要想系统处理速度快不是应该使用多线程技术。但其实Redis的数据都是放在内存中,查询存储都延时都很是小,是纳秒级别的,因此若是使用多线程,就须要加锁,系统资源还须要耗费在线程之间上下文切换上面,反而会影响性能。单进程、单线程天生就保证了请求的顺序执行,不须要加锁,也没有了没必要要的上下文切换,所以能够将硬件的性能发挥到极致
总结:这3个条件不是相互独立的,特别是第一条,若是请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说Redis为特殊的场景选择了合适的技术方案。windows
应用程序进程/线程若是发起1K个请求,则开启1K个socket文件描述符,socket在等待内核返回数据时是阻塞式的,数据未准备好就一直阻塞等待,一次只会返回一个socket结果,直到返回数据后才等待下一个socket的返回
应用进程若是发起1K个请求,则在用户空间不停轮询这1K个socket文件描述符,查看是否有结果返回。这种方法虽然不阻塞,可是效率过低,有大量无效的循环
select:能打开的文件描述符个数有限(最多1024个),若是有1K个请求,用户进程每次都要把1K个文件描述符发送给内核,内核在内部轮询后将可读描述符返回,用户进程再依次读取。由于文件描述符(fd)相关数据须要在用户态和内核态之间拷来拷去,因此性能仍是比较低poll:可打开的文件描述符数量提升,但性能仍然不够缓存
epoll(Linux下多为该技术):用户态和内核态之间不用文件描述符(fd)的拷贝,而是经过mmap技术开辟共享空间,全部fd用红黑树存储,有返回结果的fd放在链表中,用户进程经过链表读取返回结果,伪异步I/O,性能较高。epoll分为水平触发和边缘出发两种模式,ET是边缘触发,LT是水平触发,一个表示只有在变化的边际触发,一个表示在某个阶段都会触发多线程
AIO:异步I/O,性能最高,可是使用很是复杂,不是很经常使用(windows系统中多见)
多路复用技术的发展表明目前I/O发展的方向。框架
select --- 只支持1024个句柄,轮询致使性能降低异步
poll --- 支持句柄数增多,性能仍然不高socket
epoll --- 支持句柄数增多,事件性驱动,性能高性能
Redis的I/O采用Linux下最早进的epoll,包括Netty也是使用的epoll(后续会有文章专门研究Netty)spa
AIO虽然更加先进,可是写起来更加复杂,并且在Linux内核下尚未真正支持AIO,可是Windows支持AIO线程
正是Redis做者对性能极致的追求,才成就了今天Redis在缓存界的霸主地位,选择Redis就是选择了高性能!!!code