C10K問題

轉自:https://www.jianshu.com/p/ba7fa25d3590html

 

C10K問題由來

隨着互聯網的普及,應用的用戶羣體幾何倍增加,此時服務器性能問題就出現。最初的服務器是基於進程/線程模型。新到來一個TCP鏈接,就須要分配一個進程。假若有C10K,就須要建立1W個進程,可想而知單機是沒法承受的。那麼如何突破單機性能是高性能網絡編程必需要面對的問題,進而這些侷限和問題就統稱爲C10K問題,最先是由Dan Kegel進行概括和總結的,而且他也系統的分析和提出解決方案。編程

C10K問題的本質

C10K問題的本質上是操做系統的問題。對於Web 1.0/2.0時代的操做系統,傳統的同步阻塞I/O模型處理方式都是requests per second。當建立的進程或線程多了,數據拷貝頻繁(緩存I/O、內核將數據拷貝到用戶進程空間、阻塞,進程/線程上下文切換消耗大, 致使操做系統崩潰,這就是C10K問題的本質。windows

可見, 解決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上支持很好,這裏就不具體介紹啦。

參考:併發

  1. 構建C1000K的服務器(1) – 基礎
  2. 高性能網絡編程(二):上一個10年,著名的C10K併發鏈接問題
相關文章
相關標籤/搜索