12

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

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

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

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


可能的测量:

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

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


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


2009 年 9 月 6 日添加:上述网络版本命令解决方案的
示例time假想输出可能如下所示:

$ 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

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


添加了 09-06-2009:
看起来我想要的一些东西可以使用 dummynet 来实现,工具(最初)用于测试网络协议......

4

2 回答 2

15

如果我对您的理解正确,您基本上对特定于网络的系统调用的Linux 'strace'简介)感兴趣?

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

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

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

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

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

strace -e trace=open -o results.log

通过向 strace 传递一个额外的 -v 标志,您可以增加其详细程度以获取更多信息(当使用由许多较小的 shell 实用程序和独立工具组成的 git 等 SCM 时,您可能还需要考虑使用 - f 标志,以便也遵循分叉进程)。

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

  • 接受
  • 绑定
  • 连接
  • 获取对等名称
  • 获取名称
  • getockopt
  • 收视率
  • 接收来自
  • 发送
  • 发送至
  • 套索选择
  • 关闭
  • 插座
  • 套接字对

(一开始,您可能只想考虑处理 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\n位置: 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。请注意,这与 write(2) 系统调用的正常跟踪无关,后者由选项 -e trace=write 控制。

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

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

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

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

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

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

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

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

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

此外,python 当然也有扭曲

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

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

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

于 2009-06-05T21:54:27.153 回答
5

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

于 2009-06-16T18:14:18.300 回答