【问题标题】:Socket performance on linuxlinux上的套接字性能
【发布时间】:2011-03-21 16:56:36
【问题描述】:

接着我的上一个问题:

Performance issue using Javas Object streams with Sockets

我正在研究 Linux 上的套接字性能。在上面的例子中,我得到了~65μsec 的往返时间。如果我在文件系统上创建两个 fifo,这将下降到 ~45μsec。使用 localhost 套接字的额外时间一定是因为我正在访问网络堆栈。

是否有一些操作系统配置可以使 localhost 套接字与命名管道一样快?

uname -a
Linux fiatpap1d 2.4.21-63.ELhugemem #1 SMP Wed Oct 28 23:12:58 EDT 2009 i686 athlon i386 GNU/Linux

提前致谢!

【问题讨论】:

  • 您使用的是基于 2.4 的内核?这是问题的一部分。
  • 是的,我还在用电唱机;)你知道更高版本的内核是否会以不同的方式优化本地网络流量吗?
  • 可能不是,您能解释一下为什么不适合使用命名管道吗?您是否尝试过使用 UDP 而不是 TCP? (DatagramSocket)
  • 除了我的 java 应用程序之外,使用命名管道没有任何问题将不再是可移植的。不热衷于 UDP,因为我需要更多的弹性。

标签: java linux sockets


【解决方案1】:

在上面的例子中,我得到了~65μsec 的往返时间。如果我在文件系统上创建两个 fifo,这将下降到 ~45μsec。使用 localhost 套接字的额外时间一定是因为我正在访问网络堆栈。

是的,这是意料之中的。

FIFO 是相当原始的通信方法。它们的状态本质上是一个布尔变量。读取和写入通过相同的固定大小的预分配缓冲区。因此,操作系统可以并且确实优化了操作。

套接字更复杂。他们拥有成熟的 TCP 状态机。缓冲是动态的和双向的(接收、发送分别缓冲)。这意味着当您将某些内容写入本地套接字时,您几乎总是会涉及某种动态内存管理。 Linux 试图尽可能避免这种情况:零拷贝/单拷贝技巧在各处都实施。然而显然,由于调用必须通过更多代码,它们会更慢。

最后,考虑到套接字与 FIFO 相比,20us 的差异坦率地说明了 Linux 的套接字性能有多好。

附: 65us rtt = ~35us 在一个方向。 1s/35us =~ 每秒 30K 个数据包。对于没有使用单个连接进行优化的网络代码,听起来很正确。

【讨论】:

    【解决方案2】:

    我无法在 Java 方面为您提供帮助,但您可以看看 UNIX 域套接字。这是一个关于如何在 Java 中使用它们的问题:

    UNIX socket implementation for Java?

    【讨论】:

    • 是的,我可以使用基于 jni 的东西。如果可能的话,我宁愿不这样做。我希望一些更高版本的 Linux 会为我做这个优化。
    【解决方案3】:

    你之前的问题做了两个错误的假设:

    1. ICMP_ECHO(又名 ping)产生有意义的时序信息。它不会,因为除其他外,ICMP 层可以(并且应该)处于低服务优先级。
    2. 通过无数 Java 接口编组数据并不是瓶颈。因为它是。

    您的测试方法非常可疑。你想完成什么?

    【讨论】:

    • 见鬼。很好的答案。该死的那些无数 Java 接口及其性能成本。
    • On 1. ping 给了我〜与我使用命名管道进行测试的时间相同。关于 2。您是如何得出这个结论的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2011-01-19
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多