影响java nio框架性能的因数 (转)

本文探讨了使用Kilim实现RPC框架时的NIO性能优化策略,包括轻量级调度器的应用及减少线程切换的方法。对比了Kilim与Mina在处理读写操作时的不同技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近打算用kilim做一个rpc框架, kilim有自己的nio框架 而在业界有强劲的netty和mina。
所以问了一下kilim的作者,他的回答说 因为底层用的都是java nio的api,所以留给nio框架最
主要的问题是这2点
(i) 为了处理很多socket连接和优化吞吐量,会导致了大量的线程切换。
Amount of thread switching done to handle n numbers of sockets and
optimizing for throughput.

(ii) 有很多次的selector的中断和调用,唤醒seletor是很费资源的操作。

所以能做的优化有以下几点:
1,对read writer process操作分别作轻量级的scheduler,基于actor。
2,有个trick,就是read或者write操作时候,但没有读满或者写完的情况下,并不是
立即返回并再次注册channel到selector,而是再尝试若干次(3次),再返回并注册到
selector。在mina中也有同样的处理。不同之处在于kilim会yield的当前task,而mina为
了避免线程切换,只是做了简单的while循环。但目的都是减少线程切换和避免多次注册
selector。
mina 处理代码
Java代码
for (int i = WRITE_SPIN_COUNT; i > 0; i --)
{
localWrittenBytes = ch.write(buf.buf());
if (localWrittenBytes != 0 || !buf.hasRemaining())
{
break;
}
}


kilim nio的处理
Java代码
while (remaining > 0)
{
if (n == 0)
{
yieldCount++;
if (yieldCount < YIELD_COUNT)
{
Task.yield(); // don't go back to selector yet.
} else
{
pauseUntilWritable();
yieldCount = 0;
}
}
n = ch.write(buf);
remaining -= n;
}

除了上面说的2个因素以外,还有有哪些因素会影响nio的性能?

原文如下:
I have not tested netty, but here's my experience. All NIO frameworks,
Kilim included, are comparable because they use the same underlying
NIO API. The difference in performance _may_ stem from the following
two sources:

(i) Amount of thread switching done to handle n numbers of sockets and
optimizing for throughput.

(ii) Number of times the selector is interrupted and invoked. Waking
up the selector is an expensive operation.

The first one is entirely up to the user of the Kilim NIO library. A
typical server request consists of one or more reads to accumulate the
frame, processing the packet, and one or more writes to write a packet
to the socket. One can split up this work between multiple schedulers
if you wish. By default, all reading and writing is done outside of
the selector's thread. Which brings me to the next point.

I have optimized the access to the selector, by avoiding using it as
much as possible. If a socket read or write is unable to transfer any
bytes, then the task simply yields. Other runnable tasks get a chance
to run. When the task is subsequently resumed, it retries the
operation. This goes on for a fixed number of times (3), and if it
still fails, it sends a message to the selector thread to wake it up
whenever the socket is ready. See the comments on kilim.nio.EndPoint.

Please keep us posted about your netty experiments.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值