Reference documentation could be more beginner friendly in some areas
See original GitHub issueHello @mp911de.
I’ve read the lettuce’s reference documentation and found a few paragraphs I do not understand correctly. Can you please provide answers to my questions or possibly update the documentation so it is more “lettuce beginner friendly”?
- Lettuce is using sort of pipelining even if
sync
commands are used (because it just passes thecommand
down the pipe to another thread to be send with using netty). This means I can use singleconnection
within multiple threads and do not experience any kind of blocking because, for example, another thread is just waiting for response toGET
command. From Pipelining and command flushing:
Using the synchronous API, in general, the program flow is blocked until the response is accomplished. The underlying connection is busy with sending the request and receiving its response. Blocking, in this case, applies only from a current Thread perspective, not from a global perspective.
-
Nr 1. is possible because of the fact that
ClienrtResources
uses multiple I/O threads and those threads are responsible for physical connection with the Redis instance. Am I right? -
Reference documentation says that
ClientResources#ioThreadPoolSize
is
The number of threads in the I/O thread pools. … The number does not reflect the actual number of I/O threads because the client requires different thread pools for Network (NIO) and Unix Domain Socket (EPoll) connections.
a) What does ClientResources#ioThreadPoolSize
actually represent?
b) How many I/O threads (physical connections) Netty use in relation to ClientResources#ioThreadPoolSize
property?
- Reference documentation also talks about
ClientResources#computationThreadPoolSize
:
The number of threads in the computation thread pool. … Every thread represents an internal event loop where all computation tasks are run.
a) What computations is the documentation talking about?
b) Is it somehow related to ClientResources#ioThreadPoolSize
?
- How is the lettuce’s
shared connection
related/bounded toNetty's transport I/O thread
?
And a few questions related to connection pooling.
-
Syncrhonous connections: If I set
GenericObjectPoolConfig#setMaxTotal(int)
to 20 and setClientResources#ioThreadPoolSize
(from nr. 3) to 5. a) Does it mean that if I try to obtain 6th connection from the pool and send a command using that connection (assuming that all 5 I/O threads fromClientResources
are busy and waiting for response), that the command will be queued on the client side waiting for free I/O thread to process it? b) IfYES
the proper way to use pooling is to setmaxTotal > ioThreadPoolSize
? -
Asyncrhonous connections: The very same questions like in nr. 5) but with using
BoundedPoolConfig.builder().maxTotal(int)
. -
Command flushing is not allowed on pooled connections: ref:
The
AutoFlushCommands
state is set per connection and therefore affects all threads using the shared connection.
I understand that.
If you want to omit this effect, use dedicated connections.
Dedicated connection is actually a pooled connection - I can obtain a connection from a pool, disable autoFlushCommands
, process a batch request, enable autoFlushCommands
and return the connection.
The AutoFlushCommands state cannot be set on pooled connections by the lettuce connection pooling.
a) So pooled connection is NOT dedicated? b) How should one use batch processing with pooled connections?
Thank you very much for your time. Best Regards,
Martin
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:7 (4 by maintainers)
Top GitHub Comments
Feel free to edit the wiki directly.
Lettuce uses pipelining as default mode of operation. Your understanding is correct. Note that there is an extension to pipelining as outlined in the Pipelining/Flushing page. You can basically pipeline more aggressively by collecting a batch of commands that is attempted to send in as little TCP packages and with as little flushes as possible. Compared to “regular” pipelining, manual flushing has a 5x to 10x performance gain.
No. Netty’s threading model assigns a thread per transport connection. So if you dispatch commands from multiple application threads on a single connection, all I/O (read and write operations) are handled by a single EventLoop thread. You can increase the number of effectively used I/O threads by using multiple connections but that style of use makes rarely sense for the sake of performance.
To a: The number in each transport-specific EventLoopGroup. Netty 4 has currently a limitation that requires a specific EventLoopGroup per channel type. So you cannot use an NIO EventLoopGroup with kqueue or epoll transport or vice versa. Netty 5 is going to address that shortcoming.
To b: Not sure I follow. A thread does not represent a connection. A connection gets a I/O thread assigned. Any higher number of connections than
ioThreadPoolSize
reuses threads. That is, if you have 4 threads and 4 connections, each connection uses exclusively a thread (there’s a configurableEventExecutorChooser
but probably too detailed for now). If you open a 5th connection, then one of the 4 threads gets assigned to the 5th connection.Probably also worth mentioning: Typically, you use a single mechanism to establish connections (nio, kqueue, epoll) so you should only see as many as
ClientResources#ioThreadPoolSize
I/O threads. Having nio and e.g. epoll active should not happen.Computations are background tasks (cluster topology refresh, offloading of reactive pipeline signals, timers, …). That pool is configured though
ClientResources#computationThreadPoolSize
.That question is answered above.
There are no synchronous/asynchronous connections (we had this concept earlier in Lettuce 2 and 3, we removed it entirely in favor of a
StatefulConnection
exposing synchronous, asynchronous and reactive API facades).The relation between connection count and how netty threads are associated with connections is explained above.
Probably we need to improve our documentation here. We had once the restriction that pooled connections are not allowed to change their state (database selection, flushing behavior). Looking at the code, this section is no longer valid and needs to be removed/reworked.
Let me know if this helps or whether there are things that need to be addressed.
That’s fixed now in https://github.com/lettuce-io/lettuce-core/wiki/Connection-Pooling-5.1.