Le 7/12/12 11:21 AM, Lilinfeng a écrit :
Hi:
Hi !

Good afternoon.

I am a system designer at HUAWEI.

In recent 3 years, I have been using the Java NIO to develop high performance 
service gate way,
Like SMS/MMS/WAP PUSH Gateway.

This year, I do the technology selection for the industry mature NIO framework, 
such as Mina/Netty/NioFramwork/XSoket etc.
I found that Mina is the most outstanding architecture.

After reading the source code and performance test, I found there are some 
optimization point.

Listed as follows:

The receiver buffer:

When we do reading operator, every time we create a new ByteBuffer for reading 
bytes from SoketChannel, in long connection protocol,
Such as SMPP, frequently creating and destroy byte array will reduce the 
performance. In fact , we can create a cache buffer in the session
As a attribute. After performance testing, this will improve performance over 
20%(Long connect protocol).

This is not obvious. I mean, yes, possibily, when doing some specific tests you will demonstrate that it can save some CPU, but on the other hand, you may lose something else : for instance, keeping a ByteBuffer in a cache means each session will keep a ByteBuffer, until the session is closed. If you have tens of thousand sessions, with a 10k buffer for instance, that means you'll keep 100Mb of memory allocated just for that purpose. Not sure that it's sustainable in the long term.

I would say that we have to balance the advantage such a solution brings with the drawbacks taht come with.

Decode half package(some Frames condition):

If the receive buffer is only a part of a message, we will use the 
CumulativeProtocolDecoder class Solve it, we will cache the left buffer to
Session. If there are large number of half package scene, this will lead to 
frequently creating and destroy byte buffer, this is not a best choice.
You can workaround this problem by using a different decoder. The CumulativeProtocolDecoder is handy, as it does the job for you, but in some cases, it's not efficient. In LDAP (ApacheDS project), we don't use the CumulativeProtocolDecoder, we do process the bytes has they arrive, and if the message is not complete, then we stop decoding until we get some more bytes. We don't keep the ByteBuffer, we don't expand it, we just construct the resulting message while decoding the bytes.

It's a bit more complex, but it gives excellent results.



In fact, before every looping, we mark the IoBuffer for record the first 
package position, when the decode return false, we rest the IoBuffer to
The original position then return for receiving the next package. This will 
reduce the times of IoBuffer creating and simple the process.
But you will have to copy the first part of the message somewhere in memory. Likely in a byte[]. You are swapping the creation of a ByteBuffer for the creation of a temporary storage...

I don't know which version of MINA you are using, nor the JVM version you are running your test on, but one thing to recall is that with the latest JVMs, creating an object is an extremelly cheap operation, something probably cheaper than any other mechanism you may think of to avoid creating such objects.

I'm not saying that to put down your ideas, some of them may be interesting (I'm specifically thinking about caching *at least* a limited size ByteBuffer withing every session, so that you spare the BB creation for most of the received data), it's just that we have to carefully evaluate the advantage we will get from applying them compared to what we may lose on the other side...

Many thanks for those suggestions, and let's discuss them a bit further !

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com

Reply via email to