Configuring Client resources¶
Client resources are configuration settings for the client related to
performance, concurrency, and events. A vast part of Client resources
consists of thread pools (EventLoopGroups and a EventExecutorGroup)
which build the infrastructure for the connection workers. In general,
it is a good idea to reuse instances of ClientResources across
multiple clients.
Client resources are stateful and need to be shut down if they are supplied from outside the client.
Creating Client resources¶
Client resources are required to be immutable. You can create instances using two different patterns:
The create() factory method
By using the create() method on DefaultClientResources you create
ClientResources with default settings:
This approach fits the most needs.
Resources builder
You can build instances of DefaultClientResources by using the
embedded builder. It is designed to configure the resources to your
needs. The builder accepts the configuration in a fluent fashion and
then creates the ClientResources at the end:
ClientResources res = DefaultClientResources.builder()
.ioThreadPoolSize(4)
.computationThreadPoolSize(4)
.build()
Using and reusing ClientResources¶
A RedisClient and RedisClusterClient can be created without passing
ClientResources upon creation. The resources are exclusive to the
client and are managed itself by the client. When calling shutdown()
of the client instance ClientResources are shut down.
If you require multiple instances of a client or you want to provide
existing thread infrastructure, you can configure a shared
ClientResources instance using the builder. The shared Client
resources can be passed upon client creation:
ClientResources res = DefaultClientResources.create();
RedisClient client = RedisClient.create(res);
RedisClusterClient clusterClient = RedisClusterClient.create(res, seedUris);
...
client.shutdown();
clusterClient.shutdown();
res.shutdown();
Shared ClientResources are never shut down by the client. Same applies
for shared EventLoopGroupProviders that are an abstraction to provide
EventLoopGroups.
Why Runtime.getRuntime().availableProcessors() * 3?¶
Netty requires different EventLoopGroups for NIO (TCP) and for EPoll
(Unix Domain Socket) connections. One additional EventExecutorGroup is
used to perform computation tasks. EventLoopGroups are started lazily
to allocate Threads on-demand.
Shutdown¶
Every client instance requires a call to shutdown() to clear used
resources. Clients with dedicated ClientResources (i.e. no
ClientResources passed within the constructor/create-method) will
shut down ClientResources on their own.
Client instances with using shared ClientResources (i.e.
ClientResources passed using the constructor/create-method) won't
shut down the ClientResources on their own. The ClientResources
instance needs to be shut down once it's not used anymore.
Configuration settings¶
The basic configuration options are listed in the table below:
| Name | Method | Default |
|---|---|---|
| I/O Thread Pool Size | ioThreadPoolSize |
See below |
The number of threads in the I/O thread pools. Every thread represents an internal event loop where all I/O tasks are run. 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. The minimum I/O threads are 2. |
||
| Computation Thread Pool Size | computationThreadPoolSize |
See below |
The number of threads in the computation thread pool. Every thread represents an internal event loop where all computation tasks are run. The minimum computation threads are 2. |
Default thread pool size¶
Unless configured otherwise by the settings above, the number of threads (for both computation and I/O) is determined in the following order:
* if there is an environment variable setting for io.netty.eventLoopThreads we use it as default setting
* otherwise we take the number of available processors, retrieved by Runtime.getRuntime().availableProcessors() (which, as a well-known fact, sometimes does not represent the actual number of processors)
* in any case if the chosen number is lower than the minimum, which is 2 threads, then we use the minimum.
Advanced settings¶
Values for the advanced options are listed in the table below and should not be changed unless there is a truly good reason to do so.
| Name | Method | Default |
|---|---|---|
| Provider for EventLoopGroup | eventLoopGroupProvider |
none |
For those who want to reuse existing netty infrastructure or the
total control over the thread pools, the
EventLoopGroupProvider API provides a way to do so.
EventLoopGroups are obtained and managed by an
EventLoopGroupProvider. A provided
EventLoopGroupProvider is not managed by the client and
needs to be shut down once you no longer need the resources. |
||
| Provided EventExecutorGroup | eventExecutorGroup |
none |
For those who want to reuse existing netty infrastructure or the
total control over the thread pools can provide an existing
EventExecutorGroup to the Client resources. A provided
EventExecutorGroup is not managed by the client and needs
to be shut down once you no longer need the resources. |
||
| Event bus | eventBus |
DefaultEventBus |
The event bus system is used to transport events from the client to
subscribers. Events are about connection state changes, metrics, and
more. Events are published using a RxJava subject and the default
implementation drops events on backpressure. Learn more about the Reactive API. You can also publish your own
events. If you wish to do so, make sure that your events implement the
Event marker interface. |
||
| Command latency collector options | commandLatencyCollectorOptions |
DefaultCommandLatencyCollectorOptions |
The client can collect latency metrics during while dispatching
commands. The options allow configuring the percentiles, level of
metrics (per connection or server) and whether the metrics are
cumulative or reset after obtaining these. Command latency collection is
enabled by default and can be disabled by setting
commandLatencyPublisherOptions(…) to
DefaultEventPublisherOptions.disabled(). Latency
collector requires LatencyUtils to be on your class
path. |
||
| Command latency collector | commandLatencyCollector |
DefaultCommandLatencyCollector |
The client can collect latency metrics during while dispatching
commands. Command latency metrics is collected on connection or server
level. Command latency collection is enabled by default and can be
disabled by setting commandLatencyCollectorOptions(…) to
DefaultCommandLatencyCollectorOptions.disabled(). |
||
| Latency event publisher options | commandLatencyPublisherOptions |
DefaultEventPublisherOptions |
Command latencies can be published using the event bus. Latency
events are emitted by default every 10 minutes. Event publishing can be
disabled by setting commandLatencyPublisherOptions(…) to
DefaultEventPublisherOptions.disabled(). |
||
| DNS Resolver | dnsResolver |
DnsResolvers.JVM_DEFAULT ( or netty if present) |
Since: 3.5, 4.2. Deprecated: 6.4 Configures a DNS resolver to resolve hostnames to a
Since 4.4: Defaults to |
||
| Address Resolver Group | addressResolverGroup |
DefaultAddressResolverGroup.INSTANCE ( or netty DnsAddressResolverGroup if present) |
Since: 6.1 Sets the Users of DNS-based Redis-HA setups (e.g. AWS ElastiCache) might want to configure a different DNS resolver group. For example: |
||
| Reconnect Delay | reconnectDelay |
Delay.exponential() |
Since: 4.2 Configures a reconnect delay used to delay reconnect attempts.
Defaults to binary exponential delay with an upper boundary of
|
||
| Netty Customizer | NettyCustomizer |
none |
Since: 4.4 Configures a netty customizer to enhance netty components. Allows
customization of |
||
| Tracing | tracing |
disabled |
Since: 5.1 Configures a |
||