如何测量网络性能(如何对网络协议进行基准测试)

Posted

技术标签:

【中文标题】如何测量网络性能(如何对网络协议进行基准测试)【英文标题】:How to measure network performance (how to benchmark network protocol) 【发布时间】:2010-10-27 17:11:16 【问题描述】:

首先,有一点背景。分布式版本控制系统 (DVCS) 有许多不同的比较,它们比较存储库的大小或操作的基准速度。我还没有找到任何可以对各种 DVCS 和所使用的各种协议的网络性能进行基准测试的方法……除了测量涉及“克隆”、“拉”/“获取”或“推”等网络的操作(命令)的速度。

我想知道你会如何进行这样的比较;如何测量应用程序的网络性能,或如何对网络协议进行基准测试。我在这里设想还测量性能对网络带宽和网络延迟(ping 时间)的依赖性;一些协议以更多往返交换(协商)的形式牺牲延迟,以发送所需的最少最终“包”。

如果可能,我更喜欢只涉及一台计算机的解决方案。我希望看到在 Linux 上运行的开源解决方案。但我也欢迎更通用的答案。

首选操作系统:Linux首选语言:C、Perl、shell 脚本


可能的测量:

在一个会话中从服务器到客户端以及从客户端到服务器传输的总字节数;这也可以用来衡量协议的开销(带宽) 一个事务中的往返次数(连接)(延迟) 网络运行速度(克隆/拉/推所需时间)与网络带宽和网络延迟(ping 时间)的相关性

如何进行这样的测量(这样的基准)?


2009 年 2 月 6 日添加: 一个最简单的基准测试(测量)是time 命令的网络版本,即运行的命令会给我传输的字节数,以及执行给定命令期间的往返/网络连接数。


添加于 09-06-2009:示例上述time 命令的网络版本解决方案的假想输出可能如下所示: p>

$ ntime git clone -q git://git.example.com/repo.git
...
bytes sent: nnn (nn kiB), bytes received: nnn (nn kiB), avg: nn.nn KB/s
nn reads, nn writes

请注意,这只是一个示例输出,详细说明了人们可能想要获取的信息。


2009 年 9 月 6 日添加: 看起来我想要的一些东西可以使用 dummynet 来实现,这个工具(最初)用于测试网络协议...

【问题讨论】:

您是在问,如何获取所需的数据以便为任意网络程序提供这样的基准? 是的,我希望至少获得传输的总字节数以及给定命令从读取到写入的更改数,例如 CPU 和内存的时间/次,以及 SystemTap I/O 的 iotimes。 我认为要真正回答您的问题,您最好告诉我们更多关于您的首选平台/操作系统以及您首选的编程语言的信息。此外,您感兴趣的详细测量列表将告诉我们哪种方法最可行。 已添加。首选操作系统是 Linux,首选语言包括(无序)C、Perl、shell 脚本,但可以是 Python 或 Java,或其他编程语言。 【参考方案1】:

如果我对您的理解正确,您基本上对诸如 Linux 'strace' (Introduction) 之类的网络特定系统调用感兴趣?

可能是分析器和调试器的组合,用于网络应用程序(即“ntrace”),提供各种可选测量的详细分析?

在 Linux 下,strace 实用程序主要基于 Linux 内核提供的功能,即ptrace (process tracing) API:

Process Tracing Using Ptrace Playing with ptrace - part I Playing with ptrace - part II System Call Tracing using ptrace Bytecode Injection into a Running Process using Ptrace() Better process control in Linux with an improved ptrace()

使用ptrace,应该可以获取大部分你感兴趣的数据。

在 Windows 上,您可能需要查看 detours 以拦截/重定向 Winsock API 调用以进行检查/基准测试。

如果您真的不需要那么多低级信息,您也可以直接使用 strace(在 linux 上)并仅使用它来跟踪某些系统调用,例如考虑以下仅跟踪调用的行open 系统调用(使用附加的 -o FILE 参数,您可以将所有输出重定向到输出文件):

strace -e trace=open -o results.log

通过向 strace 传递一个额外的 -v 标志,您可以增加它的详细程度以获取更多信息(当使用 git 等由许多较小的 shell 实用程序和独立工具组成的 SCM 时,您可能还想查看使用 -f 标志来跟踪分叉进程)。

所以,您会感兴趣的是与sockets 相关的所有系统调用,即:

接受 绑定 连接 getpeername getsockname getsockopt 听 接收 recvfrom 发送 发送到 setsockopt 关机 插座 套接字对

(虽然一开始,您可能只想研究处理 send.../recv... 调用)

为了简化这一点,您还可以使用“network”作为参数进行跟踪,这将跟踪所有与网络相关的调用:

-e trace=network:跟踪所有网络相关的系统调用。

因此,相应的 strace 调用可能如下所示:

strace -v -e trace=accept,bind,connect,getpeername,getsockname,getsockopt,listen,recv,recvfrom,send,sendto setsockopt,shutdown,socket,socketpair -o results.log -f git pull

程序运行完毕后,你主要想检查日志文件以评估数据,这可以通过使用正则表达式轻松实现。

例如,在 linux shell 中运行以下命令时: strace -v -o wget.log -e trace=connect,recv,recvfrom,send,sendto wget http://www.google.com

生成的日志文件包含如下消息:

recv(3, "HTTP/1.0 302 Found\r\nLocation: htt"..., 511, MSG_PEEK) = 511 发送至(4, "\24\0\0\0\26\0\1\3^\206*J\0\0\0\0\0\0\0\0"..., 20, 0, sa_family=AF_NETLINK, pid=0, groups=00000000, 12) = 20

查看这两个系统调用的手册页,很明显 511 和 20 分别是传输的字节数。如果您还需要详细的时序信息,可以将 -T 标志传递给 strace:

-T -- 打印每个系统调用所花费的时间

另外,你可以通过传递 -c 标志来获取一些统计信息:

-c:计算每个系统调用的时间、调用和错误,并报告程序摘要 出口。在 Linux 上,这会尝试显示系统时间(在内核中运行的 CPU 时间) 独立于挂钟时间。如果 -c 与 -f 或 -F(如下)一起使用,则仅聚合 保留所有跟踪过程的总数。

如果您还需要检查实际处理的数据,您可能需要查看读/写说明符:

-e read=set:对从文件中读取的所有数据执行完整的十六进制和 ASCII 转储 指定集合中列出的描述符。例如,查看文件上的所有输入活动 描述符 3 和 5 使用 -e read=3,5。请注意,这与正常情况无关 跟踪由选项 -e trace=read 控制的 read(2) 系统调用。 -e write=set:对写入文件的所有数据执行完整的十六进制和 ASCII 转储 指定集合中列出的描述符。例如,查看文件上的所有输出活动 描述符 3 和 5 使用 -e write=3,5。请注意,这与正常情况无关 跟踪由选项 -e trace=write 控制的 write(2) 系统调用。

您还可以自定义字符串的最大长度:

-s strsize:指定要打印的最大字符串大小(默认为 32)。注意 文件名不被视为字符串,总是完整打印

或者将字符串转储为十六进制:

-xx:以十六进制字符串格式打印所有字符串。

因此,在大部分情况下使用 strace 似乎是一种很好的混合方法,因为它很容易做到,但仍然有大量可用的低级信息,如果您发现需要额外的低级信息,您可能需要考虑扩展 strace 或使用 strace project on sourceforge 提交相应的功能请求。

但是,想一想,实现相当简单的网络流量基准的一种涉及较少且与平台无关的方法是在客户端和实际服务器之间使用某种形式的中间层:服务器这基本上是计量、分析流量并将其重定向到真实服务器。

很像代理服务器(例如SOCKS),因此所有流量都通过您的分析器进行隧道传输,进而可以累积统计数据和其他指标。

这样的基本版本可能只需使用 netcat 和一些 shell 脚本就可以很容易地组合在一起,但是更复杂的版本可能会受益于使用 perl 或 python。

对于 SOCKS 服务器的 python 实现,您可能需要查看pysocks。

另外,python 当然还有twisted:

Twisted 是一个用 Python 编写的事件驱动的网络引擎 并在 MIT 许可下获得许可。

如果您确实需要更多低级信息,那么您可能真的想研究拦截系统调用。

如果您还需要特定协议的效率数据,您可能需要查看tcpdump。

【讨论】:

【参考方案2】:

可能的答案是使用 SystemTap。在示例脚本中,nettop 以类似“顶部”的方式显示(部分)所需的网络信息,iotime 脚本以所需的形式显示 I/O 信息。

【讨论】:

以上是关于如何测量网络性能(如何对网络协议进行基准测试)的主要内容,如果未能解决你的问题,请参考以下文章

Ceph:网络性能基线测试

如何对C ++代码的性能进行基准测试? [关闭]

SylixOS网络性能测试

SylixOS网络性能测试

SylixOS网络性能测试

SylixOS网络性能测试