Connection resilience with Azure Managed Redis (preview)
Retry commands
Configure your client connections to retry commands with exponential backoff. For more information, see retry guidelines.
TCP settings for Linux-hosted client applications
The default TCP settings in some Linux versions can cause Redis server connections to fail for 13 minutes or more. The default settings can prevent the client application from detecting closed connections and restoring them automatically if the connection wasn't closed gracefully.
The failure to reestablish a connection can happen in situations where the network connection is disrupted or the Redis server goes offline for unplanned maintenance.
We recommend these TCP settings:
Setting | Value |
---|---|
net.ipv4.tcp_retries2 |
5 |
For more information about the scenario, see Connection does not re-establish for 15 minutes when running on Linux. While this discussion is about the StackExchange.Redis library, other client libraries running on Linux are affected as well. The explanation is still useful and you can generalize to other libraries.
Using ForceReconnect with StackExchange.Redis
In rare cases, StackExchange.Redis fails to reconnect after a connection is dropped. In these cases, restarting the client or creating a new ConnectionMultiplexer
fixes the issue. We recommend using a singleton ConnectionMultiplexer
pattern while allowing apps to force a reconnection periodically. Take a look at the quickstart sample project that best matches the framework and platform your application uses. You can see an example of this code pattern in our quickstarts.
Users of the ConnectionMultiplexer
must handle any ObjectDisposedException
errors that might occur as a result of disposing the old one.
Call ForceReconnectAsync()
for RedisConnectionExceptions
and RedisSocketExceptions
. You can also call ForceReconnectAsync()
for RedisTimeoutExceptions
, but only if you're using generous ReconnectMinInterval
and ReconnectErrorThreshold
. Otherwise, establishing new connections can cause a cascade failure on a server that's timing out because it's already overloaded.
In an ASP.NET application, you can use integrated implementation in the Microsoft.Extensions.Caching.StackExchangeRedis package instead of using the StackExchange.Redis package directly. If you're using Microsoft.Extensions.Caching.StackExchangeRedis in an ASP.NET application rather than using StackExchange.Redis directly, you can set the UseForceReconnect
property to true:
Microsoft.AspNetCore.Caching.StackExchangeRedis.UseForceReconnect = true
Configure appropriate timeouts
Two timeout values are important to consider in connection resiliency: connect timeout and command timeout.
Connect timeout
The connect timeout
is the time your client waits to establish a connection with Redis server. Configure your client library to use a connect timeout
of five seconds, giving the system sufficient time to connect even under higher CPU conditions.
A small connection timeout
value doesn't guarantee a connection is established in that time frame. If something goes wrong (high client CPU, high server CPU, and so on), then a short connection timeout
value causes the connection attempt to fail. This behavior often makes a bad situation worse. Instead of helping, shorter timeouts aggravate the problem by forcing the system to restart the process of trying to reconnect, which can lead to a connect -> fail -> retry loop.
Command timeout
Most client libraries have another timeout configuration for command timeouts
, which is the time the client waits for a response from Redis server. Although we recommend an initial setting of less than five seconds, consider setting the command timeout
higher or lower depending on your scenario and the sizes of the values that are stored in your cache.
If the command timeout
is too small, the connection can look unstable. However, if the command timeout
is too large, your application might have to wait for a long time to find out whether the command is going to time out or not.
Avoid client connection spikes
Avoid creating many connections at the same time when reconnecting after a connection loss as new connection creations are rate limited. Similar to the way that short connect timeouts can result in longer outages, starting many reconnect attempts at the same time can also increase server load and extend how long it takes for all clients to reconnect successfully.
If you're reconnecting many client instances, consider staggering the new connections to avoid your new connections from being throttled.
Note
When you use the StackExchange.Redis client library, set abortConnect
to false
in your connection string. We recommend letting the ConnectionMultiplexer
handle reconnection. For more information, see StackExchange.Redis best practices.
Avoid leftover connections
Caches have limits on the number of client connections per cache tier. Ensure that when your client application recreates connections that it closes and removes the old connections.
Schedule maintenance window
Adjust your cache settings to accommodate maintenance. For more information about creating a maintenance window to reduce any negative effects to your cache, see Update channel and Schedule updates.
More design patterns for resilience
Apply design patterns for resiliency. For more information, see How do I make my application resilient.
Idle timeout
Azure Managed Redis (preview) has a 10-minute timeout for idle connections. The 10-minute timeout allows the server to automatically clean up leaky connections or connections orphaned by a client application. Most Redis client libraries have a built-in capability to send heartbeat
or keepalive
commands periodically to prevent connections from being closed even if there are no requests from the client application.
If there's any risk of your connections being idle for 10 minutes, configure the keepalive
interval to a value less than 10 minutes. If your application is using a client library that doesn't have native support for keepalive
functionality, you can implement it in your application by periodically sending a PING
command.