Skip to content

Commit a026c16

Browse files
committed
Merge branch 'main' into DOC-4288
2 parents 3c1b0c0 + 9bcb951 commit a026c16

File tree

86 files changed

+1821
-353
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1821
-353
lines changed

build/components/markdown.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def make_command_linkifier(commands: dict, name: str):
138138
def linkifier(m):
139139
command = m.group(1)
140140
if command in commands and command not in exclude:
141-
return f'[`{command}`](/commands/{command_filename(command)})'
141+
return f'[`{command}`]({{{{< relref "/commands/{command_filename(command)}" >}}}})'
142142
else:
143143
return m.group(0)
144144
return linkifier

build/update_cmds.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python3
2+
from components.syntax import Command
3+
from components.markdown import Markdown
4+
import json
5+
6+
if __name__ == '__main__':
7+
with open('data/commands_core.json', 'r') as f:
8+
j = json.load(f)
9+
10+
board = []
11+
for k in j:
12+
v = j.get(k)
13+
c = Command(k, v)
14+
sf = c.syntax()
15+
path = f'content/commands/{k.lower().replace(" ", "-")}/'
16+
md = Markdown(f'{path}index.md')
17+
md.fm_data |= v
18+
md.fm_data.update({
19+
'syntax_str': str(c),
20+
'syntax_fmt': sf,
21+
})
22+
if 'replaced_by' in md.fm_data:
23+
replaced = md.generate_commands_links(k, j, md.fm_data['replaced_by'])
24+
md.fm_data['replaced_by'] = replaced
25+
md.persist()

content/commands/client-caching/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ title: CLIENT CACHING
4343
This command controls the tracking of the keys in the next command executed
4444
by the connection, when tracking is enabled in `OPTIN` or `OPTOUT` mode.
4545
Please check the
46-
[client side caching documentation]({{< relref "/develop/use/client-side-caching" >}}) for
46+
[client side caching documentation]({{< relref "/develop/connect/clients/client-side-caching" >}}) for
4747
background information.
4848

4949
When tracking is enabled Redis, using the [`CLIENT TRACKING`]({{< relref "/commands/client-tracking" >}}) command, it is

content/commands/client-getredir/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ syntax_str: ''
3131
title: CLIENT GETREDIR
3232
---
3333
This command returns the client ID we are redirecting our
34-
[tracking]({{< relref "/develop/use/client-side-caching" >}}) notifications to. We set a client
34+
[tracking]({{< relref "/develop/connect/clients/client-side-caching#tracking" >}}) notifications to. We set a client
3535
to redirect to when using [`CLIENT TRACKING`]({{< relref "/commands/client-tracking" >}}) to enable tracking. However in
3636
order to avoid forcing client libraries implementations to remember the
3737
ID notifications are redirected to, this command exists in order to improve

content/commands/client-tracking/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ syntax_str: "[REDIRECT\_client-id] [PREFIX\_prefix [PREFIX prefix ...]] [BCAST]
7575
title: CLIENT TRACKING
7676
---
7777
This command enables the tracking feature of the Redis server, that is used
78-
for [server assisted client side caching]({{< relref "/develop/use/client-side-caching" >}}).
78+
for [server assisted client side caching]({{< relref "/develop/connect/clients/client-side-caching#tracking" >}}).
7979

8080
When tracking is enabled Redis remembers the keys that the connection
8181
requested, in order to send later invalidation messages when such keys are
@@ -85,7 +85,7 @@ when the RESP3 protocol is used) or redirected in a different connection
8585
available where clients participating in this protocol receive every
8686
notification just subscribing to given key prefixes, regardless of the
8787
keys that they requested. Given the complexity of the argument please
88-
refer to [the main client side caching documentation]({{< relref "/develop/use/client-side-caching" >}}) for the details. This manual page is only a reference for the options of this subcommand.
88+
refer to [the main client side caching documentation]({{< relref "/develop/reference/client-side-caching" >}}) for the details. This manual page is only a reference for the options of this subcommand.
8989

9090
In order to enable tracking, use:
9191

content/commands/client-trackinginfo/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ syntax_fmt: CLIENT TRACKINGINFO
2929
syntax_str: ''
3030
title: CLIENT TRACKINGINFO
3131
---
32-
The command returns information about the current client connection's use of the [server assisted client side caching]({{< relref "/develop/use/client-side-caching" >}}) feature.
32+
The command returns information about the current client connection's use of the [server assisted client side caching]({{< relref "/develop/connect/clients/client-side-caching" >}}) feature.
3333

3434
Here's the list of tracking information sections and their respective values:
3535

content/commands/json.strlen/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ is JSONPath to specify. Default is root `$`, if not provided. Returns null if th
4949

5050
## Return
5151

52-
JSON.STRLEN returns by recursive descent an array of integer replies for each path, the array's length, or `nil`, if the matching JSON value is not a string.
52+
JSON.STRLEN returns by recursive descent an array of integer replies for each path, the string's length, or `nil`, if the matching JSON value is not a string.
5353
For more information about replies, see [Redis serialization protocol specification]({{< relref "/develop/reference/protocol-spec" >}}).
5454

5555
## Examples

content/commands/readwrite/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ command_flags:
1818
- stale
1919
- fast
2020
complexity: O(1)
21-
description: Enables read-write queries for a connection to a Reids Cluster replica
21+
description: Enables read-write queries for a connection to a Redis Cluster replica
2222
node.
2323
group: cluster
2424
hidden: false
2525
linkTitle: READWRITE
2626
since: 3.0.0
27-
summary: Enables read-write queries for a connection to a Reids Cluster replica node.
27+
summary: Enables read-write queries for a connection to a Redis Cluster replica node.
2828
syntax_fmt: READWRITE
2929
syntax_str: ''
3030
title: READWRITE
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
- rs
8+
- rc
9+
- oss
10+
- kubernetes
11+
- clients
12+
description: Server-assisted, client-side caching in Redis
13+
linkTitle: Client-side caching
14+
title: Client-side caching introduction
15+
weight: 20
16+
---
17+
18+
*Client-side caching* reduces network traffic between
19+
a Redis client and the server, which generally improves performance.
20+
21+
By default, an [application server](https://en.wikipedia.org/wiki/Application_server)
22+
(which sits between the user app and the database) contacts the
23+
Redis database server through the client library for every read request.
24+
The diagram below shows the flow of communication from the user app,
25+
through the application server to the database and back again:
26+
27+
{{< image filename="images/csc/CSCNoCache.drawio.svg" >}}
28+
29+
When you use client-side caching, the client library
30+
maintains a local cache of data items as it retrieves them
31+
from the database. When the same items are needed again, the client
32+
can satisfy the read requests from the cache instead of the database:
33+
34+
{{< image filename="images/csc/CSCWithCache.drawio.svg" >}}
35+
36+
Accessing the cache is much faster than communicating with the database over the
37+
network and it reduces network traffic. Client-side caching reduces
38+
the load on the database server, so you may be able to run it using less hardware
39+
resources.
40+
41+
As with other forms of [caching](https://en.wikipedia.org/wiki/Cache_(computing)),
42+
client-side caching works well in the very common use case where a small subset of the data
43+
is accessed much more frequently than the rest of the data (according
44+
to the [Pareto principle](https://en.wikipedia.org/wiki/Pareto_principle)).
45+
46+
## Updating the cache when the data changes {#tracking}
47+
48+
All caching systems must implement a scheme to update data in the cache
49+
when the corresponding data changes in the main database. Redis uses an
50+
approach called *tracking*.
51+
52+
When client-side caching is enabled, the Redis server remembers or *tracks* the set of keys
53+
that each client connection has previously read. This includes cases where the client
54+
reads data directly, as with the [`GET`]({{< relref "/commands/get" >}})
55+
command, and also where the server calculates values from the stored data,
56+
as with [`STRLEN`]({{< relref "/commands/strlen" >}}). When any client
57+
writes new data to a tracked key, the server sends an invalidation message
58+
to all clients that have accessed that key previously. This message warns
59+
the clients that their cached copies of the data are no longer valid and the clients
60+
will evict the stale data in response. Next time a client reads from
61+
the same key, it will access the database directly and refresh its cache
62+
with the updated data.
63+
64+
{{< note >}}If any connection from a client gets disconnected (including
65+
one from a connection pool), then the client will flush all keys from the
66+
client-side cache. Caching then resumes for subsequent reads from the
67+
connections that are still active.
68+
{{< /note >}}
69+
70+
The sequence diagram below shows how two clients might interact as they
71+
access and update the same key:
72+
73+
{{< image filename="images/csc/CSCSeqDiagram.drawio.svg" >}}
74+
75+
## Which commands can cache data?
76+
77+
All read-only commands (with the `@read`
78+
[ACL category]({{< relref "/operate/oss_and_stack/management/security/acl" >}}))
79+
will use cached data, except for the following:
80+
81+
- Any commands for
82+
[probabilistic data types]({{< relref "/develop/data-types/probabilistic" >}}).
83+
These types are designed to be updated frequently, which means that caching
84+
has little or no benefit.
85+
- Non-deterministic commands such as [`HGETALL`]({{< relref "/commands/hgetall" >}}),
86+
[`HSCAN`]({{< relref "/commands/hscan" >}}),
87+
and [`ZRANDMEMBER`]({{< relref "/commands/zrandmember" >}}). By design, these commands
88+
give different results each time they are called.
89+
- Redis Query Engine commands (with the `FT.*` prefix), such as
90+
[`FT.SEARCH`]({{< baseurl >}}/commands/ft.search).
91+
92+
You can use the [`MONITOR`]({{< relref "/commands/monitor" >}}) command to
93+
check the server's behavior when you are using client-side caching. Because `MONITOR` only
94+
reports activity from the server, you should find the first cacheable
95+
access to a key causes a response from the server. However, subsequent
96+
accesses are satisfied by the cache, and so `MONITOR` should report no
97+
server activity if client-side caching is working correctly.
98+
99+
## What data gets cached for a command?
100+
101+
Broadly speaking, the data from the specific response to a command invocation
102+
gets cached after it is used for the first time. Subsets of that data
103+
or values calculated from it are retrieved from the server as usual and
104+
then cached separately. For example:
105+
106+
- The whole string retrieved by [`GET`]({{< relref "/commands/get" >}})
107+
is added to the cache. Parts of the same string retrieved by
108+
[`SUBSTR`]({{< relref "/commands/substr" >}}) are calculated on the
109+
server the first time and then cached separately from the original
110+
string.
111+
- Using [`GETBIT`]({{< relref "/commands/getbit" >}}) or
112+
[`BITFIELD`]({{< relref "/commands/bitfield" >}}) on a string
113+
caches the returned values separately from the original string.
114+
- For composite data types accessed by keys
115+
([hash]({{< relref "/develop/data-types/hashes" >}}),
116+
[JSON]({{< relref "/develop/data-types/json" >}}),
117+
[set]({{< relref "/develop/data-types/sets" >}}), and
118+
[sorted set]({{< relref "/develop/data-types/sorted-sets" >}})),
119+
the whole object is cached separately from the individual fields.
120+
So the results of `JSON.GET mykey $` and `JSON.GET mykey $.myfield` create
121+
separate entries in the cache.
122+
- Ranges from [lists]({{< relref "/develop/data-types/lists" >}}),
123+
[streams]({{< relref "/develop/data-types/streams" >}}),
124+
and [sorted sets]({{< relref "/develop/data-types/sorted-sets" >}})
125+
are cached separately from the object they form a part of. Likewise,
126+
subsets returned by [`SINTER`]({{< relref "/commands/sinter" >}}) and
127+
[`SDIFF`]({{< relref "/commands/sdiff" >}}) create separate cache entries.
128+
- For multi-key read commands such as [`MGET`]({{< relref "/commands/mget" >}}),
129+
the ordering of the keys is significant. For example `MGET name:1 name:2` is
130+
cached separately from `MGET name:2 name:1` because the server returns the
131+
values in the order you specify.
132+
- Boolean or numeric values calculated from data types (for example
133+
[`SISMEMBER`]({{< relref "/commands/sismember" >}})) and
134+
[`LLEN`]({{< relref "/commands/llen" >}}) are cached separately from the
135+
object they refer to.
136+
137+
## Usage recommendations
138+
139+
Like any caching system, client-side caching has some limitations:
140+
141+
- The cache has only a limited amount of memory available. When the limit
142+
is reached, the client must *evict* potentially useful items from the
143+
cache to make room for new ones.
144+
- Cache misses, tracking, and invalidation messages always add a slight
145+
performance penalty.
146+
147+
Below are some guidelines to help you use client-side caching efficiently, within these
148+
limitations:
149+
150+
- **Use a separate connection for data that is not cache-friendly**:
151+
Caching gives the most benefit
152+
for keys that are read frequently and updated infrequently. However, you
153+
may also have data, such as counters and scoreboards, that receives frequent
154+
updates. In cases like this, the performance overhead of the invalidation
155+
messages can be greater than the savings made by caching. Avoid this problem
156+
by using a separate connection *without* client-side caching for any data that is
157+
not cache-friendly.
158+
- **Estimate how many items you can cache**: The client libraries let you
159+
specify the maximum number of items you want to hold in the cache. You
160+
can calculate an estimate for this number by dividing the
161+
maximum desired size of the
162+
cache in memory by the average size of the items you want to store
163+
(use the [`MEMORY USAGE`]({{< relref "/commands/memory-usage" >}})
164+
command to get the memory footprint of a key). For example, if you had
165+
10MB (or 10485760 bytes) available for the cache, and the average
166+
size of an item was 80 bytes, you could fit approximately
167+
10485760 / 80 = 131072 items in the cache. Monitor memory usage
168+
on your server with a realistic test load to adjust your estimate
169+
up or down.
170+
171+
## Reference
172+
173+
The Redis server implements extra features for client-side caching that are not used by
174+
the main Redis clients, but may be useful for custom clients and other
175+
advanced applications. See
176+
[Client-side caching reference]({{< relref "/develop/reference/client-side-caching" >}})
177+
for a full technical guide to all the options available for client-side caching.

content/develop/connect/clients/dotnet.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dotnet add package NRedisStack
3737

3838
Connect to localhost on port 6379.
3939

40-
```
40+
```csharp
4141
using NRedisStack;
4242
using NRedisStack.RedisStackCommands;
4343
using StackExchange.Redis;
@@ -70,7 +70,7 @@ Console.WriteLine(String.Join("; ", hashFields));
7070
// name: John; surname: Smith; company: Redis; age: 29
7171
```
7272

73-
To access Redis Stack capabilities, you should use appropriate interface like this:
73+
To access Redis Stack capabilities, use the appropriate interface like this:
7474

7575
```
7676
IBloomCommands bf = db.BF();
@@ -84,7 +84,7 @@ IJsonCommands json = db.JSON();
8484
ITimeSeriesCommands ts = db.TS();
8585
```
8686

87-
### Connect to a Redis cluster
87+
## Connect to a Redis cluster
8888

8989
To connect to a Redis cluster, you just need to specify one or all cluster endpoints in the client configuration:
9090

@@ -106,7 +106,7 @@ db.StringSet("foo", "bar");
106106
Console.WriteLine(db.StringGet("foo")); // prints bar
107107
```
108108

109-
### Connect to your production Redis with TLS
109+
## Connect to your production Redis with TLS
110110

111111
When you deploy your application, use TLS and follow the [Redis security]({{< relref "/operate/oss_and_stack/management/security/" >}}) guidelines.
112112

@@ -169,6 +169,23 @@ conn.StringSet("foo", "bar");
169169
Console.WriteLine(conn.StringGet("foo"));
170170
```
171171

172+
## Multiplexing
173+
174+
Although example code typically works with a single connection,
175+
real-world code often uses multiple connections at the same time.
176+
Opening and closing connections repeatedly is inefficient, so it is best
177+
to manage open connections carefully to avoid this.
178+
179+
Several other
180+
Redis client libraries use *connection pools* to reuse a set of open
181+
connections efficiently. NRedisStack uses a different approach called
182+
*multiplexing*, which sends all client commands and responses over a
183+
single connection. NRedisStack manages multiplexing for you automatically.
184+
This gives high performance without requiring any extra coding.
185+
See
186+
[Connection pools and multiplexing]({{< relref "/develop/connect/clients/pools-and-muxing" >}})
187+
for more information.
188+
172189
## Example: Indexing and querying JSON documents
173190

174191
This example shows how to convert Redis search results to JSON format using `NRedisStack`.

0 commit comments

Comments
 (0)