哪種OS更適合高性能網絡應用

哪種OS更適合高性能網絡應用
 英文原文:http://www.samag.com/documents/s=1148/sam0107a/0107a.htm
摘要
本文通過實驗測試對Linux、Solaris (for Intel)、FreeBSD和Windows 2000在運行高性能網絡應用程序方面的速度進行了比較。描述瞭如何根據需要從您的軟件提供商那裏獲得相應性能和軟件體系結構的產品,解釋了每個設計是如何產生不同的性能特性的,並且最終確定了對於每個通用的網絡程序設計來說哪個操作系統最爲合適。我們通過仿真和真實環境測試提出了操作系統基準,並對相應結果給出了評價。
我們發現,與其所依賴的操作系統相比較,軟件應用程序的體系結構是決定其執行速度的更主要因素。我們的基準程序(benchmarks)證明,基於進程的體系結構與異步任務體系結構之間會有12倍的性能差異。值得注意的是,即使使用最有效的異步體系結構,不同操作系統間的性能差異也會相差75%以上。疑懼我們的度量基準,我們發現Linux是執行性能最好的操作系統,它比排在第二位的Solaris的性能高35%,然後纔是Windows,排在最後的是FreeBSD。

背景

在Lyris技術公司,我們的任務是編寫高性能、跨平臺、基於email的應用程序。衆所周知,更好的應用程序性能是決定競爭優勢的關鍵因素,所以我們花了大量的時間在影響應用程序性能的所有因素(軟件、硬件和操作系統)方面進行調整。我們的客戶經常問的一個問題是哪個操作系統最適合運行我們的軟件。另一種情況是,他們已經選擇了一個操作系統,他們會問怎樣才能讓他們的系統更快地運行我們的應用程序。另外,我們運營了一個主機託管(hosting)部門,我們希望在爲我們的託管客戶提供最好性能的前提下儘量降低我們的硬件成本。
大多互聯網應用程序都是按照下面的步驟進行工作的:


接受一個TCP/IP連接請求或者與另外一臺計算機建立一個連接;

一旦建立了連接,通過TCP/IP 交換各種各樣基於文本的命令;

這些命令會引發不同的行爲,如讀磁盤(例如瀏覽網頁)、寫磁盤(例如將一條接收到的電子郵件消息進行排隊)或者調用外部功能(例如郵件過濾、反向DNS查找等)。
通常,一個網絡應用程序涉及的性能問題包括:

用盡可能快的速度完成大量的併發任務;

有效地處理大量的等待(由慢速的TCP/IP連接引起或者等待連接的另一端發送下一個命令);

有效地執行TCP/IP操作。
爲了設計最佳性能的網絡應用程序,應用程序的軟件設計人員必需選擇一個充分考慮了上面的性能準則的軟件體系結構。兩個最主要的因素是任務體系結構和TCP/IP調用體系結構。
任務體系結構
在任務體系結構領域,有三個主要的技術:

每個任務一個進程(面向進程的)——運行程序的很多複本,每個複本每次只處理一個任務。有時候,每次創建一個新任務都需要相應地創建一個新的進程(如inetd、Sendmail),但有些也設計成可以重用進程(如Apache)。這種體系結構在低負載的情況下會產生很好的性能。在運行中等程度的負載時,如果進程影象比較小(如qmail)、已經實現了針對該應用程序的效率改進或者該類型的應用程序不會創建太多的同時任務時,其性能也還可以。如果採用了進程緩衝技術並且同時運行的進程總數不是很多(如中低程度的負載),就可以採用多CPU來解決問題。這種技術在所有的操作系統上都可以實現,然而,從實現的的角度講,UNIX明顯地要比Windows更有效。(Windows沒有fork()系統調用,很少有Windows應用程序採用這種技術,因爲它在Windows上實在太慢了)。

每個任務一個線程(多線程)——只運行該程序的一個複本,在這個複本中,每個任務都由一個單獨的執行線程來處理。多線程應用程序在低-中負載情況下的性能非常好,在更高的負載下,其性能就明顯下降了(但通常也是可以接受的)。然而,超高負載會將多線程應用程序帶入死亡旋渦(death-spiral)。通常情況下,多線程應用程序最多可以處理500到1000個併發的任務。這在大多情況下是可以接受的。每個新認爲使用一個新的線程,相對於新進程而言,新線程消耗更少的內存和更少的CPU處理能力。僅僅最流行的UNIX變種(通常是商用操作系統)才能夠在沉重的多線程負載下保持穩定,所以很少有開放源碼工程採用多線程技術。這種技術在多CPU上的性能可能比在單CPU上的性能還要差,因爲多處理器計算機上的信號量(semaphore)鎖處理的代價非常高。(多線程軟件的例子有Netscape Web server和Apache on Windows)

一個線程處理多個任務(異步處理)——程序的一個複本運行固定數量的線程(通常每種類型的任務對應一個線程),每個線程通過一種稱爲異步(非阻塞)TCP/IP的技術處理大量的同類型任務。因爲大多數程序根本不需要處理高負載,並且異步編程非常困難,所以很少有支持這種技術的程序出現。異步程序可以在多CPU計算機上平滑擴展,因爲它們大多采用彼此獨立的長效線程。這種技術很少需要跨CPU的鎖,因此每個線程都可以永久且有效地分配給一個單獨的CPU(如DNS BIND守侯進程daemon)

TCP/IP調用體系結構
第二個影響性能的主要因素是TCP/IP調用體系結構。在操作系統級,有多種方法可以實現相同的網絡操作。TCP/IP的速度與優化程序設計之間存在着權衡的問題(更快的技術對編程人員來說意味着更多的工作)。加之,更快的技術並不是對所有的平臺都可用;更高的性能需求可能會限制平臺選擇的自由度。

阻塞式TCP/IP調用
阻塞式TCP/IP調用等待所有被請求的操作完成後立即對結果進行操作。在任務數量比較少時,操作結果會在事件發生時立即予以響應;但在任務數量比較大的情況下,會導致操作系統的巨量上下文切換系統開銷,這時的效率相當低。在低負載的情況下,阻塞(同步)TCP/IP調用產生很少的等待時間,這對低負載的Web服務器一類的應用來說非常理想(頁面響應非常迅速,條件是負載永遠不會太高)。然而,如果使用的是面向進程的體系結構,且每一個新的網絡連接都要建立一個相應的新進程(如inetd)時,阻塞TCP/IP所帶來的等待時間上的性能就會被運行一個新進程所導致的顯著的系統調用迅速抵消。

非阻塞TCP/IP調用
非阻塞(異步)TCP/IP調用發起一個操作後就轉而進行其它的工作。當操作完成或者發生了一個事件,這個進程就會獲得通知並進行相應的響應。這種兩不處理模式需要更多的編程工作,有時響應新事件會花費少量的時間(增加了等待延時)。在中-高負載的情況下,這種非阻塞技術會產生更好的執行性能,並且可以避免討厭的高負荷,但同阻塞TCP/IP調用相比,等待延時可能稍微長了點兒。
上述的每一個任務處理體系結構都與相應的TCP/IP系統調用模型相匹配。面向進程和多線程的程序可能會趨向於採用阻塞TCP/IP調用,因爲這是編程的最簡單方法並且大多數情況下只需要處理低負載。然而採用異步任務體系結構的應用程序就必需使用非阻塞的TCP/IP操作以處理多任務了:根本不能選擇阻塞TCP/IP。因此,如果您發現一個網絡應用程序採用了高度可擴展的異步任務體系結構,您當然也是從其所採用的最具擴展性的TCP/IP調用體系結構(非阻塞)上獲得了不少好處。

真實環境測試
爲了評估不同操作系統和網絡應用程序的性能,我們進行了三類不同的測試:真實環境、磁盤I/O和任務體系結構比較。我們檢測的操作系統包括Linux (Red Hat 7.0, kernel 2.2.16-22)、Solaris 2.8 for Intel、FreeBSD 4.2和Windows 2000 Server。這些操作系統都是可獲得的商業版本中最新的,並且沒有重新編譯(或者說我們將操作系統軟件開包安裝後就進行了測試)。我們在相同的4-GB SCSI-3驅動器上(IBM 型號是 DCAS-34330)安裝了上述操作系統,並且在相同的機器(ASUS P3B主板、Intel Pentium III 550-MHz處理器、384-MB SDRAM、Adaptec 2940UW SCSI控制器、ATI Rage Pro 3D顯卡、Intel EtherExpress Pro 10/100 Ethernet網卡)上進行測試。
我們採用測試我們自己開發的MailEngine軟件的郵件發送速度來進行真實環境測試。MailEngine是一個郵件發送服務器,它可以移植到所有要進行測試的平臺上(其實還包括Sparc上的Solaris),它採用的是異步體系結構(帶有采用poll()系統調用的非阻塞TCP/IP)。爲了不將電子郵件真的發送到具有200,000個成員的測試列表,我們是在測試模式下運行的MailEngine。在這種模式下,MailEngine實現發送郵件的所有步驟但是最後使用RSET命令而不是DATA命令。這樣就在真正發送數據之前退出QUIT了SMTP連接,這樣就不會向接收者發送任何電子郵件了。我們的工作量是將一條消息發送到分佈在9113個域下的200,000個電子郵件地址。因爲是同一條消息在內存中爲所有的接收者進行排隊,所以磁盤I/O並不是影響性能的主要因素。我們緩慢地提高同時連接的數量,以便觀察負載的提升對性能的影響。

 


圖1 操作系統的比較

圖1(操作系統的比較)顯示了在MailEngine的測試模式中,不同操作系統上一定範圍的同時連接數量下的電子郵件傳輸速度的測試結果。Linux在速度上佔有明顯的優勢,它比排在第二位的Solaris快約35%。總體上來說,性能隨着連接數量的增加而提高,這張圖也顯示速度的增長邊際超過1500個連接。FreeBSD在加到多於1500個連接時的性能會有些下降。
在UNIX風格的操作系統上,需要適當的調整內核以便允許在一個進程中使用如此多的連接。除內核調整外,當負載超過2500個連接時,FreeBSD還會給出資源不足的警告並且停止運行。

文件系統測試
許多網絡應用程序同樣需要將信息在硬盤上進行排隊以便以後處理(如Sendmail的郵件隊列)或處理溢出情況的能力。爲了模仿在典型情況文件系統的效率,我們寫了一個在單個目錄下創建、寫入和讀回10,000個文件的C++程序,它每次只操作一個文件。爲了全面測試文件系統對不同種類文件的整體效率,測試文件的大小從4 KB到128 KB遞增。

 


圖2 創建、寫和讀10,000個文件所需要的時間

圖2顯示了文件系統的測試結果。Linux和Windows的速度基本相同,它們都比另外兩個明顯地快得多:是FreeBSD的6倍、Solaris的10倍。每個操作系統所使用的文件系統分別是:Linux - EXT2, Solaris - UFS, Windows 2000 - NTFS, FreeBSD - UFS。其它的文件系統無疑將會產生不同的性能結果。如果您的軟件應用程序嚴重依賴於磁盤,我建議您使用Linux或Windows或者其它運行於FreeBSD或Solaris上的替代文件系統。

應用程序體系結構測試
最後,我們不同的網絡應用程序體系結構在每一操作系統上的表現進行了測試。我們寫了一個簡單的C++服務程序,它對每一個連接請求都給出一個"450 too busy"的響應消息。我們程序測試的三個體系結構是:(1)基於進程的體系結構,對每個連接都產生一個新的進程予以處理;(2)多線程體系結構,爲每個進程分配一個線程;(3)異步體系結構,所有連接都使用非阻塞的TCP/IP予以應答。一個獨立的C++程序運行在另外一臺計算機(使用Linux操作系統)上,它試圖以最快的速度連接我們的服務器,緩慢增加同時的連接負載並且計算成功接收的響應信息。對於本文來說,這麼多的測試結果圖(12個)顯然太多了,因此我們繪製了每個任務體系結構的平均值以便顯示大體上的性能差異。

 


圖3 每種網絡結構的平均吞吐量

圖3顯示了每種類型的任務體系結構在所有操作系統平臺上的平均性能。雖然不同平臺上性能的差異是非常明顯的,但其顯著性與體系結構的選擇所造成的顯著性差異還是相去甚遠。最慢的網絡應用體系結構是基於進程的結構,它對連接的處理能力只有異步方法的5%。在1000個同時連接的情況下,同基於線程的方法相比,異步方法的負載能力要高出35%。趨勢線顯示,隨着負載的增長,多線程方法與異步方法之間的性能差異將拉大。

爲高性能應用進行內核調整
在缺省配置中,我們測試的UNIX風格的操作系統並不支持多線程和異步程序所需要的如此大量的同時TCP/IP連接。這種限制嚴重地限制了應用程序的性能,甚至錯誤地規勸系統管理員不要採用這些高性能體系結構。值得慶幸的是,這些限制可以容易地通過內核調整來克服。在UNIX上,每個TCP/IP連接使用一個文件描述符,所以您必需提高操作系統上可以提供的文件描述符的總量,同時也要提高每個進程允許使用的描述符的最大值。所有的UNIX風格的操作系統都有一個ulimit的shell命令(sh和bash),這個命令可以讓使用它進行了適當的內核調整之後的shell上運行的命令可以打開更多的文件描述符。我們建議使用ulimit -n 8192。這裏是我們推薦的內核調整過程:
在Linux上: echo 65536 > /proc/sys/fs/file-max改變系統可提供的文件描述符的數量。
在FreeBSD上:將下面這些內容追加到 /etc/sysctl 文件的末尾(或者,您可以使用 sysctl -w 命令來填加這些內容):
kern.maxfiles=65536
kern.maxfilesperproc=32768
在Solaris上:將下面的內容加入 /etc/system 文件後reboot:
set rlim_fd_max=0x8000
set rlim_fd_cur=0x8000

提要
我們的真實環境測試顯示,操作系統最好與最差的性能差距達到了75%,Linux擁有比排在第二位的Solaris還要高出35%的卓越性能。更重要的是,異步應用程序比基於進程的應用程序平均快12倍,比多線程的應用程序快35%。如果磁盤I/O佔用了應用程序運行時間的主要部分,那麼在Linux和Windows 2000上的磁盤I/O任務的處理速度要比Solaris快10倍以上,比FreeBSD也要快出6倍之多!
如果您正在評估一個網絡應用軟件,並且它的最終性能對您來說至關重要,那麼軟件的體系結構將是一個關鍵的評估準則(或者說,你應該選擇多線程或異步結構)。
 

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