Multiple selectors in multiple threads

Is it useful to distribute incoming connections between n threads, each with its own independent NIO Selector , where n is, say, the number of cores on the server? Suppose I am writing a server that should handle several client connections. I could be something like:

 selector.select(); Iterator<SelectionKey> i = selector.selectedKeys().iterator(); while (i.hasNext()) { SelectionKey key = i.next(); i.remove(); if (!key.isValid()) continue; if (key.isAcceptable()) { // get one of the n selectors (I'd have one per core) Selector chosenSelector = getRandomSelector(); // delegate the new connection to the chosen selector SocketChannel newChannel = key.channel.accept(); newChannel.configureBlocking(false); newChannel.register(chosenSelector, SelectionKey.OP_READ); } } 

Do you guys think that makes sense? I mean, n threads, each with a different selector? Or should I just stick to one selector thread that processes OP_READ for all connections? Or maybe something else?

+7
java multithreading selector nio
source share
3 answers

No, this is not beneficial, since the ratio of the code that needs to be processed and the time it takes for I / O operations is negligible. Especially when you consider the extra time required to synchronize fragmented data. However, it is useful to process the received data in separate streams.

So, basically: to have a single-threaded selector cycle that copies data from one buffer to the task buffer for further processing in a separate stream, and then runs Runnable with this task buffer in Executor to process this copied data.

+2
source share

I will have only one selector, and it will propagate messages over a fixed number of threads through a messy ring buffer. Then you can have your stream completely without blocking, a super-fast way. The stream will be like this:

Critical selector => DEMUX => Workflows => MUX => Critical selector

You just need to make sure that your workflows are enough (and you have enough free cores for them) to quickly process your messages, otherwise you can get full DEMUX, and the selector will have to either block or discard messages.

I suggest you read this article to get an idea of ​​how an asynchronous, single-threaded, non-blocking network structure works. Of course, you can also check Netty or Mina. For an idea of ​​the delays you have to pay using demux and the nanosecond multiplexer, refer to this test .

0
source share

I'm not quite sure where the current answers are coming from. I think the question has been edited.

Is it useful to distribute incoming connections between n threads, each with its own independent NIO selector, where n is, say, the number of cores on the server?

What you are describing here is a basic model of a worker. You usually have 2 employees per core. Every employee has a Selector . This model is absolutely necessary for Windows, since each selector can only process 1024 sockets and work, which makes the JDK disastrous for performance.

Theme β†’ Selector β†’ OP_READ / OP_WRITE β†’ Make Smoothies

This is a fundamental variation in reactor structure.

It is important that one SocketChannel connected to only one Selector . Therefore, do not call SocketChannel.register() in a bunch of Selectors and listen to OP_READ for everyone, because you will not get any benefit.

http://man7.org/linux/man-pages/man7/epoll.7.html

Q2 Can two instances of epoll wait for the same file descriptor? If so, are events being reported as descriptors of the epoll file?

A2 Yes, and events will be reported to both. However, programming may be required carefully to do this correctly.

-one
source share

All Articles