起源: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。同时还提供了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。

上面让咱们一一介绍每个选项。

测试环境搭建

首先让咱们介绍RESP3协定相干的选项,REDIRECT <id>放在最初介绍。

在尝试之前,你首先须要装置一个redis 6.x的版本,目前时6.0.1。在官方网站上有源代码的下载,编译装置也很简略:

make distcleanmakemake testsudo 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 6379Trying ::1...Connected to localhost.Escape character is '^]'.hello 3%7$6server$5redis$7version$56.0.1......

之后尝试开启tracking并读取a的值:

client tracking on+OKset a 1+OKget a$11

这个时候如果应用redis-cli作为另外一个client更新a的值,telnet这个client应该能取得告诉:

127.0.0.1:6379> set a 2OK

察看telnet,它收到了一个生效音讯:

>2$10invalidate*1$1a

留神它采纳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+OKclient tracking on prefix user bcast+OK

咱们tracking两个前缀,以a结尾的所有的key和以user结尾的所有的key,所有a结尾的所有的key和以user结尾的所有的key(包含auser)的key变动时它应该都收到音讯。

而后咱们应用redis-cli更新三个key: abcuser:32432723213feed:6532343243432:

127.0.0.1:6379> set abc 100OK127.0.0.1:6379> set user:32432723213 goodOK127.0.0.1:6379> set feed:6532343243432 abcOK

telnet client收到abcuser:32432723213的生效音讯,而不会收到feed:6532343243432的生效音讯:

>2$10invalidate*1$3abc>2$10invalidate*1$16user: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+OKget a$12

接下来咱们发送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的生效音讯。

留神: OPTINOPTOUT是针对的非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 listid=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 12127.0.0.1:6379> set a 1000OK

能够看到telnet客户端收到了生效音讯:

*3  $7  message  $20  __redis__:invalidate  *1  $1  a

如果你要转发的目标client开启了RESP3协定,你就不须要RESP3 Pub/Sub了,因为RESP3原生反对Push音讯。

redis的tracking feature的实现代码在:tracking.c。