【问题标题】:Concurrent read() of separate SocketChannels slow for large ByteBuffers [closed]对于大型ByteBuffers,单独的SocketChannels的并发读取()速度很慢[关闭]
【发布时间】:2012-02-26 15:26:30
【问题描述】:

我编写了一个用于远程存储的 Java 服务器(一个 iSCSI 目标)。客户端可以通过发送携带数据有效负载的数据包序列来写入数据。这些数据包由一个固定长度的报头(48 个字节)和一个可变长度的数据段组成。数据段的长度在头部指定,可以认为是固定的(8KiB)。

接收数据包是一个由两部分组成的过程。首先将标头读取到大小为 48 字节的 ByteBuffer 中。之后立即通过 ByteBuffer.allocate(...) 创建第二个 ByteBuffer。第二个缓冲区的大小与标头中指定的数据段长度相匹配。然后使用 SocketChannel.read(ByteBuffer) 方法将数据段读入第二个 ByteBuffer。在简单的情况下,此过程按预期工作 - 更大的数据段和更长的序列会提高 IO 速度。 “简单情况”是指有一个线程使用阻塞的 SocketChannel 来接收(和处理)数据包。但是,如果添加第二个具有自己的 TCP 连接和关联的 SocketChannel 的线程,SockerChannel.read(ByteBuffer) 执行时间会上升到 2.5 毫秒以上,而客户端服务器在两者上都发送 32KiB 写入命令(即 4 个连续数据包)连接。这增加了 8 到 10 倍。

我想强调的是,在这个阶段,除了同一个网络接口卡之外,两个线程不共享任何资源。每个 SocketChannel 的读取缓冲区大小为 43690 字节(较大的大小对这种现象没有任何影响)。

任何想法可能导致此问题或如何解决此问题?

【问题讨论】:

    标签: java performance concurrency socketchannel


    【解决方案1】:

    ...当客户端服务器发送 32KiB 写入命令时(即 4 两个连接上的连续数据包)。

    您能否提供一些有关测试设置的详细信息?客户端是否将数据包串行发送到两个连接?然后根据设置,增加可能是客户端驱动的。

    是本地主机设置(一台机器上的客户端和服务器)还是不同主机上的客户端和服务器?你都测试过吗?不要欺骗自己在 localhost 设置中看到执行时间增加,特别是如果只有一个 cpu 并且测试客户端也在本地运行,甚至可能是单线程的。

    【讨论】:

    • 客户端和服务器运行在不同的机器上,都有大量的空闲内核。但你是对的,错误似乎在于客户端。起初我没有看到这一点,因为我对我的测试软件的质量有太多的信心,并在我的初步测量过程中切换了版本。我将iometer 与 Microsoft iSCSI Initiator 一起使用,其中一个似乎会引入很大的延迟,无论它连接到哪个目标/服务器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多