Connect to the server
Connect your .NET application to a Redis database
Basic connection
You can connect to the server simply by passing a string of the
form "hostname:port" to the Connect() method (for example,
"localhost:6379"). However, you can also connect using a
ConfigurationOptions parameter. Use this to specify a
username, password, and many other options:
using StackExchange.Redis;
ConfigurationOptions conf = new ConfigurationOptions {
EndPoints = { "localhost:6379" },
User = "yourUsername",
Password = "yourPassword"
};
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(conf);
IDatabase db = redis.GetDatabase();
db.StringSet("foo", "bar");
Console.WriteLine(db.StringGet("foo")); // prints bar
Unlike other clients, StackExchange.Redis doesn't support Connection URLs but it does support its own similar configuration string format. See Connection URLs to learn how to convert a standard URL to a configuration string.
Connect to a Redis cluster
The basic connection will use the
Cluster API
if it is available without any special configuration. However, if you know
the addresses and ports of several cluster nodes, you can specify them all
during connection in the Endpoints parameter:
ConfigurationOptions options = new ConfigurationOptions
{
//list of available nodes of the cluster along with the endpoint port.
EndPoints = {
{ "localhost", 16379 },
{ "localhost", 16380 },
// ...
},
};
ConnectionMultiplexer cluster = ConnectionMultiplexer.Connect(options);
IDatabase db = cluster.GetDatabase();
db.StringSet("foo", "bar");
Console.WriteLine(db.StringGet("foo")); // prints bar
Connect to Redis Sentinel
To connect through Redis Sentinel,
list the Sentinels in EndPoints and set ServiceName to the name of the primary that
the Sentinels monitor. The client asks the Sentinels for the current primary.
using StackExchange.Redis;
ConfigurationOptions conf = new ConfigurationOptions {
EndPoints = { "localhost:26379", "localhost:26380", "localhost:26381" },
ServiceName = "mymaster"
};
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(conf);
IDatabase db = redis.GetDatabase();
db.StringSet("foo", "bar");
Console.WriteLine(db.StringGet("foo")); // prints bar
You can also use a configuration string, such as
"localhost:26379,localhost:26380,localhost:26381,serviceName=mymaster".
If the Sentinels and the data nodes have different credentials, connect to the Sentinels
first with SentinelConnect(), using the Sentinel credentials. Then call
GetSentinelMasterConnection() with the credentials for the primary and replicas:
using StackExchange.Redis;
// Connect to the Sentinels with the Sentinel credentials.
ConfigurationOptions sentinelConf = new ConfigurationOptions {
EndPoints = { "localhost:26379", "localhost:26380", "localhost:26381" },
User = "yourSentinelUsername",
Password = "yourSentinelPassword"
};
ConnectionMultiplexer sentinel = ConnectionMultiplexer.SentinelConnect(sentinelConf);
// Connect to the primary with the Redis credentials.
ConfigurationOptions conf = new ConfigurationOptions {
ServiceName = "mymaster",
User = "yourUsername",
Password = "yourPassword"
};
ConnectionMultiplexer redis = sentinel.GetSentinelMasterConnection(conf);
IDatabase db = redis.GetDatabase();
The connection also includes the replicas that the Sentinels report. To read from a
replica, pass CommandFlags.PreferReplica (or CommandFlags.DemandReplica) to a read-only
command. Replication is asynchronous, so a replica can return stale data.
// Read from a replica if one is available, otherwise from the primary.
Console.WriteLine(db.StringGet("foo", CommandFlags.PreferReplica)); // prints bar
Connect to your production Redis with TLS
When you deploy your application, use TLS and follow the Redis security guidelines.
Before connecting your application to the TLS-enabled Redis server, ensure that your certificates and private keys are in the correct format.
To convert user certificate and private key from the PEM format to pfx, use this command:
openssl pkcs12 -inkey redis_user_private.key -in redis_user.crt -export -out redis.pfx
Enter password to protect your pfx file.
Establish a secure connection with your Redis database using this snippet.
ConfigurationOptions options = new ConfigurationOptions
{
EndPoints = { { "my-redis.cloud.redislabs.com", 6379 } },
User = "default", // use your Redis user. More info https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/
Password = "secret", // use your Redis password
Ssl = true,
SslProtocols = System.Security.Authentication.SslProtocols.Tls12
};
options.CertificateSelection += delegate
{
return X509CertificateLoader.LoadPkcs12FromFile("redis.pfx", "secret"); // use the password you specified for pfx file
};
options.CertificateValidation += ValidateServerCertificate;
bool ValidateServerCertificate(
object sender,
X509Certificate? certificate,
X509Chain? chain,
SslPolicyErrors sslPolicyErrors)
{
if (certificate == null) {
return false;
}
var ca = X509CertificateLoader.LoadCertificateFromFile("redis_ca.pem");
bool verdict = (certificate.Issuer == ca.Subject);
if (verdict) {
return true;
}
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
return false;
}
ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect(options);
//Creation of the connection to the DB
IDatabase conn = muxer.GetDatabase();
//send SET command
conn.StringSet("foo", "bar");
//send GET command and print the value
Console.WriteLine(conn.StringGet("foo"));
SNI hostname selection for cluster connections
The SNI precedence scheme described in this section
requires StackExchange.Redis v3.3.1 or later.
When you connect with TLS to a cluster that StackExchange.Redis discovers through
CLUSTER SLOTS, each discovered node needs its own
SNI hostname. This allows a shared load
balancer or proxy to route the TLS handshake to the right backend. StackExchange.Redis
resolves the SNI hostname for a connection in this order:
- An explicitly configured
ConfigurationOptions.SslHostalways wins. - Otherwise, a
DnsEndPointuses its own host. - Otherwise, the client falls back to the default SNI provider.
- If none of these is available, the client uses the endpoint address.
Because of this order, ConfigurationOptions.SslHost only reports a value if you set one
explicitly; it doesn't report a host that the client inferred for you.
Connect using Smart client handoffs (SCH)
Smart client handoffs (SCH) is a feature of Redis Cloud and Redis Software servers that lets them actively notify clients about planned server maintenance shortly before it happens. This lets a client take action to avoid disruptions in service. See Smart client handoffs for more information about SCH.
SCH support in StackExchange.Redis requires v3.3.0 or later. In v3.3.0 and
v3.3.1, the SCH API is marked [Experimental], and SCH is never enabled
unless you set MaintenanceNotifications yourself. From v3.4.0, the API is no
longer experimental, so the compiler no longer reports the SER010
diagnostic and you can remove any suppression you added for it.
The client enables SCH automatically, in Auto mode, when either of the
following is true:
- You connect using a hostname that the client recognizes as Redis Cloud
(
*.cloud.redislabs.com,*.cloud.redis.io, or*.redislabs.com) or Azure Managed Redis (*.redis.azure.netor*.redisenterprise.cache.azure.net). - You name a provider profile with the
defaultsconfiguration key (defaults=enterprise,defaults=rediscloud, ordefaults=amr).
For any other endpoint, SCH is disabled by default. This includes Redis
Software databases, which have no hostname pattern to recognize, and hosted
databases that you reach through a CNAME, private DNS, or a proxy. For these,
either set defaults=enterprise, which also applies that profile's other
default settings, or enable SCH with the MaintenanceNotifications
configuration option, in code or using the maintNotifications key in a
configuration string:
var options = ConfigurationOptions.Parse("host:6379,maintNotifications=Auto,maintRelaxedTimeout=15");
// or, in code:
var options = new ConfigurationOptions {
EndPoints = { "host:6379" },
MaintenanceNotifications = MaintenanceNotificationMode.Auto,
MaintenanceRelaxedTimeout = TimeSpan.FromSeconds(15),
};
var muxer = await ConnectionMultiplexer.ConnectAsync(options);
The ConfigurationOptions object accepts the following SCH-related parameters:
| Name | Description |
|---|---|
MaintenanceNotifications |
Whether to request SCH. The options are Disabled (the default, unless the client recognizes the endpoint or you set defaults), Enabled (require SCH and reject the connection, including a fallback to RESP2, if the server can't deliver it), and Auto (request SCH and tolerate a server that doesn't support it). |
MaintenanceMovingEndpointType |
The endpoint type to request for a replacement node during a handoff. The options are ServerDefault (no preference), Auto (the default; derived from the connection's scheme and encryption), InternalIp, InternalFqdn, ExternalIp, ExternalFqdn, and None. |
MaintenanceRelaxedTimeout |
The timeout to use for commands and connections while the server has announced maintenance. The default is 10 seconds. |
MaintenanceRelaxedWindowMax |
The maximum time to keep using the relaxed timeout if no notification arrives to close the window. The default is three times MaintenanceRelaxedTimeout. |
MaintenancePostEventRelaxedDuration |
How long to keep using the relaxed timeout after a closing notification, to cover trailing effects of the maintenance. |
Subscribe to the ConnectionMultiplexer.ServerMaintenanceEvent event to
observe SCH notifications. This is the same event that some servers (such as
Azure Cache for Redis) already use for their own maintenance notifications
(see Production usage),
so check the runtime type of the event arguments to tell the two apart:
muxer.ServerMaintenanceEvent += (object sender, ServerMaintenanceEvent e) => {
if (e is PushMaintenanceEvent pme) {
// A server-native SCH notification.
Console.WriteLine($"SCH notification: {pme.NotificationType} at {pme.EndPoint}");
} else {
// An older, provider-specific notification (for example, from Azure Cache for Redis).
Console.WriteLine($"Maintenance event: {e.RawMessage}");
}
};
RedisConnectionException and RedisTimeoutException both expose a
MaintenanceType property, so you can tell whether a failure happened
because of ongoing maintenance.
Multiplexing
Although example code typically works with a single connection, real-world code often uses multiple connections at the same time. Opening and closing connections repeatedly is inefficient, so it is best to manage open connections carefully to avoid this.
Several other Redis client libraries use connection pools to reuse a set of open connections efficiently. StackExchange.Redis uses a different approach called multiplexing, which sends all client commands and responses over a single connection. StackExchange.Redis manages multiplexing for you automatically. This gives high performance without requiring any extra coding. See Connection pools and multiplexing for more information.