You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Overall changes:
- [x] introduce `Resp2Type` and `Resp3Type` shims (`Resp2Type` has reduced types); existing code using `[Obsolete] Type` uses `Resp2Type` for minimal code impact
- [x] mark existing `Type` as `[Obsolete]`, and proxy to `Resp2Type` for compat
- [x] deal with null handling differences
- [x] deal with `Boolean`, which works very differently (`t`/`f` instead of `1`/`0`)
- [x] deal with `[+|-]{inf|nan}` when parsing doubles (explicitly called out in the RESP3 spec)
- [x] parse new tokens
- [x] `HELLO` handshake
- [x] core message and result handling
- [x] validation and fallback
- [x] prove all return types (see: redis/redis-specifications#15)
- [x] <strike>streamed RESP3</strike> omitting; not implemented by server; can revisit
- [x] deal with pub/sub differences
- [x] check routing of publish etc
- [x] check re-wire of subscription if failed
- [x] check receive notifications
- [x] connection management (i.e. not to spin up in resp3)
- [x] connection fallback spinup (i.e. if we were trying resp3 but failed)
- [x] other
- [x] [undocumented RESP3 delta](redis/redis-doc#2513)
- [x] run core tests in both RESP2 and RESP3
- [x] compensate for tests that expect separate subscription connections
Co-authored-by: Nick Craver <[email protected]>
Co-authored-by: Nick Craver <[email protected]>
Copy file name to clipboardExpand all lines: docs/Configuration.md
+30-11Lines changed: 30 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
Configuration
1
+
# Configuration
2
2
===
3
3
4
4
When connecting to Redis version 6 or above with an ACL configured, your ACL user needs to at least have permissions to run the ECHO command. We run this command to verify that we have a valid connection to the Redis service.
@@ -15,7 +15,7 @@ The `configuration` here can be either:
15
15
16
16
The latter is *basically* a tokenized form of the former.
17
17
18
-
Basic Configuration Strings
18
+
## Basic Configuration Strings
19
19
-
20
20
21
21
The *simplest* configuration example is just the host name:
@@ -66,7 +66,7 @@ Microsoft Azure Redis example with password
The `ConfigurationOptions` object has a wide range of properties, all of which are fully documented in intellisense. Some of the more common options to use include:
@@ -98,6 +98,7 @@ The `ConfigurationOptions` object has a wide range of properties, all of which a
98
98
| version={string} |`DefaultVersion`| (`4.0` in Azure, else `2.0`) | Redis version level (useful when the server does not make this available) |
99
99
| tunnel={string} |`Tunnel`|`null`| Tunnel for connections (use `http:{proxy url}` for "connect"-based proxy server) |
100
100
| setlib={bool} |`SetClientLibrary`|`true`| Whether to attempt to use `CLIENT SETINFO` to set the library name/version on the connection |
101
+
| protocol={string} |`Protocol`|`null`| Redis protocol to use; see section below |
Tokens in the configuration string are comma-separated; any without an `=` sign are assumed to be redis server endpoints. Endpoints without an explicit port will use 6379 if ssl is not enabled, and 6380 if ssl is enabled.
124
125
Tokens starting with `$` are taken to represent command maps, for example: `$config=cfg`.
125
126
126
-
Obsolete Configuration Options
127
+
## Obsolete Configuration Options
127
128
---
129
+
128
130
These options are parsed in connection strings for backwards compatibility (meaning they do not error as invalid), but no longer have any effect.
129
131
130
132
| Configuration string |`ConfigurationOptions`| Previous Default | Previous Meaning |
| responseTimeout={int} |`ResponseTimeout`|`SyncTimeout`| Time (ms) to decide whether the socket is unhealthy |
133
135
| writeBuffer={int} |`WriteBuffer`|`4096`| Size of the output buffer |
134
136
135
-
Automatic and Manual Configuration
137
+
## Automatic and Manual Configuration
136
138
---
137
139
138
140
In many common scenarios, StackExchange.Redis will automatically configure a lot of settings, including the server type and version, connection timeouts, and primary/replica relationships. Sometimes, though, the commands for this have been disabled on the redis server. In this case, it is useful to provide more information:
@@ -161,7 +163,8 @@ Which is equivalent to the command string:
A slightly unusual feature of redis is that you can disable and/or rename individual commands. As per the previous example, this is done via the `CommandMap`, but instead of passing a `HashSet<string>` to `Create()` (to indicate the available or unavailable commands), you pass a `Dictionary<string,string>`. All commands not mentioned in the dictionary are assumed to be enabled and not renamed. A `null` or blank value records that the command is disabled. For example:
@@ -184,8 +187,9 @@ The above is equivalent to (in the connection string):
184
187
$INFO=,$SELECT=use
185
188
```
186
189
187
-
RedisServerPermissions
190
+
## Redis Server Permissions
188
191
---
192
+
189
193
Iftheuseryou're connecting to Redis with is limited, it still needs to have certain commands enabled for the StackExchange.Redis to succeed in connecting. The client uses:
190
194
- `AUTH` toauthenticate
191
195
- `CLIENT` tosettheclientname
@@ -205,7 +209,7 @@ For example, a common _very_ minimal configuration ACL on the server (non-cluste
205
209
206
210
Note that if you choose to disable access to the above commands, it needs to be done via the `CommandMap` and not only the ACL on the server (otherwise we'll attempt the command and fail the handshake). Also, if any of the these commands are disabled, some functionality may be diminished or broken.
207
211
208
-
twemproxy
212
+
## twemproxy
209
213
---
210
214
211
215
[twemproxy](https://github.com/twitter/twemproxy) is a tool that allows multiple redis instances to be used as though it were a single server, with inbuilt sharding and fault tolerance (much like redis cluster, but implemented separately). The feature-set available to Twemproxy is reduced. To avoid having to configure this manually, the `Proxy` option can be used:
@@ -218,8 +222,9 @@ var options = new ConfigurationOptions
218
222
};
219
223
```
220
224
221
-
envoyproxy
225
+
##envoyproxy
222
226
---
227
+
223
228
[Envoyproxy](https://github.com/envoyproxy/envoy) is a tool that allows to front a redis cluster with a set of proxies, with inbuilt discovery and fault tolerance. The feature-set available to Envoyproxy is reduced. To avoid having to configure this manually, the `Proxy` option can be used:
224
229
```csharp
225
230
varoptions=newConfigurationOptions+{
@@ -229,7 +234,7 @@ var options = new ConfigurationOptions+{
229
234
```
230
235
231
236
232
-
Tiebreakers and Configuration Change Announcements
237
+
## Tiebreakers and Configuration Change Announcements
233
238
---
234
239
235
240
Normally StackExchange.Redis will resolve primary/replica nodes automatically. However, if you are not using a management tool such as redis-sentinel or redis cluster, there is a chance that occasionally you will get multiple primary nodes (for example, while resetting a node for maintenance it may reappear on the network as a primary). To help with this, StackExchange.Redis can use the notion of a *tie-breaker* - which is only used when multiple primaries are detected (not including redis cluster, where multiple primaries are *expected*). For compatibility with BookSleeve, this defaults to the key named `"__Booksleeve_TieBreak"` (always in database 0). This is used as a crude voting mechanism to help determine the *preferred* primary, so that work is routed correctly.
@@ -240,8 +245,9 @@ Both options can be customized or disabled (set to `""`), via the `.Configuratio
240
245
241
246
These settings are also used by the `IServer.MakeMaster()` method, which can set the tie-breaker in the database and broadcast the configuration change message. The configuration message can also be used separately to primary/replica changes simply to request all nodes to refresh their configurations, via the `ConnectionMultiplexer.PublishReconfigure` method.
242
247
243
-
ReconnectRetryPolicy
248
+
## ReconnectRetryPolicy
244
249
---
250
+
245
251
StackExchange.Redis automatically tries to reconnect in the background when the connection is lost for any reason. It keeps retrying until the connection has been restored. It would use ReconnectRetryPolicy to decide how long it should wait between the retries.
246
252
ReconnectRetryPolicy can be exponential (default), linear or a custom retry policy.
247
253
@@ -266,3 +272,16 @@ config.ReconnectRetryPolicy = new LinearRetry(5000);
266
272
//5 5000
267
273
//6 5000
268
274
```
275
+
276
+
## Redis protocol
277
+
278
+
Without specific configuration, StackExchange.Redis will use the RESP2 protocol; this means that pub/sub requires a separate connection to the server. RESP3 is a newer protocol
279
+
(usually, but not always, available on v6 servers and above) which allows (among other changes) pub/sub messages to be communicated on the *same* connection - which can be very
280
+
desirable in servers with a large number of clients. The protocol handshake needs to happen very early in the connection, so *by default* the library does not attempt a RESP3 connection
281
+
unless it has reason to expect it to work.
282
+
283
+
The library determines whether to use RESP3 by:
284
+
- The `HELLO` command has been disabled: RESP2 is used
285
+
- A protocol *other than*`resp3` or `3` is specified: RESP2 is used
286
+
- A protocol of `resp3` or `3` is specified: RESP3 is attempted (with fallback if it fails)
Copy file name to clipboardExpand all lines: docs/ReleaseNotes.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,7 @@ Current package versions:
8
8
9
9
## Unreleased
10
10
11
+
- Adds: RESP3 support ([#2396 by mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/2396)) - see https://stackexchange.github.io/StackExchange.Redis/Resp3
11
12
- Fix [#2507](https://github.com/StackExchange/StackExchange.Redis/issues/2507): Pub/sub with multi-item payloads should be usable ([#2508 by mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/2508))
12
13
- Add: connection-id tracking (internal only, no public API) ([#2508 by mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/2508))
13
14
- Add: `ConfigurationOptions.LoggerFactory` for logging to an `ILoggerFactory` (e.g. `ILogger`) all connection and error events ([#2051 by NickCraver](https://github.com/StackExchange/StackExchange.Redis/pull/2051))
RESP2 and RESP3 are evolutions of the Redis protocol, with RESP3 existing from Redis server version 6 onwards (v7.2+ for Redis Enterprise). The main differences are:
4
+
5
+
1. RESP3 can carry out-of-band / "push" messages on a single connection, where-as RESP2 requires a separate connection for these messages
6
+
2. RESP3 can (when appropriate) convey additional semantic meaning about returned payloads inside the same result structure
7
+
3. Some commands (see [this topic](https://github.com/redis/redis-doc/issues/2511)) return different result structures in RESP3 mode; for example a flat interleaved array might become a jagged array
8
+
9
+
For most people, #1 is the main reason to consider RESP3, as in high-usage servers - this can halve the number of connections required.
10
+
This is particularly useful in hosted environments where the number of inbound connections to the server is capped as part of a service plan.
11
+
Alternatively, where users are currently choosing to disable the out-of-band connection to achieve this, they may now be able to re-enable this
12
+
(for example, to receive server maintenance notifications) *without* incurring any additional connection overhead.
13
+
14
+
Because of the significance of #3 (and to avoid breaking your code), the library does not currently default to RESP3 mode. This must be enabled explicitly
15
+
via `ConfigurationOptions.Protocol` or by adding `,protocol=resp3` (or `,protocol=3`) to the configuration string.
16
+
17
+
---
18
+
19
+
#3 is a critical one - the library *should* already handle all documented commands that have revised results in RESP3, but if you're using
20
+
`Execute[Async]` to issue ad-hoc commands, you may need to update your processing code to compensate for this, ideally using detection to handle
21
+
*either* format so that the same code works in both REP2 and RESP3. Since the impacted commands are handled internally by the library, in reality
22
+
this should not usually present a difficulty.
23
+
24
+
The minor (#2) and major (#3) differences to results are only visible to your code when using:
25
+
26
+
- Lua scripts invoked via the `ScriptEvaluate[Async](...)` or related APIs, that either:
27
+
- Uses the `redis.setresp(3)` API and returns a value from `redis.[p]call(...)`
28
+
- Returns a value that satisfies the [LUA to RESP3 type conversion rules](https://redis.io/docs/manual/programmability/lua-api/#lua-to-resp3-type-conversion)
29
+
- Ad-hoc commands (in particular: *modules*) that are invoked via the `Execute[Async](string command, ...)` API
30
+
31
+
...both which return `RedisResult`. **If you are not using these APIs, you should not need to do anything additional.**
32
+
33
+
Historically, you could use the `RedisResult.Type` property to query the type of data returned (integer, string, etc). In particular:
34
+
35
+
- Two new properties are added: `RedisResult.Resp2Type` and `RedisResult.Resp3Type`
36
+
- The `Resp3Type` property exposes the new semantic data (when using RESP3) - for example, it can indicate that a value is a double-precision number, a boolean, a map, etc (types that did not historically exist)
37
+
- The `Resp2Type` property exposes the same value that *would* have been returned if this data had been returned over RESP2
38
+
- The `Type` property is now marked obsolete, but functions identically to `Resp2Type`, so that pre-existing code (for example, that has a `switch` on the type) is not impacted by RESP3
39
+
- The `ResultType.MultiBulk` is superseded by `ResultType.Array` (this is a nomenclature change only; they are the same value and function identically)
40
+
41
+
Possible changes required due to RESP3:
42
+
43
+
1. To prevent build warnings, replace usage of `ResultType.MultiBulk` with `ResultType.Array`, and usage of `RedisResult.Type` with `RedisResult.Resp2Type`
44
+
2. If you wish to exploit the additional semantic data when enabling RESP3, use `RedisResult.Resp3Type` where appropriate
45
+
3. If you are enabling RESP3, you must verify whether the commands you are using can give different result shapes on RESP3 connections
0 commit comments