內存: 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