评测 表1.服务器使用率评测[td]方法 | 已处理的应答 | SACK 处理过程中扫描的包 | 经历的时间 | CPU 使用率 | 每个应答取样的滴答数 | 每传输 1KB 取样的滴答数 | 平均重传队列长度 | 基准 | 252,955 | 0 | 1:02 | 22% | 1.72 | 0.56 | 5 | 定制,不启用 SACK | 498,275 | 0 | 2:59 | 9% | 1.47 | 1.03 | 7,000 - 10,000 | 定制,启用 SACK | 534,202 | 755,368,500 | 12:47 | 33% | 10.87 | 8.13 | 1,414 |
误导数据可以很容易地解释一些令人惊讶的数据点。
请注意定制的客户机的应答数很高,大约是基准 wget 的二倍。原因是定制的客户机的设计目的是进一步恶化服务器行为。因此,它不会对应答进行合并。如果两个相邻的应答不包括任何数据,则大多数 TCP 协议栈都会把两个应答合并成一个。定制的客户机可以提供这样的选项,但对于这个数据,没有启用这个选项。在启用此选项的情况下又进行了一次测量,结果证明这并不能从本质上影响结果。要想了解原因,请阅读下面的 小节。
读者也会注意到这样一个现象:触发 SACK 路径的节点每传输 1KB 的数据的滴答数是基准数的 16 倍之高,但 CPU 使用率的差异只为 1.5,比较适中。另一个关键的数据集是测试经历的时间。基准占用了 22% 的 CPU,占用时间为一分钟多一点,而启用 SACK 选项的客户机占用了 33% 的 CPU,占用时间为 13 分钟左右。最终,启用 SACK 选项的客户机每传输同样数目的数据会占用更多的 CPU 周期。
乍看起来,这些测量值看起来并不是非常糟糕。虽然在攻击过程中 CPU 使用率达到 33%,但它并没有完全耗尽。如果 CPU 被完全占用,其它工作就无法完成,这会造成拒绝服务。
遗憾的是,深入分析这些数据则会出现问题。总的传输时间达到:从基准的 1 分钟达到完全攻击场景中的 13 分钟。另外,与基准的 1 分钟不同,在全部的 13 分钟内,增加的 CPU 使用率一直保持较高的值。整体上而言,达到同样的目标需要花费更多的 CPU 周期。您可通过比较三种数据点中每传输 1KB 数据的取样滴答数清晰地看到这一点。
继续深入分析会发现 33% 的 CPU 使用率会误导我们。13 分钟内包括一个反复的 CPU 激增循环,在这期间,整个服务器的占用率为 100%。这些 CPU 激增之后,CPU 使用趋于平稳,然后进行下一次循环。总体结果是平均使用率为 33%,但很长一段时间内 CPU 被远程主机触发的 TCP 处理完全占用。
考虑这三种场景下 CPU 占用率和时间图:
图 1. 不启用 SACK 时使用 wget 的基准评测基准评测结果良好并且效率很高。传输很快完成并充分利用了可用带宽,而任何时刻 CPU 的占用率都未超过 25%。这证明了这类中等服务器在适合的环境下可以很好地利用网络。
图 2. 未启用 SACK 选项的大窗口定制客户机定制客户机在未启用 SACK 的情况下也会生成一个合理的使用率图。管理大窗口的复杂性以及不可避免的损失将导致更多的 CPU 被占用,但在任何时刻,服务器都能保持正常运行。
图 3. 启用 SACK 选项的大窗口定制客户机您肯定会被启用 SACK 的下载具有如此高的 CPU 使用率所震惊。虽然整体使用率均值为 33%,图中清晰地显示出反复出现的 CPU 峰值,在这期间服务器被全部占用。
图中反复描绘曲线 y=x^2 直到 y=100%。这表明每个 SACK 选项需要扫描整个重传队列以便找到它指向的数据。当发送方的拥塞窗口增大时,它会在发送出一个包和收到应答之间的时间内成倍地增加传输中的包的数目。对每个接收到的 SACK 选项都需要对这种翻倍的队列进行检查。令人惊讶的是,收到 50 万个应答的情况下,SACK 处理需要执行 7.55 亿次包比较。这种算法造成图呈现指数形式。
使用更大的服务器实验最初的问题是仅仅用了普通的 1.2GHz Athlon 处理器作为服务器。这似乎低估了服务器端的处理能力。
可是,测试更快的服务器或实现优化(如把两个应答合并为一个)无法使这里看到的二次曲线有所改善。这种改变将使拥塞窗口超出这些评测中看到的 3200 个包的限制,但是服务器端的 CPU 使用率的曲辊式增长在将窗口增至 10000 或更高(这对充塞快速以太网是必要的)之前仍然会达到最大。
最后的疑惑是为什么这对服务器而言不是灾难性的。可以想象到使用率增加到 100% 并在随后的传输过程中保持这一水平。可是,我们却看到一系列呈周期性的使用率。这似乎不象是重传队列正在缩短。或者正是这样?
实际上,重传队列确实是周期性地一直减少到 0 个包。此时这个过程重新开始,拥塞窗口又一次增大,而 SACK 开销也是如此。整个过程在几秒种后又会达到可以影响服务器 CPU 使用率的大小。
队列开始减少,原因是高峰时大量的处理量触发了 TCP 基于超时的恢复机制。栈对超时的响应是把拥塞窗口重设回空状态。这个新的小窗口对传输速度有所阻碍,但当窗口再次增长到危险边缘时能保持服务器有效并可处理其它工作。 |