My application is not web based, just need to use sockets to service around 1000 clients. Throughput and latency are of utmost importance to me. Currently using select() from NIO but thinking of moving on to asynchronous IO in NIO.2.
When should asynchronous I/O be used?
What is the primary use case for asynchronous I/O?
If you are using Infiniband networks I would suggest looking at the Asynchronous IO.
Comparing Java 7 Async NIO with NIO.
However if you are using regular ethernet, it is just as likely to slower as faster. The coding is more complicated than using non-blocking IO which is more complicated than using blocking IO.
If latency is of utmost importance I suggest you look at using kernel by-pass network adapters like Solarflare. However if a 100 micro-second latency is acceptable to you, it is unlikely you need this.
Asynchronous IO is very good in situations where you need to scale to handle many concurrent connections. Historically one way of doing this was to dedicate a thread per connection, but this approach has limitations you can read about here. With Asynchronous IO you can easier handle many things with less threads and thus scale better.
Depending on the problem it might or might not be the right approach as nothing can beat a single thread when it comes to latency. However, this is a very extreme end and means you care about microseconds. In many cases is a trade-off between latency and throughput/scalability.
In any case it comes down to what you want to solve and what your expectations (numbers) need to be. Asynchronous IO is great and many cases and so is synchronous. There might also be other things you might want to consider such as protocol. Multiple clients interested in the same data (streaming) could indicate you want to look at multicast. If traffic is dedicated per client, then that might not be the approach.
Not knowing your latency requirements, but assuming they are not in a few microseconds I would definitely look into asychronous IO just reading you have 1000 clients. Asynchronous IO is by no means slow and synchronous/single thread connections might not scale well for you.
Related
I run multiple game servers and I want to develop a custom application to manage them. Basically all the game servers will connect to the application to exchange data. I don't want any of this data getting lost so I think it would be best to use TCP. I have looked into networking and understand how it works however I have a question about cpu usage. More servers are being added and in the next few months it could potentially reach around 100 - 200 and will continue to grow as needed. Will new threads for each server use a lot of cpu and is it a good idea to do this? Does anyone have any suggestions on how to go about this? Thanks.
You should have a look at non blocking io. With blocking io, each socket will consume 1 thread and the number of threads in a system is limited. And even if you can create 1000+, it is a questionable approach.
With non blocking io, you can server multiple sockets with a single thread. This is a more scalable approach + you control how many threads at any given moment are running.
More servers are being added and in the next few months it could potentially reach around 100 - 200 and will continue to grow as needed. Will new threads for each server use a lot of cpu and is it a good idea to do this?
It is a standard answer to caution away from 100s of threads and to the NIO solution. However, it is important to note that the NIO approach has a significantly more complex implementation. Isolating the interaction with a server connection to a single thread has its advantages from a code standpoint.
Modern OS' can fork 1000s of threads with little overhead aside from the stack memory. If you are sure of your scaling factors (i.e. you're not going to reach 10k connections or something) and you have the core memory then I would say that a thread per TCP connection could work very well. I've very successfully run applications with 1000s of threads and have not seen fall offs in performance due to context switching which used to be the case with earlier processors/kernels.
I have a Java application that require communication between different process. Process could run in same JVM or different JVM, but runs on the same machine.
My application need to submit "messages" to another process (same or different JVM) and forgot about it. similar to messaging queue like IBM "MQ", but simple, and only use memory, no IO to hard disk for performance gains.
I'm not sure what is the best approach from Performance prescriptive.
I wonder if RMI is efficient in terms of Performance, I think it require some overhead.
What about TCP/IP socket using local host?
any other thought?
I wonder if RMI is efficient in terms of Performance, I think it require some overhead.
RMI is efficient for what it does. It does much more than most people need, but is usually more than faster enough. You should be able to get of the order of 1-3 K messages per second with a latency around 1 milli-second.
What about TCP/IP socket using local host?
That is always an option but with plain Java Serialization this will not be a lot faster than using RMI. How you do the serialization and deserialization is critical for high performance.
An important note is that much of the time is spent serializing and deserilizing the message, something most transports don't help you with, so if you want maximum performance you have to consider an efficient marshalling strategy. Most transport protocols only benchmark raw bytes.
Ironically if you are willing to use disk, it can be faster than TCP or UDP (like ZeroMQ) plus you get persistence for "free".
This library (I am the author) can perform millions of messages per second between processes with latency as low as 100 nano-second (350x lower than ZeroMQ) https://github.com/peter-lawrey/Java-Chronicle Advantages are
ultra fast serialization and deserialization, something most transport benchmarks avoid including this as it often takes much longer than the transport costs.
is that you can monitor what is happening between queues any time after the message was sent.
replay all messages.
the producer can be any amount of data ahead of your consumer to handle micro-burst gracefully up to the size of your disk space. e.g. the consumer can be TBs behind.
supports replication over TCP.
restart of either the consumer or producer is largely transparent.
If you are developing server application try to consider ZeroMQ. It has great performance, allow to build interprocess communication easier, allow to build asynchronous API.
ZeroMQ declare fantastic performance with InterProcess communication. Even better than TCP sounds great. We are consider this solution for our clusterisation schema.
Pieter Hintjens give the great answer for performance comparison between different Message Broker.
I need to create a relatively simple Java tcp/ip server and I'm having a little trouble determining if I should use something like Netty or just stick with simple ServerSocket and InputStream/OutputStream.
We really just need to listen for a request, then pass the new client Socket off to some processing code in a new thread. That thread will terminate once the processing is complete and the response is sent.
I like the idea of pipelines, decoders, etc. in Netty, but for such a simple scenario it doesn't seem worth the added up front development time. It seems like a bit overkill for our initial requirements, but I'm a little nervous that there are lots of things I'm not considering. What, if any, are the benefits of Netty for such simple requirements? What am I failing to consider?
The main advantage of Netty over simply reading from and writing to sockets using streams is that Netty supports non-blocking, asynchronous I/O (using Java's NIO API); when you use streams to read and write from sockets (and you start a new thread for each connected accepted from a ServerSocket) you are using blocking, synchronous I/O.
The Netty approach scales much better, which is important if your system needs to be able to handle many (thousands) of connections at the same time. If your system does not need to scale to many simultaneous connections, it might not be worth the trouble to use a framework like Netty.
Some more background information: Threads are relatively expensive resources in an operating system. Each thread needs memory for the stack (which can be for example 2 MB in size). When you create thousands of threads, this is going to cost a lot of memory; also, operating systems have limits on the number of threads that can be created. So you don't want to start a new thread for each accepted connection. The idea of asynchronous I/O is to decouple the threads from the connections (no one-to-one relation). There can be many more connections than threads, and whenever some event happens on one of the connections (for example, data is received), a thread from a thread pool is temporarily used to handle the event.
I think that the benefits of using netty are not immediate but actually come later when requirements change and maintenance becomes more complex for your project. Netty brings built in understanding of the HTTP protocol so that you can provide simple RESTful web services. Also you have the option of utilizing asynchronous request processing that netty provides as a framework so that you can potentially get better performance and service several orders of magnitude more concurrent requests.
First, write the logic of your service so that it's independent of your communication layer.
As Victor Sorokin said, there's a learning advantage to doing it yourself. So it ought to be worthwhile to write it with sockets. It will involve less effort to get started, and if it works well enough then you're off to the races.
If you find that you need more scalability/robustness later, you can switch to netty. Just write a new netty layer that communicates for your service logic layer and swap them out.
I've read several posts about java.net vs java.nio here on StackOverflow and on some blogs. But I still cannot catch an idea of when should one prefer NIO over threaded sockets. Can you please examine my conclusions below and tell me which ones are incorrect and which ones are missed?
Since in threaded model you need to dedicate a thread to each active connection and each thread takes like 250Kilobytes of memory for it's stack, with thread per socket model you will quickly run out of memory on large number of concurrent connections. Unlike NIO.
In modern operating systems and processors a large number of active threads and context switch time can be considered almost insignificant for performance
NIO throughoutput can be lower because select() and poll() used by asynchronous NIO libraries in high-load environments is more expensive than waking up and putting to sleep threads.
NIO has always been slower but it allows you to process more concurrent connections. It's essentially a time/space trade-off: traditional IO is faster but has a heavier memory footprint, NIO is slower but uses less resources.
Java has a hard limit per concurrent threads of 15000 / 30000 depending on JVM and this will limit thread per connection model to this number of concurrent connections maximum, but JVM7 will have no such limit (cannot confirm this data).
So, as a conclusion, you can have this:
If you have tens of thousands concurrent connections - NIO is a better choice unless a request processing speed is a key factor for you
If you have less than that - thread per connection is a better choice (given that you can afford amount of RAM to hold stacks of all concurrent threads up to maximum)
With Java 7 you may want to go over NIO 2.0 in either case.
Am I correct?
That seems right to me, except for the part about Java limiting the number of threads – that is typically limited by the OS it's running on (see How many threads can a Java VM support? and Can't get past 2542 Threads in Java on 4GB iMac OSX 10.6.3 Snow Leopard (32bit)).
To reach that many threads you'll probably need to adjust the stack size of the JVM.
I still think the context switch overhead for the threads in traditional IO is significant. At a high level, you only gain performance using multiple threads if they won't contend for the same resources as much, or they spend time much higher than the context switch overhead on the resources.
The reason for bringing this up, is with new storage technologies like SSD, your threads come back to contend on the CPU much quicker
There is not a single "best" way to build NIO servers, but the preponderance of this particular question on SO suggests that people think there is! Your question summarizes the use cases that are suited to both options well enough to help you make the decision that is right for you.
Also, hybrid solutions are possible too! You could hand the channel off to threads when they are going to do something worthy of their expense, and stick to NIO when it is better.
I would say start with thread-per-connection and adapt from there if you run into problems.
If you really need to handle a million connections you should consider writing (or finding) a simple request broker in C (or whatever) that will use far less memory per connection than any java implementation can. The broker can receive requests asynchronously and queue them to backend workers written in your language of choice.
The backends thus only need a thread per active request, and you can just have a fixed number of them so the memory and database use is predetermined to some degree. When large numbers of requests are running in parallel the requests are made to wait a bit longer.
Thus I think you should never have to resort to NIO select channels or asynchronous I/O (NIO 2) on 64-bit systems. The thread-per-connection model works well enough and you can do your scaling to "tens or hundreds of thousands" of connections using some more appropriate low-level technology.
It is always helpful to avoid premature optimization (i.e. writing NIO code before you really have massive numbers of connections coming in) and don't reinvent the wheel (Jetty, nginx, etc.) if possible.
What most often is overlooked is that NIO allows zero copy handling. E.g. if you listen to the same multicast traffic from within multiple processes using old school sockets on one single server, any multicast packet is copied from the network/kernel buffer to each listening application. So if you build a GRID of e.g. 20 processes, you get memory bandwidth issues. With nio you can examine the incoming buffer without having to copy it to application space. The process then copies only parts of the incoming traffic it is interested in.
another application example:
see http://www.ibm.com/developerworks/java/library/j-zerocopy/ for an example.
I have pretty much already decided not to use asynchronous, non-blocking Java NIO. The complexity versus benefit is very questionable in general, and I think it's not worth it in this project particularly.
But most of what I read about NIO, and comparisons with older java.io.* focuses on non-blocking, asynchronous NIO versus thread-per-connection synchronous I/O using java.io.*. However, NIO can be used in synchronous, blocking, thread-per-connection mode, which is rarely discussed it seems.
Here's the question: Is there any performance advantage of synchronous, blocking NIO versus traditional synchronous, blocking I/O (java.io.*)? Both would be thread-per-connection. How does the complexity compare?
Note that this is a general question, but at the moment I am primarily concerned with TCP socket communication.
An advantage of NIO over "traditional" IO is that NIO can use direct buffers that allow the OS to use DMA for some operations (e.g. reading from a network connection directly into a memory-mapped file) and thereby avoid copying data to intermediate buffers.
If you're moving large amounts of data in a scenario where this technique does avoid copy operations that would otherwise be performed, this can have a big impact on performance.
It basically boils down the number of concurrent connections and how busy those connections are. Blocking (standard thread per connection) is faster, both in latency and throughput (about twice as fast for a simple echo server). So if your system can cope with maintaining a thread for each connection (<1000 connections as a rule of thumb) go for the blocking approach. If you have lots of mostly idle connections (e.g. Comet long poll requests or IMAP idle connections) then switching to a non-blocking architecture could help scale your system.
I can not speak to the technology in particular, but it is not unusual for asynchronous libraries to provide synchronous operations to facilitate in debugging.
For instance if you are having problems you can eliminate the asynchronous portions of the logic without rewriting your entire process. This is especially helpful since synchronous processes are typically much easier to work with.