对于大型ByteBuffers,单独的SocketChannel的并发read()速度较慢

时间:2012-02-26 15:26:30

标签: java performance concurrency socketchannel

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

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

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

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

1 个答案:

答案 0 :(得分:1)

  

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

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

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