Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a native transport for linux using epoll ET #2229

Closed
wants to merge 1 commit into from

Conversation

normanmaurer
Copy link
Member

This transport use JNI (C) to directly make use of epoll in Edge-Triggered mode for maximal performance on Linux. Beside this it also support using TCP_CORK and produce less GC then the NIO transport using JDK NIO.
It only builds on linux and skip the build if linux is not used. The transport produce a jar which contains all needed .so files for 32bit and 64 bit. The user only need to include the jar as dependency as usually
to make use of it and use the correct classes.

@normanmaurer normanmaurer self-assigned this Feb 13, 2014
@normanmaurer normanmaurer added this to the 4.0.16.Final milestone Feb 13, 2014
@normanmaurer
Copy link
Member Author

@trustin @daschl please review!

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="ISO-8859-15"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

licensed to the ASF ? :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups... :)

Am 13.02.2014 um 15:44 schrieb Matthias Wessendorf notifications@github.com:

In transport-native-epoll/pom.xml:

@@ -0,0 +1,116 @@
+
+<!--

  • Licensed to the Apache Software Foundation (ASF) under one
    licensed to the ASF ? :-)


Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Feb 13, 2014

Build result for #2229 at 0f3ad0d: Failure

@normanmaurer
Copy link
Member Author

@trustin you need to pimp up our CI so it can built it :)

Am 13.02.2014 um 16:03 schrieb trustin-notification notifications@github.com:

Build result for #2229 at 0f3ad0d: Failure


Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Feb 13, 2014

Build result for #2229 at ce897fe: Failure

@ninja-
Copy link

ninja- commented Feb 13, 2014

Interesting...my tries at integrating native code compilation & maven has failed because all maven jni plugins were too buggy(namely: nar-maven-plugin).

Do you have any benchmarks yet @normanmaurer ?

cc @md-5

@normanmaurer
Copy link
Member Author

@ninja- no "official" benchmarks yet, I will write an blog post with benchmarks soon.

To make it short it is faster then "plain nio" and produce less GC.

@ghost
Copy link

ghost commented Feb 13, 2014

Build result for #2229 at e673789: Failure

@trustin
Copy link
Member

trustin commented Feb 14, 2014

I installed necessary tools to the CI machine and the build still fails. It seems like it's related with working directory?

@trustin
Copy link
Member

trustin commented Feb 14, 2014

Nevermind - CI machine did not have tar installed.

@normanmaurer
Copy link
Member Author

From the error it looks like you missed to install autoconf..

Am 14.02.2014 um 03:56 schrieb Trustin Lee notifications@github.com:

I installed necessary tools to the CI machine and the build still fails. It seems like it's related with working directory?


Reply to this email directly or view it on GitHub.

@normanmaurer
Copy link
Member Author

Ok .. All good now? Be sure to install libs for 32 and 64 bit :)

Am 14.02.2014 um 04:09 schrieb Trustin Lee notifications@github.com:

Nevermind - CI machine did not have tar installed.


Reply to this email directly or view it on GitHub.

@normanmaurer
Copy link
Member Author

@trustin I think you are still missing:
yum install glibc-devel.i686

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at e673789: Success

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 74d76b0: Success

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 19bf2ebf802c0ec7008ef1f2aea251c9f312c9de: Success

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 4290d399fcd8f7bf8d98de6225a6b702439af19b: Success

@normanmaurer
Copy link
Member Author

@trustin ok now all bugs are fixed... :)

* Helper class to load JNI resources.
*
*/
public final class JNILoader {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JniLoader

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 872797503b85c9133876fc882585b2cbfb717651: Failure

setOption(env, fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
}

JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_setTCPCork(JNIEnv *env, jclass clazz, jint fd, jint optval) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be setTcpCork? I guess you renamed some methods after generating this header file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes let me fix it

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 2001561b109f613e482e17020f5188800b741ffa: Failure

@trustin
Copy link
Member

trustin commented Feb 14, 2014

Could we also add and support an arbitrary option? We could expose the following operations to a user:

jint getOption(JNIEnv *env, jint fd, int level, int optname, const void *optval, socklen_t optlen)
int setOption(JNIEnv *env, jint fd, int level, int optname, const void *optval, socklen_t len)

For example:

Epoll(Server)SocketChannel.config().setOption(int optName, byte[] optVal)
byte[] option = Epoll(Server)SocketChannel.config().getOption(int optName)

@normanmaurer
Copy link
Member Author

@trustin I guess we could but I would like to be careful and test this in more detail. Just it is not too easy to kill the JVM.

@trustin
Copy link
Member

trustin commented Feb 14, 2014

@normanmaurer I see. Maybe we can add it later when it's on demand.

# sudo yum install autoconf automake libtool glibc-devel.i686 glibc-devel libgcc.i686 make

__Debian(64Bit)__
# sudo apt-get install autoconf automake libtool make gcc-multilib
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this to the dedicated wiki page and add a link to it - just like we did for microbench: https://github.com/netty/netty/blob/master/microbench/README.md

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, you could add some stuff like how to switch to the Epoll transport (and how easy it is) by a simple example.

@normanmaurer
Copy link
Member Author

@trustin so ready to merge ? If so I will squash and merge :)


@Override
public EpollSocketChannelConfig setTrafficClass(int trafficClass) {
return this;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 2f01350fbda9f9d3b0e531af30f4a6ff644c5fa5: Failure

@ghost
Copy link

ghost commented Feb 14, 2014

Build result for #2229 at 455562e12af03ad3b9c2e539f654b4357243769e: Success

super(channel);

this.channel = channel;
setTcpNoDelay(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you wrap this with:

if (PlatformDependent.canEnableTcpNoDelayByDefault()) { .. }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

Am 14.02.2014 um 21:12 schrieb Trustin Lee notifications@github.com:

In transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollSocketChannelConfig.java:

+import static io.netty.channel.ChannelOption.*;
+
+public final class EpollSocketChannelConfig extends DefaultChannelConfig

  •    implements SocketChannelConfig {
    
  • protected final EpollSocketChannel channel;
  • private volatile boolean allowHalfClosure;
  • /**
  • \* Creates a new instance.
    
  • */
    
  • EpollSocketChannelConfig(EpollSocketChannel channel) {
  •    super(channel);
    
  •    this.channel = channel;
    
  •    setTcpNoDelay(true);
    
    Could you wrap this with:

if (PlatformDependent.canEnableTcpNoDelayByDefault()) { .. }

Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Feb 15, 2014

Build result for #2229 at f123cafd1673fb92e55af1a614e75f25970e7d3f: Success

This transport use JNI (C) to directly make use of epoll in Edge-Triggered mode for maximal performance on Linux. Beside this it also support using TCP_CORK and produce less GC then the NIO transport using JDK NIO.
It only builds on linux and skip the build if linux is not used. The transport produce a jar which contains all needed .so files for 32bit and 64 bit. The user only need to include the jar as dependency as usually
to make use of it and use the correct classes.

This includes also some cleanup of @trustin
@ghost
Copy link

ghost commented Feb 15, 2014

Build result for #2229 at a7f4c95365aa394a6bd01caf352c7ac765a6982d: Success

@normanmaurer
Copy link
Member Author

Addressed all comments, squashed and merged into 4.0, 4.1 and master.. Thanks for the review guys!

@dawud-tan
Copy link

@normanmaurer, Mr. @bnoordhuis said in libuv#485#issuecomment-9198365 that he was reconsidering edge-triggered mode in libuv. It reduces the number of system calls substantially but it slows down some benchmarks because a lot more time is spent inside kernel-side spinlocks. Had you been aware of this issue?

@normanmaurer
Copy link
Member Author

@dawud-tan we not saw any of his observations. That said you can use LT and ET in Netty. You can configure it via a ChannelOption

@bnoordhuis
Copy link

The scalability issues have, by and large, been addressed in newer kernels. I profiled on (IIRC) a stock 2.6.32 kernel.

@normanmaurer
Copy link
Member Author

@bnoordhuis thanks! This explains why I not saw these yet I guess :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants