了解 UNIX® 網路布局會幫助您了解自己的網路及其運行方式。但是,當 UNIX 網路性能和傳輸文件或連接服務的速度突然下降時,究竟發生了什麼?如何診斷網路問題並找到網路中出現問題的地方?本文介紹一些快速發現和識別性能問題的方法以及解決問題的步驟。
簡介
網路的性能對於環境其餘部分的性能和可靠性影響很大。如果應用程序和服務等待通過網路傳輸的數據,或者客戶機無法連接它們或接收信息,就需要解決這些問題。
性能問題還會影響應用程序和環境的可靠性。性能問題可能由網路故障導致,在某些情況下性能問題甚至是網路故障的原因。要想了解和診斷網路問題,首先需要了解問題的性質;問題往往與延時或帶寬相關。
在一般情況下,網路性能問題常常與底層硬體有關;無法突破網路環境的物理限制。所有性能問題還常常與某種協議或系統相關,比如 NFS 或 Web 訪問。但是,可以在操作系統中診斷和識別問題,決定正確的糾正措施。
本文討論識別性能問題涉及的幾個步驟:
了解網路指標
要想了解和診斷性能問題,首先需要確定基線性能水平。首先介紹在判斷基線性能時使用的兩個重要概念:網路延時和網路帶寬。
網路延時
網路延時是向目的地發送請求到目的地實際接收到數據包之間的時間間隔。作為網路性能指標,延時增加說明網路繁忙,這意味著要傳輸的數據包數量超過了傳輸能力,數據的發送者在傳輸或重新傳輸之前必須等待。
當網路的複雜性以及數據包要經過的主機或網關數量增加時,也會增加網路延時。點之間的線纜長度也會影響延時。對於長距離線路,傳統的銅線總是比光纖連接慢。
網路延時與應用程序延時不同。網路延時只與通過網路傳輸數據包相關,而應用程序延時是指應用程序接收請求到它做出響應之間的時間間隔。
網路帶寬
帶寬表示在特定的一段時間內可以通過網路傳輸的數據包數量。帶寬影響可以傳輸的數據量,它把向一個主機傳輸數據的速度限制為網路連接支持的最大速度,在使用多個併發連接時限制總傳輸速度。
從理論上說,網路帶寬應該不會變,除非改變網路介面和硬體。影響網路帶寬的主要因素是在給定時刻使用網路的主機數量。
例如,1GB 的乙太網介面可以向另一個網路主機傳輸 1GB 數據,或向 10 個主機同時傳輸 100MB,或向 100 個主機同時傳輸 10MB。當然,實際上常常不需要穩定的帶寬。在一段時間內會有來自大量主機的許多小請求,伺服器的可用帶寬看起來可以比客戶機帶寬的總和大得多。
獲得統計數據
在判斷網路中是否發生問題之前,需要先確定基線性能,然後據此做出假設。為此,必須通過檢查各種網路參數(與網路應用程序環境相關的延時、性能和測試)判斷性能,然後監視和對比性能隨時間的變化。
應該在可控制的狀況下執行基線網路測試。在理想情況下,應該在隔離(沒有其他網路通信流)和有典型的網路通信流兩種場景中執行測試,這會提供兩個基線:
對於實際測試過程,可以使用許多標準工具和測試判斷基線值。
測量延時
所有網路管理員都很熟悉 ping 工具,使用它作為檢查網路設備的可用性和延時的基本工具。在大多數機器上都可以使用 ping,包括客戶機和伺服器,只要它們已經配置為對 ping 工具發送給設備的 ICMP 數據包做出響應。簡單地說,ping 向設備發送一個 echo 數據包,期望設備把數據包的內容發送回來。
在這個過程中,ping 可以監視發送數據包和接收響應花費的時間,這是測量 echo 過程的響應時間的有效方法。按照最簡單的形式,可以向一個主機發送 echo 請求並查明響應時間(見清單 1)。
$ ping example PING example.example.pri (192.168.0.2): 56 data bytes 64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.169 ms 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.167 ms ^C --- example.example.pri ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.167/0.168/0.169/0.001 ms |
需要使用 Control-C 停止 ping 過程。在 Solaris 和 AIX® 上,需要使用 -s 選項發送多個 echo 數據包並獲得計時信息。為了獲得基線數據,可以使用 -c 選項(在 Linux® 上)指定數量。在 Solaris/AIX 上,可以指定數據包大小(默認大小為 56 位元組)和要發送的數據包數量,這樣就不必手工終止 ping 過程。然後可以自動地獲得計時信息(見清單 2)。
$ ping -s example 56 10 PING example: 56 data bytes 64 bytes from example.example.pri (192.168.0.2): icmp_seq=0. time=0.143 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=1. time=0.163 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=2. time=0.146 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=3. time=0.134 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=4. time=0.151 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=5. time=0.107 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=6. time=0.142 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=7. time=0.136 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=8. time=0.143 ms 64 bytes from example.example.pri (192.168.0.2): icmp_seq=9. time=0.103 ms ----example PING Statistics---- 10 packets transmitted, 10 packets received, 0% packet loss round-trip (ms) min/avg/max/stddev = 0.103/0.137/0.163/0.019 |
清單 2 中的示例是在網路比較空閑的時候得到的結果。如果在測試期間檢查的主機(或網路本身)比較忙,那麼 ping 時間會顯著增加。只使用 ping 不足以表明是否有問題,但是有時候 ping 可以快速地查明是否有問題需要進一步診斷。
對 ping 的支持可能會禁用,所以在使用 ping 檢查主機是否可用之前應該確認能夠訪問此主機。
理想情況下,應該在一段時間內連續地跟蹤特定主機之間的 ping 時間,這樣就可以得到平均響應時間,然後識別要檢查的位置。
使用 sprayd
sprayd 守護進程和相關聯的 spray 工具向指定的主機發送一個大的數據包流,判斷這些數據包中有多少得到了響應。它是一種測量網路性能的方法,不應該把它當作性能指標,因為它使用無連接的傳輸機制。根據定義,使用無連接傳輸機制發送的數據包並不保證能夠到達目的地,在通信中允許丟失數據包。
使用 spray 可以查明網路上是否有很多通信流,因為如果無連接傳輸 (UDP) 丟失許多數據包,就說明網路(或主機)太忙了。
在 Solaris、AIX 和其他一些 UNIX 平台上可以使用 spray。可能需要啟用 spray 守護進程(通常通過 inetd)。啟動 sprayd 守護進程之後,可以運行 spray 並指定主機名(見清單 3)。
$ spray tiger sending 1162 packets of length 86 to tiger ... 101 packets (8.692%) dropped by tiger 70 packets/sec, 6078 bytes/sec |
正如前面提到的,不應該把速度作為可靠的性能指標,但是丟失的數據包數量是有意義的。
使用簡單的網路傳輸測試
判斷網路帶寬性能的最佳方法是,在與機器收發數據時檢查實際的速度。可以使用許多不同的工具執行跨許多應用程序和協議的測試,但是最簡單的方法往往是最有效的。
例如,為了判斷在使用 NFS 通過網路傳輸文件時的網路帶寬,可以對一個簡單的文件傳輸過程進行計時。為此,使用 mkfile 創建一個大文件(例如使用 $ mkfile 2g 2gbfile 創建一個 2GB 的文件),然後通過網路把它傳輸給另一台機器並計算花費的時間(見清單 4)。
$ time cp /nfs/mysql-live/transient/2gbfile . real 3m45.648s user 0m0.010s sys 0m9.840s |
應該多次運行測試,然後求出傳輸過程的平均時間,從而比較準確地了解性能水平。
可以使用清單 5 這樣的 Perl 腳本自動地執行複製和計時。
#!/usr/bin/perl use Benchmark; use File::Copy; use Data::Dumper; my $file = shift or die "Need a file to copy from\n"; my $srcdir = shift or die "Need a source directory to copy from\n"; my $count = shift || 10; my $t = timeit($count,sub {copy(sprintf("%s/%s",$srcdir,$file),$file)}); printf("Time is %.2fs\n",($t->[0]/$count)); |
[火星人 ] UNIX 網路性能分析已經有744次圍觀