7

I have 2 JVMs on the same machine that I want to pass about 1Mb of (serializable) data between ideally in under 5 ms.

Under load, using HTTP to localhost takes about 70ms average.

I tried hazelcast, passing the data via a distributed queue - about 50ms average.

Is there a faster way?


I'm using spring boot.

  • 1
    Does "under load" mean that the receiving thread might not even get scheduled for 70ms because you have more computation heavy threads than CPU cores? – CodesInChaos Jan 6 '17 at 22:01
  • @codes good question: the benchmark I created does no processing, it just receives and returns a big string. I'm using (about) half the cores to send and half to receive. – Bohemian Jan 6 '17 at 22:07
  • While there are certainly faster transports than http on localhost, it still shouldn't be anywhere that slow. – CodesInChaos Jan 6 '17 at 22:10
  • @CodesInChaos hmmm. You made me think about how many threads I had on both sides, and it had too many. My throughput with less processing threads on the listening side and less on the sending side gave results of about 10ms with 600+ TPS. Which is acceptable. I'm still going to try memory mapped file for interest sake. – Bohemian Jan 6 '17 at 23:42
4

Why don't you use pure sockets?

A socket on the same machine will send data over pretty quickly. Assuming you can send 100 MB\s over, you should be able to send 1 MB in roughly 10 ms. Getting higher speeds than this will be a bit tricky. If you had a good card you could get it to under 5 ms.

If you can serialize the data, you can send it over quite easily. See this for sending objects over sockets.

Using files would give you an average of about 80-160 MB/s or 12 ms - 6.25 ms to send 1 MB, but you'd have to read it again which will take more time.

You could use a Memory-mapped file to only have to read the file once and have it stored in memory so any virtual machine could read it from memory. Keeping a file in memory with a MappedByteBuffer will provide efficient access but you'd have to read the file first. This is also a bit more complicated than sending over sockets or writing to/reading from a file.

-1

Try using a memory mapped file, using the NIO classes.

  • That's what I'm about to try, but I didn't want to influence people's thinking – Bohemian Jan 6 '17 at 22:05
  • Using a memory mapped file was about 3 times slower than HTTP (which turned out to be about 8ms avg). I a used a new file for each call (because in the wild the data size can not be predicated, but it's about 1 Mb). So this didn't work for me. – Bohemian Jan 7 '17 at 1:34
  • 1
    @Bohemian - if you used a different file each time, then it was identical to writing the file to the filesystem. Which requires updating and searching directories (did you delete files after use? if not then the directory lookup will grow ever longer) as well as the physical disk reads and writes. The way to use a memory-mapped file for IPC is to re-use blocks, allocating each message more space than you need, and tracking the messages via some form of ring-buffer. There are, however, a few issues with synchronization and memory barriers that you need to be aware of. – kdgregory Jan 7 '17 at 13:06
  • @Bohemian It would be interesting if you made a table of your findings along with methodlology/code in your post. I'm sure others would find it helpful :) – marathon Jan 7 '17 at 16:35
  • @kdg yep I've figured that. It's back to basics memalloc with no free lunch. – Bohemian Jan 7 '17 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.