服務器併發IO模型

1.影響網絡性能的因素

CPU

cache miss、perf、sse4、內存拷貝、系統調用、進程切換

內存

空間換時間、GC、內存泄漏

磁盤

IOPS、帶寬、隨機/順序讀寫、PageCache

網絡

網卡、內核參數、異步與同步、併發

 

網卡硬件

芯片處理能力、網卡隊列、中斷CPU綁定、中斷平衡

操作系統

TCP/IP協議棧、內核參數、內核特性

應用程序

同步阻塞、異步非阻塞、Epoll、ZeroCopy、緩存區

 

2.網絡套接字

       套接字是網絡編程中的一種通信機制,是支持TCP/IP的網絡通信的基本操作單元,可以看做是不同主機之間的進程進行雙向通信的端點,簡單的說就是通信的兩方的一種約定,用套接字中的相關函數來完成通信過程。

#include<sys/socket>
int socket(int domain, int type, int protocol);

domain:域,AF_INET(IPv4域),AP_INET6(IPv6域),AF_UNIX(UNIX域)

type:SOCKET_DGRAM(UDP),SOCKET_STREAM(TCP),RAW(原始套接字,能修改協議棧裏面的內容)

 

 3.四種併發模型

3.1 併發式模型(Fork/CreateThread)

        每個客戶端創建一個進程/線程,切換進程/線程太耗資源

 

3.2 Leader-Fallower模型(Apache/PHP-FPM)

         預先創建N個進程或線程,在子進程/線程中循環Accept,並處理網絡請求,多個進程爭搶Accept,發送響應後close並繼續Accpet。

3.2.1 C10K問題 

       服務器是基於進程/線程模型。新到來一個TCP連接,就需要分配一個進程。假如有C10K,就需要創建1W個進程,可想而知單機是無法承受的。當創建的進程或線程多了,數據拷貝頻繁(緩存I/O、內核將數據拷貝到用戶進程空間、阻塞,進程/線程上下文切換消耗大, 導致操作系統崩潰,這就是C10K問題的本質。那麼如何突破單機性能是高性能網絡編程必須要面對的問題,進而這些侷限和問題就統稱爲C10K問題。

解決辦法:IO多路複用

3.3 Reactor模型

       基於epoll實現時間循環-時間驅動編程,所有邏輯需要在回調中完成,多次IO操作要進行嵌套回調。

select運行機制

       select()的機制中提供一種fd_set的數據結構,實際上是一個long類型的數組,每一個數組元素都能與一打開的文件句柄(不管是Socket句柄,還是其他文件或命名管道或設備句柄)建立聯繫,建立聯繫的工作由程序員完成,當調用select()時,由內核根據IO狀態修改fd_set的內容,由此來通知執行了select()的進程哪一Socket或文件可讀。

select機制的問題

  1. 每次調用select,都需要把fd_set集合從用戶態拷貝到內核態,如果fd_set集合很大時,那這個開銷也很大
  2. 同時每次調用select都需要在內核遍歷傳遞進來的所有fd_set,如果fd_set集合很大時,那這個開銷也很大
  3. 爲了減少數據拷貝帶來的性能損壞,內核對被監控的fd_set集合大小做了限制,並且這個是通過宏控制的,大小不可改變(限制爲1024)

Poll

      poll的機制與select類似,與select在本質上沒有多大差別,管理多個描述符也是進行輪詢,根據描述符的狀態進行處理,但是poll沒有最大文件描述符數量的限制(鏈表代替數組)。也就是說,poll只解決了上面的問題3,並沒有解決問題1,2的性能開銷問題。

Epoll

      epoll在Linux2.6內核正式提出,是基於事件驅動的I/O方式,相對於select來說,epoll沒有描述符個數限制,使用一個文件描述符管理多個描述符,將用戶關心的文件描述符的事件存放到內核的一個事件表中,這樣在用戶空間和內核空間的copy只需一次。

 

3.4 半同步半異步模型(Swoole/Ngix+FPM)

         Master進程實現IO,解決高併發,長連接問題。

        Worker進程處理業務邏輯,同步模型易於編程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章