redis為何如此之快
- Redis基本是內存操作,所以速度很快
內存:
1. 尋址時間:納秒級別ns
2. 帶寬:很大
磁盤:
1. 尋址時間:毫秒級別ms
2. 帶寬:G/M
磁盤比內存尋址慢了10W倍以上,所以單機Redis能支持每秒10W以上的請求
- Redis通信采用非阻塞IO, 內部實現采用epolll+自己實現的簡單的事件框架。epoll中的讀、寫、關閉、連接都轉化成了事件,然后利用epoll的多路復用特性,絕不在io上浪費一點時
- 單機Redis采用單進程、單線程、單實例,避免了不必要的上下文切換和競爭條件
可能很多人認為要想系統處理速度快不是應該使用多線程技術。但其實Redis的數據都是放在內存中,查詢存儲都延時都非常小,是納秒級別的,所以如果使用多線程,就需要加鎖,系統資源還需要耗費在線程之間上下文切換上面,反而會影響性能。單進程、單線程天生就保證了請求的順序執行,不需要加鎖,也沒有了不必要的上下文切換,因此可以將硬件的性能發揮到極致
這3個條件不是相互獨立的,特別是第一條,如果請求都是耗時的,采用單線程吞吐量及性能可想而知了。應該說Redis為特殊的場景選擇了合適的技術方案。
Epoll的高性能如何成就Redis
I/O模型 BIO、NIO、多路復用I/O、AIO
1. 阻塞I/O(Blocking I/O BIO)
應用程序進程/線程如果發起1K個請求,則開啟1K個socket文件描述符,socket在等待內核返回數據時是阻塞式的,數據未準備好就一直阻塞等待,一次只會返回一個socket結果,直到返回數據后才等待下一個socket的返回
2. 輪詢非阻塞I/O(Non-Blocking I/O NIO)
應用進程如果發起1K個請求,則在用戶空間不停輪詢這1K個socket文件描述符,查看是否有結果返回。這種方法雖然不阻塞,但是效率太低,有大量無效的循環
3. 多路復用I/O(Multiplexing I/O)
select: 能打開的文件描述符個數有限(最多1024個),如果有1K個請求,用戶進程每次都要把1K個文件描述符發送給內核,內核在內部輪詢后將可讀描述符返回,用戶進程再依次讀取。因為文件描述符(fd)相關數據需要在用戶態和內核態之間拷來拷去,所以性能還是比較低
poll:可打開的文件描述符數量提高,但性能仍然不夠
epoll(linux下多為該技術):用戶態和內核態之間不用文件描述符(fd)的拷貝,而是通過mmap技術開辟共享空間,所有fd用紅黑樹存儲,有返回結果的fd放在鏈表中,用戶進程通過鏈表讀取返回結果,偽異步I/O,性能較高。epoll分為水平觸發和邊緣出發兩種模式,ET是邊緣觸發,LT是水平觸發,一個表示只有在變化的邊際觸發,一個表示在某個階段都會觸發
4. 異步I/O AIO
AIO:異步I/O,性能最高,但是使用非常復雜,不是很常用(windows系統中多見)