天天看點

關于C10K問題詳解-突破單機性能是高性能網絡程式設計

C10K問題由來

随着網際網路的普及,應用的使用者群體幾何倍增長,此時伺服器性能問題就出現。最初的伺服器是基于程序/線程模型。新到來一個TCP連接配接,就需要配置設定一個程序。假如有C10K,就需要建立1W個程序,可想而知單機是無法承受的。那麼如何突破單機性能是高性能網絡程式設計必須要面對的問題,進而這些局限和問題就統稱為C10K問題,最早是由Dan Kegel進行歸納和總結的,并且他也系統的分析和提出解決方案。

C10K問題的本質

C10K問題的本質上是作業系統的問題。對于Web 1.0/2.0時代的作業系統,傳統的同步阻塞I/O模型處理方式都是requests per second。當建立的程序或線程多了,資料拷貝頻繁(緩存I/O、核心将資料拷貝到使用者程序空間、阻塞,程序/線程上下文切換消耗大, 導緻作業系統崩潰,這就是C10K問題的本質。

可見, 解決C10K問題的關鍵就是盡可能減少這些CPU資源消耗。

C10K問題的解決方案

  1. 每個連接配接配置設定一個獨立的線程/程序
  2. 同一個線程/程序同時處理多個連接配接

每個程序/線程處理一個連接配接

每個程序/線程同時處理 多個連接配接(I/O多路複用)

  1. select方式:使用fd_set結構體告訴核心同時監控那些檔案句柄,使用逐個排查方式去檢查是否有檔案句柄就緒或者逾時。該方式有以下缺點:檔案句柄數量是有上線的,逐個檢查吞吐量低,每次調用都要重複初始化fd_set。
  2. poll方式:該方式主要解決了select方式的2個缺點,檔案句柄上限問題(連結清單方式存儲)以及重複初始化問題(不同字段标注關注事件和發生事件),但是逐個去檢查檔案句柄是否就緒的問題仍然沒有解決。
  3. epoll方式:該方式可以說是C10K問題的killer,他不去輪詢監聽所有檔案句柄是否已經就緒。epoll隻對發生變化的檔案句柄感興趣。其工作機制是,使用"事件"的就緒通知方式,通過epoll_ctl注冊檔案描述符fd,一旦該fd就緒,核心就會采用類似callback的回調機制來激活該fd, epoll_wait便可以收到通知, 并通知應用程式。而且epoll使用一個檔案描述符管理多個描述符,将使用者程序的檔案描述符的事件存放到核心的一個事件表中, 這樣資料隻需要從核心緩存空間拷貝一次到使用者程序位址空間。而且epoll是通過核心與使用者空間共享記憶體方式來實作事件就緒消息傳遞的,其效率非常高。但是epoll是依賴系統的(Linux)。
  4. 異步I/O以及Windows,該方式在windows上支援很好,這裡就不具體介紹啦。