C10k-problem

知識預熱

線程:
      一般是一個CPU核心對應一個線程的,核心越多,線程越多,處理能力越出色。而因特爾I系列的CPU可以模擬多線程技術,達到更高的處理運算能力,但是因爲是模擬的,所以並不能與實際核心相提並論。例如INTEL的I3就是雙核4線程。(當然,編程的時候要注意的是,CPU 0 不能用得過狠)

 I/O :
     任何瞬間也只能有一個磁頭在工作,其他磁頭閒置。 由於 VM,cache , 有各種東東的存在,一次I/O不代表一次讀寫。

     I/O Stack的流程(內核3.3版本的I/O Stack):
         I/O Stack流圖分爲幾大部分:
            1>.direct I/O 的O_Direct調用
            2>.Page Cache;
            3>.VFS,也即文件系統、網絡通信等
            4>.Block I/O層
            5>.I/O調度方式;
            6>.SCSI處理層;
            7>.磁盤硬件設備;   

(來自thomas-krenn.com的圖片) 


TCP/UDP:
     TCP是面向流的, 不會間斷. TCP爲了提高傳輸效率, 發送數據的時候, 並不是直接發送數據到網路, 而是先暫存到系統緩衝, 超過時間或者緩衝滿了, 才把緩衝區的內容發送出去, 這樣, 就可以有效提高發送效率. 所以會造成所謂的粘包, 即前一份Send的數據跟後一份Send的數據可能會暫存到緩衝當中, 然後一起發送.
     UDP就不同了, 面向報文形式, 系統是不會緩衝的, 也不會做優化的, Send的時候, 就會直接Send到網絡上, 對方收不收到也不管, 所以這塊數據總是能夠能一包一包的形式接收到, 而不會出現前一個包跟後一個包都寫到緩衝然後一起Send.
     
文件FD設置:
      linux對每個進程能打開的文件數目有限制。服務器需要修改破解限制。

------------------------------------------我是分割線----------------------------------------------------------

C10K
     附一篇好文章 link : http://www.kegel.com/c10k.html
     網絡服務在處理數以萬計的客戶端連接時,往往出現效率低下甚至完全癱瘓,這被稱爲 C10K問題。

      C10K問題的最大特點是:設計不夠良好的程序,其性能和連接數及機器性能的關係往往 是非線性的。舉個例子:如果沒有考慮過C10K問題,一個經典的基於select的程序能在 舊服務器上很好處理1000併發的吞吐量,它在2倍性能新服務器上往往處理不了併發2000的吞吐量。 這是因爲在策略不當時,大量操作的消耗和當前連接數n成線性相關。會導致單個任務的資源消耗和當前連接數的關係會是O(n)。而服務程序需要同時對數以萬計的socket進 行I/O處理,積累下來的資源消耗會相當可觀,這顯然會導致系統吞吐量不能和機器性 能匹配。爲解決這個問題,必須改變對連接提供服務的策略。
     主要有兩方面的策略:
          1.應用軟件以何種方式和操作系統合作,獲取I/O事件並調度多 個socket上的I/O操作;
          2. 應用軟件以何種方式處理任務和線程/進程的關係。前者主 要有阻塞I/O、非阻塞I/O、異步I/O這3種方案,後者主要有每任務1進程、每任務1線 程、單線程、多任務共享線程池以及一些更復雜的變種方案。
     常用的經典策略如下:
         1.  Serve one client with each thread/process, and use blocking I/O 。Apache、ftpd等都是這種工作模式。
         2. Serve many clients with single thread, and use nonblocking I/O and readiness notification 。優點在於實現較簡單,方便移植,也 能提供足夠的性能;缺點在於無法充分利用多CPU的機器。尤其是程序本身沒有複雜的 業務邏輯時。
         3. Serve many clients with each thread, and use nonblocking I/O and readiness notification 對經典模型2的簡單改進,缺點是容易在多線程併發上出bug,甚至某些OS不支持多線程 操作readiness notification。
         4.  Serve many clients with each thread, and use asynchronous I/O 在有AI/O支持的OS上,能提供相當高的性能。不過AI/O編程模型和經典模型差別相當 大,基本上很難寫出一個框架同時支持AI/O和經典模型,降低了程序的可移植性。

         在參考了一些開源的代碼,和結合一些測試。我寫了一個簡單的socket-server以實現 C10K。
     (在我的渣本機本上,跑起來的性能遠超C10K。但是,我的庫沒有寫到業務上去,所以性能可能測出來好很多。實際要看業務來討論真實性能)
         源碼地址:https://github.com/PhoneLi/chatroom
      




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