0

In my server, I have 1000 threads that are listening to 1000 different UDP sockets. When a thread receives a packet it puts the UDP packets on a thread-safe queue. The code is like this.

   while(true)
    { 
        ......
        socket.receive(packet); 
        packetQueue.add(packet);
        ..... 

    }

In a second on average a thread (UDP socket) receives 50 packets that are on average the server receives

1000 * 50 = 50K

UDP packets. The server is working more or less fine.

But now I want to change the design a little now. Now I am planning to use 1 thread that will listen on 1 socket and after receiving those packets that thread will put that packet in the queue like before.

So now on average 50K UDP packets will come to the server on that port.

Will this new architecture be able to handle this load? From Java networking perspective does it make any difference if all the packets are coming to one port or different ports?

  • 1
    Can you easily just test it out? 1000 threads means lots of context switching, which is costly. But one thread may not allow for any concurrency that could be gained. The UDP code probably will work OK with 1000 times as many packets hitting one port. – user251748 Mar 22 '18 at 15:05
  • The only way to really know that for sure is to measure, but I doubt that the port itself is a bottleneck, unless getting more speed requires you to listen on more than one port at the same time. – Robert Harvey Mar 22 '18 at 15:07
  • 1
    @nocomprende if all the threads are blocking on IO, they will not cost CPU time, no? – Phoenix Mar 22 '18 at 15:08
  • @Phoenix If servicing a packet requires a switch to a different thread, that is more overhead than having all packets serviced by a single thread. – user251748 Mar 22 '18 at 16:18
  • Long ago I needed to create a database transaction server shell. I took the easy way out and made it multi-threaded. A colleague with a much bigger brain had already created a single threaded version (on entirely different hardware and OS). I always wished we could compare them, but alas. – user251748 Mar 22 '18 at 16:27
1

It should handle it, depends of your implementation.

One thread is enough to push it to the queue. The problem is the size of the queue and how fast you are able to take data from it. Maximum size of the UDP package in IPv4 is 65,507 bytes, multiply it by 50 000 and you get more than 3gb per second. You need to be sure that packages are not lost if queue is full, unless you don't mind

Use Netty it will help you out with this. There is a similar question on stackoverflow

  • Can you be a little more specific? Saying you think it will work and then pointing in the direction of an off-site post doesn't really make a good answer. – Robert Harvey Mar 22 '18 at 15:07
  • Such queue problems would seem to occur similarly in the 1000 port version, since OP is adding all packets to the same single thread-safe queue. The OP states that is working (more-or-less) fine (maybe they're using small packets or have sufficient horsepower). – Erik Eidt Mar 22 '18 at 16:10
  • 1
    It could even be worse on the 1000 thread version, due to additional threads contending for locks on the thread-safe queue, in particular, if the 1000 threads are spread evenly across 4 or more CPUs, that will decrease cache effectiveness as MESI will have to transfer ownership of cache lines between CPUs. See also LMAX Disruptor, which uses single writer, single reader (different CPUs) in a special way to play nice w/ MESI. – Erik Eidt Mar 22 '18 at 16:11

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.