pgjdbc-ng icon indicating copy to clipboard operation
pgjdbc-ng copied to clipboard

Repair/Replace/Remove Netty

Open kdubb opened this issue 5 years ago • 15 comments

During #349 I investigate the performance difference between the mainline and this driver. There is a real difference (to say the least) when testing on localhost. It is reduced significantly when testing across a link (even a very fast low latency link). It's worth investigating other options.

One of the key requirements is that it remain asynchronous, as we move forward we will need that functionality.

Options I know of:

  • Homegrown Thread Per Connection (NIO or Blocking)
    • Spawn a thread for each connection to handle message delivery while writing directly to the socket. This is a fairly easy to implement solution when using blocking sockets.
    • According to my testing the real win here is to use blocking sockets but I could have done something drastically wrong while using NIO.
  • Netty
    • Accept the penalty and work to make it as low as possible
  • Netty OIO
    • This is "thread per connection" built on blocking sockets. Unfortunately it currently doesn't work and they've deprecated it. To get it to work for just a test you need to monkey around with it quite a bit. We could take it maintain it for our own use; advantage being that Netty NIO is interchangeable.
  • Homegrown NIO
    • Build something catered to our needs but that uses NIO and works similar to Netty. There are obvious speed improvements to be made (e.g. writing to the socket from the connection thread) but I'm not 100% sure why Netty made those choices so this may be a fools errand.

kdubb avatar Dec 19 '18 23:12 kdubb

@normanmaurer I know you're a busy man but was wondering if you might weigh in here. I can elaborate on the performance issues we see (raised in #349) if need be.

kdubb avatar Dec 19 '18 23:12 kdubb

There is http://xnio.jboss.org/ too

jesperpedersen avatar Dec 20 '18 08:12 jesperpedersen

@jesperpedersen I hacked together a simple Socket based implementation that uses a reader thread per connection and checked it into a branch here 60778131164a877de148af0059f0620f6da4b5ec. This hack alone gets makes ng only around 15% slower than og when using localhost and about 7% when going across a link.

Of particular interest. I tried a "slick" implementation first. I used a SocketChannel in blocking mode (aka blocking NIO) because Netty's ByteBuf has awesome features for scattering reads and gathering writes. I used them to buffer writes until flush and pull in separate buffers combining them in to a contiguous buffer without copying.... that was nearly as slow as Netty itself. It appears that using NIO is the issue; or I'm doing something very wrong.

This still uses Netty ByteBuf; if we ditch it that can be removed and all the reference counting that comes with it.

kdubb avatar Dec 21 '18 18:12 kdubb

@jesperpedersen @davecramer After the lengthy investigation & discussion in #349... wondering if you guys have seen this https://openjdk.java.net/jeps/353?

If java.net.Socket is soon to be built on NIO then any performance difference between the two must be vanishing.. and that might not be immediately be in good direction because for all I've seen and read NIO is slower.

kdubb avatar Sep 29 '19 17:09 kdubb

FYI JEP353 is implemented in JDK13

kdubb avatar Sep 29 '19 17:09 kdubb

java.net.Socket + ssl buffers data, and it seems there's no sensible way to check if the connection holds some data or not (e.g. server notifications). That is really painful for copy / replication processing over SSL.

vlsi avatar Sep 29 '19 18:09 vlsi

Sounds like that might be a +1 for Netty.

It's SSL uses Java's SSL handler (or a native OpenSSL/BoringSSL if available & chosen) but is layered in the Netty message stack (you just plug it in for SSL, leave it out for plain). All the normal message notifications are fired when data is received; you can even hook into notifications "below" SSL in the stack (while the packet is still encrypted).

I never did any performance comparison with SSL enabled might be an interesting study though.

kdubb avatar Sep 29 '19 18:09 kdubb

pgjdbc has recently switched to "ssl by default" for security reasons, and the default buffering in SSL implementation in Java did bite us a couple of times :-/

vlsi avatar Sep 29 '19 18:09 vlsi

I've opened issue in netty/netty#9627 to explore any solutions/help the Netty team might be able to offer.

kdubb avatar Oct 01 '19 18:10 kdubb

What is the status of this issue? It looks like a potential solution was presented in the netty issue but nobody followed up.

crinklywrappr avatar Mar 18 '21 05:03 crinklywrappr

@crinklywrappr I've updated the Netty issue, there is no answer as to why blocking sockets are inherently slower than non-blocking Netty.

kdubb avatar Mar 18 '21 06:03 kdubb

@kdubb are they really? I thought that was only the case over very low latency connections. Once their was significant latency the differences become moot ?

davecramer avatar Mar 18 '21 09:03 davecramer

@davecramer You are correct. My testing showed that this issue nearly disappears once operating over any remote link (i.e. not a localhost connection).

My hypothesis is that this is a thread context switching issue, which seems to explain the data I've seen.

kdubb avatar Mar 18 '21 13:03 kdubb

FYI, this issue is still open mostly because I want to explore removing Netty once loom is ready.

kdubb avatar Mar 18 '21 13:03 kdubb

haha, that might be a while :)

davecramer avatar Mar 18 '21 13:03 davecramer