起源:urlify.cn/mYVVNf
Redis 6.0 的新个性也是在一步步的探讨和优化中确定的。很多的个性曾经在之前的 RC 等版本中介绍过了。然而正式 GA 版中也有一些新的变动:
- 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)
@antirez 提到只是 Redis 历史上最大的一次版本更新,所以审慎倡议在利用的产品中还是多多测试评估,并且承诺一旦遇到大的 bug 就会紧急公布 6.0.1 版。果不其然,一天后就公布了 6.0.1 版,修复了一个 allocator 的 bug,这个 bug 是为了优化而引入的,当初临时去掉了。
I just released Redis 6.0.1. Unfortunately there was a bug in Redis 6.0.0 introduced just a few days before the release, that only happens when using the non-default allocator (libc malloc in this case triggers it). Optimization reverted, 6.0.1 released. Sorry for the issue.
本文次要关注 Client side caching(客户端缓存) 这一个性。
smallnest/RESP3 是 Redis RESP3 协定的解析库,你能够应用它和 Redis 底层通信,或者包装它实现新版的 Redis client 库或者 Redis Server 端。
一年前,当 @antirez 加入完纽约 Redis 大会后,5:30 就在旅店中醒来了,面对曼哈顿街头的漂亮风景,在芸芸众生中考虑 Redis 的将来。包含客户端缓存。
其实,客户端缓存个性是收到 Redis Conf 2018 的 Ben Malec 的影响,一下子关上了 @antirez 思路。咱们晓得,很多公司应用 Redis 做缓存零碎,并且很好的进步了数据拜访的性能,然而很多企业为了进一步应答热点数据,还是会在 redis 的 client 端缓存一部分热点数据,用来应答吃瓜事件。比方在微博咱们常常遇到的是明星出轨、明星分分合合、突发事件等等,每年都会有几次突发的事件,微博除了应用 Redis 做缓存防止间接拜访数据库,还会在后面加更多的 cache 层,比方 L1 cache
等,采纳 memcached 等产品作为热数据的缓存。那么就有一个问题,如何可能及时的同步这些 cache 和 redis 的数据呢?Ben 提供了十分有意思的想法。
伫立在曼哈顿的街头,@antirez 陷入了深思,起初回到旅馆他开始实现初版的客户端的缓存。当然,最终 Redis 6.0 中实现和这个初版的实现差异很大,然而很是显然,从客户端的演化过程中咱们还是能看到 @antirez 对这个个性所在的衡量(trade off)。对于这个历史本文不做太多的介绍,因为咱们更关注于这个个性最终是什么样子的。
Redis 实现的是一个服务端帮助的客户端缓存,叫做tracking
。客户端缓存的命令是:
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。同时还提供了 OPTIN
、OPTOUT
等模式。
生效音讯:当一个 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。
上面让咱们一一介绍每个选项。
测试环境搭建
首先让咱们介绍 RESP3 协定相干的选项,REDIRECT <id>
放在最初介绍。
在尝试之前,你首先须要装置一个 redis 6.x 的版本,目前时 6.0.1。在官方网站上有源代码的下载,编译装置也很简略:
make distclean
make
make test
sudo make install
置信很快就有编译好的二进制包能够下载。
启动 server, 它会在 6379 端口启动一个服务:
redis-server
应用 redis-cli
拜访, 默认拜访本机的 6379 实例:
redis-cli
当然你能够通过 -h
查看额定的参数配置,比方应用其它端口等等,这里咱们应用最简略的例子,重点是理解客户端缓存的个性。
有时候为了更好的察看 redis 的返回后果,咱们应用 telnet
而不是 redis-cli
作为 client 连贯 redis,因为 redis-cli 对后果做了解决,尤其是生效音讯,你可能无奈观测到。
BCAST 播送模式 (client tracking on
)
启动 redis server:
启动 redis-cli:
当然,咱们应用 telnet 来测试,不便察看 redis 的返回后果,方才 redis-cli 用来更新 key 值,辅助测试。连贯上之后发送 hello 3
开启 RESP3 协定:
➜ ~ telnet localhost 6379
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello 3
%7
$6
server
$5
redis
$7
version
$5
6.0.1
......
之后尝试开启 tracking
并读取 a
的值:
client tracking on
+OK
set a 1
+OK
get a
$1
1
这个时候如果应用 redis-cli 作为另外一个 client 更新 a
的值,telnet 这个 client 应该能取得告诉:
127.0.0.1:6379> set a 2
OK
察看 telnet,它收到了一个生效音讯:
>2
$10
invalidate
*1
$1
a
留神它采纳 RESP3 中的 PUSH 类型(>
)。
如果这个应用你再应用 redis-cli 更新 a
的值,telnet 不会再收到生效音讯。除非 telnet client 再 get a
一次,从新tracking
a 的值。
能够随时勾销tracking
:
client tracking off
tracking 特定前缀的 key (client tracking on
)
下面的形式会 tracking 所有的 key,如果你只想跟踪特定的 key, 目前 redis 提供了一种形式,也就是前缀匹配的形式。你能够只 tracking 特定前缀的 key。它值利用了播送模式。
应用 telnet client 设定前缀和开启 tracking:
hello 3.......
client tracking on prefix a bcast
+OK
client tracking on prefix user bcast
+OK
咱们 tracking 两个前缀,以 a
结尾的所有的 key 和以 user
结尾的所有的 key, 所有 a
结尾的所有的 key 和以 user
结尾的所有的 key(包含 a
和user
)的 key 变动时它应该都收到音讯。
而后咱们应用 redis-cli 更新三个 key: abc
、user:32432723213
和feed:6532343243432
:
127.0.0.1:6379> set abc 100
OK
127.0.0.1:6379> set user:32432723213 good
OK
127.0.0.1:6379> set feed:6532343243432 abc
OK
telnet client 收到 abc
和user:32432723213
的生效音讯, 而不会收到 feed:6532343243432
的生效音讯:
>2
$10
invalidate
*1
$3
abc>2
$10
invalidate
*1
$16
user:32432723213
你能够通过 client tracking off
进行客户端缓存。目前貌似不能只进行对单个的前缀的 tracking
。即便你应用client tracking off prefix user
也是勾销对所有的 key 的tracking
。
......
} else if (!strcasecmp(c->argv[2]->ptr,"off")) {disableTracking(c);
} else {......
抉择退出
如果应用 OPTIN
, 能够有抉择的开启tracking
。只有你发送client caching yes
之后的下一条的只读命令的 key 才会 tracking
, 否则 其它的只读命令中的 key 不会 tracking。
首先咱们开始 optin
,读取 a 的指,这个时候应用 redis-cli client 批改 a 的值为 1000,咱们并没有收到a
的生效音讯。
client tracking on optin
+OK
get a
$1
2
接下来咱们发送client caching yes
,紧接着获取 a 的值,这个时候如果再批改 a 的值,你就能够收到一条 a 的生效音讯:
client caching yes
+OK
get a
$4
1000
>2
$10
invalidate
*1
$1
a
必须是紧跟着 client caching yes
吗? 是的,比方发送上面的命令,只会tracking
b, 而不是 a:
client caching yes
+OK
get b
_
get a
$4
2000
抉择退出
如果应用 OPTOUT
, 你也能够有抉择的退出tracking
。只有你发送client caching off
之后的下一条的只读命令的 key 才会进行 tracking
, 否则 其它的只读命令中的 key 都会被 tracking。
能够看到它和 OPTIN
正好相同,你能够依据你的场景来抉择。
比方上面的例子,开启 OPTOUT
之后,对任意的 key 的变动都收到生效音讯:
client tracking on optout
+OK
get a
$4
3000
>2
$10
invalidate
*1
$1
a
这个时候如果咱们想排除 b
这个 key,能够只针对它进行设置:
client caching no
+OK
get b
$1
3
之后对 b 的变动并不会收到 b 的生效音讯。
留神 : OPTIN
和OPTOUT
是针对的非 BCAST 场景,也就是只有你发送了 key 的只读命令后,才会跟踪相应的 key。而播送模式是无论你是否发送过 key 的只读命令,只有 redis 批改了 key,都会发送相应 key(或者匹配前缀的 key)的生效音讯。
NOLOOP
失常设置时,生效音讯是发给所有参加的 client,然而如果设置了NOLOOP
, 则不会发送给更新这个 key 的 client。
client tracking on bcast noloop
+OK
set a 1
+OK
client tracking off
+OK
client tracking on bcast
+OK
set a 1
+OK
>2
$10
invalidate
*1
$1
a
留神,勾销 tracking 只需调用 client tracking off
即可。
REDIRECT
最初,让咱们看一下转发音讯的解决。这是为了兼容 RESP2 协定一个解决形式,将生效音讯转发给另外一个 client。
首先咱们查看 redis-cli 的 client id:
127.0.0.1:6379> client list
id=4 addr=127.0.0.1:61017 fd=8 name= age=33103 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
应用 telnet 连贯 redis, 查看 client id:
client id
:12
telnet 客户端开启订阅生效音讯:
SUBSCRIBE __redis__:invalidate
*3
$9
subscribe
$20
__redis__:invalidate
:1
而后咱们就能够将 redis-cli 的生效音讯转发给 telnet client:
client tracking on bcast redirect 12
127.0.0.1:6379> set a 1000
OK
能够看到 telnet 客户端收到了生效音讯:
*3
$7
message
$20
__redis__:invalidate
*1
$1
a
如果你要转发的目标 client 开启了 RESP3 协定,你就不须要 RESP3 Pub/Sub 了,因为 RESP3 原生反对 Push 音讯。
redis 的 tracking feature 的实现代码在:tracking.c。