Redis6.0 客户端缓存

新特性预览

  • SSL
  • ACL: 更好,命令支持
  • RESP3
  • Client side caching:重新设计
  • Threaded I/O
  • Diskless replication on replicas
  • Cluster support in Redis-benchmark and improved redis-cli cluster support
  • Disque in beta as a module of Redis: 开始侵入消息队列领域
  • Redis Cluster Proxy
  • 支持RDB不再使用时可立即删除,针对不落盘的场景
  • PSYNC2: 优化的复制协议
  • 超时设置支持更友好
  • 更快的RDB加载,20% ~ 30%的提升
  • STRALGO,新的字符串命令,目前只有一个实现LCS (longest common subsequence)

    Client side caching(客户端缓存)

    Redis实现的是一个服务端协助的客户端缓存,叫做tracking。客户端缓存的命令是:

    1. CLIENT TRACKING ON|OFF [REDIRECT client-id] [PREFIX prefix] [BCAST] [OPTIN] [OPTOUT] [NOLOOP]

    tracking开启时, Redis会”记住”每个客户端请求的key,当key的值发现变化时会发送失效信息给客户端(invalidation message)。失效信息可以通过RESP3协议发送给请求的客户端,或者转发给一个不同的连接(支持RESP2+ Pub/Sub)。当广播模式(broadcasting)开启时,参与tracking的客户端会收到它通过前缀订阅的key的相关的通知,即使它没请求过对应的key。同时还提供了OPTINOPTOUT等模式。

    失效消息:当一个key的数据有修改的时候,需要告诉客户端它以前缓存的数据失效了,这时redis会主动发送一条失效消息

  • REDIRECT : 将失效消息转发给另外一个客户端。当不使用RESP3而是使用老的RESP2和Redis通讯时,client本身不支持处理失效消息,所以可以开启一个支持Pub/Sub客户端处理失效消息。当然如果客户端支持RESP3也可以将失效消息转发给另外一个客户端。这个cace放在最后演示。

  • BCAST: 使用广播模式开始tracking。在这种模式下客户端需要设置将track的key的前缀,这些key的失效消息会广播给所有参与的客户端,不管这些客户端是否请求/缓存额这些key。不开始广播模式时,Redis只会track那些只读命令请求的key,并且只会报告一次失效消息。
  • PREFIX : 只应用了广播模式,注册一个key的前缀。所有以这个前缀开始的key有修改时,都会发送失效消息。可以注册多个前缀。如果不设置前缀,那么广播模式会track每一个key。
  • OPTIN: 当广播模式没有激活时,正常不会track只读命令的key,除非它们在CLIENT CACHING yes之后被调用。
  • OPTOUT: 当广播模式没有激活时,正常会track只读命令的key,除非它们在CLIENT CACHING off之后被调用。
  • NOLOOP: 不发送client自己修改的key。

    环境说明

    Redis6.0.5(安装参考如下)

语雀内容
为了更好的观察redis的返回结果,使用telnet而不是redis-cli作为client连接redis,因为redis-cli对结果做了处理,尤其是失效消息,可能无法观测到。

1、BCAST 广播模式 (client tracking on)

A.使用Telent连接6380端口进行测试(监听响应的协议内容),连接上之后发送hello 3开启RESP3协议-(在设置新的监听模式前需要关闭其他的监听模式)

  1. $ telnet 127.0.0.1 6380
  2. $ hello 3
  3. version
  4. $5
  5. 6.0.5
  6. $5
  7. proto
  8. :3
  9. $2
  10. id
  11. :1648
  12. $4
  13. mode
  14. $10
  15. standalone
  16. $4
  17. role
  18. $6
  19. master
  20. $7
  21. modules
  22. *1
  23. %2
  24. $4
  25. name
  26. $2
  27. bf
  28. $3
  29. ver
  30. :20201

image.png

B.通过telnet开启 tracking 操作Redis Server

  1. client tracking on
  2. +OK
  3. set a 1
  4. +OK
  5. get a
  6. $1
  7. 1

image.png

C.使用Redis-cli更新a的值,观察telent收到失效消息

更新值

  1. 127.0.0.1:6380> set a 2
  2. OK

image.png
telnet收到失效信息
image.png

D.取消tracking

  1. $ client tracking off

2、tracking特定前缀的key (client tracking on)

上面的方式会tracking所有的key,如果只想跟踪特定的key, 目前redis提供了一种方式,也就是前缀匹配的方式。可以tracking特定前缀的key。它应用了广播模式。

A.使用telnet client设定前缀和开启tracking(在设置新的监听模式前需要关闭其他的监听模式)-(在设置新的监听模式前需要关闭其他的监听模式)

并设置key以及初值

  1. hello 3
  2. client tracking off
  3. +OK
  4. client tracking on prefix a bcast
  5. +OK
  6. client tracking on prefix user bcast
  7. +OK
  8. set abc 100
  9. >2
  10. $10
  11. invalidate
  12. *1
  13. $3
  14. abc
  15. set user:211 good
  16. +OK
  17. >2
  18. $10
  19. invalidate
  20. *1
  21. $8
  22. user:211
  23. set feed 112
  24. +OK

image.png

B.使用Redis-cli更新具有特定前缀的key值,可以在telnet观察到失效消息

  1. 127.0.0.1:6380> set abc 101
  2. OK
  3. 127.0.0.1:6380> set user:211 bad
  4. OK
  5. 127.0.0.1:6380> set feed 1222
  6. OK

telnet client收到abcuser:211的失效消息,而不会收到feed的失效消息:
image.png

C.通过client tracking off停止客户端缓存

目前貌似不能只停止对单个的前缀的tracking。即使使用client tracking off prefix user也是取消对所有的key的tracking

  1. client tracking off
  2. +OK

3、选择加入(optin)

如果使用OPTIN,可以有选择的开启tracking。只有发送client caching yes之后的下一条的只读命令的key才会tracking, 否则其它的只读命令中的key不会tracking

A.首先开始optin,读取a的指,这个时候使用redis-cli client修改a的值为1000,并没有收到a的失效消息。-(在设置新的监听模式前需要关闭其他的监听模式)

  1. hello 3
  2. client tracking off
  3. +OK
  4. client tracking on optin
  5. +OK
  6. get a
  7. $1
  8. 2

B.接下来发送client caching yes,紧接着获取a的值,这个时候如果再修改a的值,就可以收到一条a的失效消息

  1. client tracking on optin
  2. +OK
  3. get a
  4. $1
  5. 2
  6. client caching yes
  7. +OK
  8. get a
  9. $1
  10. 2
  11. set a 1
  12. >2
  13. $10
  14. invalidate
  15. *1
  16. $1
  17. a
  18. +OK

image.png

C.必须是紧跟着client caching yes ,比如发送下面的命令,只会tracking abc,而不是a

  1. client caching yes
  2. +OK
  3. get abc
  4. $3
  5. 101
  6. set abc 100
  7. >2
  8. $10
  9. invalidate
  10. *1
  11. $3
  12. abc
  13. +OK
  14. set a 2
  15. +OK
  16. get a
  17. $2
  18. 2

image.png

4、选择退出

如果使用OPTOUT,也可以有选择的退出tracking。只有发送client caching off之后的下一条的只读命令的key才会停止tracking, 否则其它的只读命令中的key都会被tracking
可以看到它和OPTIN正好相反,可以根据场景来选择。

A.开启OPTOUT之后,对任意的key的变动都收到失效消息-(在设置新的监听模式前需要关闭其他的监听模式)

  1. hello 3
  2. client tracking off
  3. +OK
  4. client tracking on optout
  5. +OK
  6. get a
  7. $2
  8. 2
  9. set a 1
  10. >2
  11. $10
  12. invalidate
  13. *1
  14. $1
  15. a
  16. +OK
  17. set abc 111
  18. +OK
  19. get abc
  20. $3
  21. 111
  22. set abc 123
  23. >2
  24. $10
  25. invalidate
  26. *1
  27. $3
  28. abc
  29. +OK

image.png

B.排除b这个key,只针对他的监听排除,之后对b的变动并不会收到b的失效消息。

  1. client caching no
  2. +OK
  3. get b
  4. _
  5. set b 123
  6. +OK
  7. set abc 124
  8. +OK
  9. get abc
  10. $3
  11. 124
  12. set abc 123
  13. >2
  14. $10
  15. invalidate
  16. *1
  17. $3
  18. abc
  19. +OK

image.png
注意: OPTINOPTOUT是针对的非BCAST场景,也就是只有发送了key的只读命令后,才会跟踪相应的key。而广播模式是无论是否发送过key的只读命令,只要redis修改了key,都会发送相应key(或者匹配前缀的key)的失效消息。

5、NOLOOP

正常设置时,失效消息是发给所有参与的client,但是如果设置了NOLOOP,则不会发送给更新这个key的client。

  1. hello 3
  2. client tracking off
  3. +OK
  4. client tracking on bcast noloop
  5. +OK
  6. get a
  7. $1
  8. 1
  9. set a 2
  10. +OK
  11. set a 1
  12. +OK
  13. client tracking off
  14. +OK
  15. client tracking on bcast
  16. +OK
  17. get a
  18. $1
  19. 1
  20. set a 2
  21. +OK
  22. >2
  23. $10
  24. invalidate
  25. *1
  26. $1
  27. a

image.png

6、REDIRECT

转发消息的处理。这是为了兼容RESP2协议一个处理方式,将失效消息转发给另外一个client。

A.首先查看redis-cli的client id

  1. 127.0.0.1:6380> client list
  2. id=7 addr=127.0.0.1:40819 fd=11 name=sentinel-4b84598d-cmd age=5415 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=publish user=default
  3. id=8 addr=127.0.0.1:33181 fd=12 name=sentinel-4b84598d-pubsub age=5415 idle=0 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=subscribe user=default
  4. id=9 addr=127.0.0.1:57018 fd=13 name=sentinel-a4c5c2fb-cmd age=5415 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=publish user=default
  5. id=10 addr=127.0.0.1:42870 fd=14 name=sentinel-a4c5c2fb-pubsub age=5415 idle=0 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=subscribe user=default
  6. id=4 addr=127.0.0.1:46312 fd=8 name= age=5415 idle=0 flags=S db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=replconf user=default
  7. id=1648 addr=121.239.106.21:53729 fd=16 name= age=3780 idle=426 flags=t db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=set user=default
  8. id=1619 addr=127.0.0.1:39158 fd=15 name= age=3807 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client user=default
  9. id=5 addr=127.0.0.1:59946 fd=9 name=sentinel-14bd5b81-cmd age=5415 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping user=default
  10. id=6 addr=127.0.0.1:51611 fd=10 name=sentinel-14bd5b81-pubsub age=5415 idle=0 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=subscribe user=default

image.png

B.使用telnet连接redis,查看client id

  1. client id
  2. :1648

C.telnet 客户端开启订阅失效消息

  1. hello 3
  2. client tracking off
  3. +OK
  4. SUBSCRIBE __redis__:invalidate
  5. >3
  6. $9
  7. subscribe
  8. $20
  9. __redis__:invalidate
  10. :1
  11. client tracking on bcast redirect 1648
  12. +OK

D.在Redis-cli进行值更新

  1. 127.0.0.1:6380> set a 100
  2. OK

image.png

E.可以看到telnet客户端收到了失效信息

  1. >2
  2. $10
  3. invalidate
  4. *1
  5. $1
  6. a

image.png
如果要转发的目的client开启了RESP3协议,就不需要RESP3 Pub/Sub了,因为RESP3原生支持Push消息。
redis的tracking feature的实现代码在:tracking.c。