你见过5点半的曼哈顿街头吗?一年前,当antirez在参加完纽约Redis大会后,5:30就在旅店中醒来了,面对曼哈顿街头的美丽景色,在芸芸众生中思索Redis的未来。包括客户端缓存。
简介
Redis实现的是一个服务端协助的客户端缓存,叫做tracking。用法是:CLIENT TRACKING ON|OFF [REDIRECT client-id] [PREFIX prefix] [BCAST] [OPTIN] [OPTOUT] [NOLOOP]
当tracking开启时,Redis客户端会“记住”每个请求过的key;当服务端key发生修改命令操作时,就会发送失效消息给客户端。失效消息可以通过RESP3协议发送给请求的客户端,或者转发给一个订阅频道__redis__:invalidate
的连接。
- REDIRECT:将失效消息转发给另外一个客户端。当我们使用的是老的RESP2和Redis通讯时,client本身不支持处理失效消息,所以可以开启一个Pub/Sub客户端处理失效消息。
- BCAST:使用广播模式开始tracking,在这种模式下客户端需要设置将track的key前缀,这些key的失效消息会广播给所有参与的客户端,不管这些客户端是否请求/缓存了这些key。不开启广播模式的时候,Redis只会Track那些只读命令请求的key,并且只会报告一次失效消息。
- PREFIX:只应用了广播模式,注册一个key的前缀。所有以这个前缀开始的key有修改时,都会发送失效消息。可以注册多个前缀,如果不设置前缀,那么广播模式会track每一个key。
- OPTIN:当广播模式没有开启时,正常不会track只读命令的key,除非它们在CLIENT CACHING yes之后被调用。
- OPTPUT:当广播模式没有开启时,正常会track只读命令的key,除非它们在CLIENT CACHING off之后被调用。
- NOLOOP:不发送自身修改的key失效消息给自己。
使用验证
为了能够更好的观察,我们使用telnet来进行连接。并开启RESP3协议模式1
2telnet 127.0.0.1 6379
hello 3
BCAST 广播模式
在使用telnet连接redis服务后,使用命令client tracking on
启动广播模式进行。并使用get a
命令模拟读请求。
在另外一个客户端对该key进行修改后,telnet这个client立即会收到该key过期的消息通知。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26hello 3
%7
$6
server
$5
redis
$7
version
$5
6.0.5
$5
proto
:3
...
client tracking on
+OK
get a
$1
2
>2
$10
invalidate
*1
$1
a
在收到key的实效消息通知后,如果其他客户端再对该key进行修改。telnet也不会再收到实效消息。这意味telnet客户端已经将该key的缓存给清理了,除非再次进行读请求将该key再次进行缓存。
在telnet运行中,随时可以使用命令client tracking off
关闭广播模式,telnet客户端将不会再缓存key。
PREFIX 前缀模式
在上面的广播模式下,客户端会缓存所有的请求过的key。如果你只想跟踪特定的key,则可以使用前缀匹配的方式。
使用以下命令只对指定前缀的key进行缓存,可以执行多次,指定不同前缀。1
2client tracking on prefix a bcast
client tracking on prefix user bcast
你可以使用client tracking off
取消对所有key前缀的缓存。但是不支持只停止特定单个前缀key的缓存。
OPTIN 选择加入
使用optin
可以有选择的开启tracking。只有你发送client caching yes
之后的下一条只读命令涉及的key才会被tracking。其他只读命令中的key不会被tracking。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19client tracking on optin
+OK
get a
$1
2
client caching yes
+OK
get a
$4
1000
>2
$10
invalidate
*1
$1
a
OPTOUT 选择退出
使用optout
可以有选择的关闭tracking。当你发送client caching off
之后的下一条只读命令涉及的key不会被tracking。其他只读命令中的key都会被tracking。它的效果与optin
相反。
REDIRECT
REDIRECT是为了兼容RESP2协议的一个处理方式,能够将失效消息转发给另外一个client。
RESP2协议客户端,查看客户端ID,并开启订阅模式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20client id
:135
SUBSCRIBE __redis__:invalidate
*3
$9
subscribe
---
$20
__redis__:invalidate
:1
*3
$7
message
$20
__redis__:invalidate
*1
$1
a
RESP3开启失效消息转发,并执行修改操作。在执行修改操作后,RESP2客户端就收到了失效消息。1
2
3
4client tracking on bcast redirect 135
+OK
set a 300
+OK
如果转发的目的client开启了RESP3协议,就不需要RESP3 Pub/Sub了,因为RESP3原生支持Push消息。
NOLOOP
正常设置时,失效消息是发给所有参与的Client,但是如果设置了NOLOOP,则不会发送给更新这个key的Client。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24client tracking on bcast
+OK
get a
$1
2
set a 1
+OK
>2
$10
invalidate
*1
$1
a
----
client tracking on bcast noloop
+OK
set a 2
+OK
get a
$1
2
set a 1
+OK