Redis02-Redis高性能與epoll

Redis爲什麼如此之快

  • Redis基本是內存操做,因此速度很快
內存:  
1. 尋址時間:納秒級別ns  
2. 帶寬:很大  
磁盤:  
1. 尋址時間:毫秒級別ms  
2. 帶寬:G/M  
磁盤比內存尋址慢了10W倍以上,因此單機Redis能支持每秒10W以上的請求
  • Redis通訊採用非阻塞IO, 內部實現採用epolll+本身實現的簡單的事件框架。epoll中的讀、寫、關閉、鏈接都轉化成了事件,而後利用epoll的多路複用特性,毫不在io上浪費一點時
  • 單機Redis採用單進程、單線程、單實例,避免了沒必要要的上下文切換和競爭條件
可能不少人認爲要想系統處理速度快不是應該使用多線程技術。但其實Redis的數據都是放在內存中,查詢存儲都延時都很是小,是納秒級別的,因此若是使用多線程,就須要加鎖,系統資源還須要耗費在線程之間上下文切換上面,反而會影響性能。單進程、單線程天生就保證了請求的順序執行,不須要加鎖,也沒有了沒必要要的上下文切換,所以能夠將硬件的性能發揮到極致

總結:這3個條件不是相互獨立的,特別是第一條,若是請求都是耗時的,採用單線程吞吐量及性能可想而知了。應該說Redis爲特殊的場景選擇了合適的技術方案。windows

image.png

Epoll的高性能如何成就Redis

I/O模型 BIO、NIO、多路複用I/O、AIO

1. 阻塞I/O(Blocking I/O BIO)

應用程序進程/線程若是發起1K個請求,則開啓1K個socket文件描述符,socket在等待內核返回數據時是阻塞式的,數據未準備好就一直阻塞等待,一次只會返回一個socket結果,直到返回數據後纔等待下一個socket的返回

image.png

2. 輪詢非阻塞I/O(Non-Blocking I/O NIO)

應用進程若是發起1K個請求,則在用戶空間不停輪詢這1K個socket文件描述符,查看是否有結果返回。這種方法雖然不阻塞,可是效率過低,有大量無效的循環

image.png

3. 多路複用I/O(Multiplexing I/O)

select:能打開的文件描述符個數有限(最多1024個),若是有1K個請求,用戶進程每次都要把1K個文件描述符發送給內核,內核在內部輪詢後將可讀描述符返回,用戶進程再依次讀取。由於文件描述符(fd)相關數據須要在用戶態和內核態之間拷來拷去,因此性能仍是比較低

poll:可打開的文件描述符數量提升,但性能仍然不夠緩存

epoll(Linux下多爲該技術):用戶態和內核態之間不用文件描述符(fd)的拷貝,而是經過mmap技術開闢共享空間,全部fd用紅黑樹存儲,有返回結果的fd放在鏈表中,用戶進程經過鏈表讀取返回結果,僞異步I/O,性能較高。epoll分爲水平觸發和邊緣出發兩種模式,ET是邊緣觸發,LT是水平觸發,一個表示只有在變化的邊際觸發,一個表示在某個階段都會觸發多線程

image.png
image.png

4. 異步I/O AIO

AIO:異步I/O,性能最高,可是使用很是複雜,不是很經常使用(windows系統中多見)

image.png

Redis的I/O總結

多路複用技術的發展表明目前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

相關文章
相關標籤/搜索