精选文章 Redis 6.0 除了多线程,别忘了这个牛逼特性!

Redis 6.0 除了多线程,别忘了这个牛逼特性!

作者:程序猿DD_ 时间: 2020-07-25 09:31:00
程序猿DD_ 2020-07-25 09:31:00

点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

Redis 6.0 除了多线程,别忘了这个牛逼特性!1

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 放在最后介绍。

在尝试之前,你首先需要安装一个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 6.0 除了多线程,别忘了这个牛逼特性!2

启动redis-cli:Redis 6.0 除了多线程,别忘了这个牛逼特性!3

当然,我们使用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(包括auser)的key变动时它应该都收到消息。

然后我们使用redis-cli更新三个key: abcuser:32432723213feed: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收到abcuser: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的失效消息。

注意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 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。

来源 | https://urlify.cn/mYVVNf

往期推荐

JDK 14 里的调试神器了解一下?

谷歌 Java 编程风格指南

有理有据:一篇来自前端同学对后端接口的吐槽!

面试:如何决定使用 HashMap 还是 TreeMap?

扬言要干掉 RESTful API 的 GraphQL 是什么鬼?

欢迎加入我的知识星球,聊技术、说职场、侃社会。

头发很多的中年程序员DD和他的朋友们在这里期待你的到来!

加入方式:长按下方二维码噢

Redis 6.0 除了多线程,别忘了这个牛逼特性!4

最近更新:

周三技术人分享:为什么架构师大多是后端?

周六社会人分享:民法典:聊聊那些跟房子相关的东西

我的星球是否适合你?

点击阅读原文看看我们都聊过啥?

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

您可能感兴趣

  • 渗透测试 QA 收集

    目录 1、拿到一个待检测的站,你觉得应该先做什么? 2、判断出网站的CMS对渗透有什么意义? 3.一个成熟并且相对安全的CMS,渗透时扫目录的意义? 4.常见的网站服务器容器。 5.mysql注入点,用工具对目标站直接写入一句话,需要哪些条件? 6.目前已知哪些版本的容器有解析漏洞,具体举例。 7.如何手工快速判断目标站是windows还是linux服务器? 8.为何一个mysql数据库的站...

  • 广告行业中那些趣事系列9:一网打尽Youtube深度学习推荐系统

    最新最全的文章请关注我的微信公众号:数据拾光者。 摘要:本篇主要分析Youtube深度学习推荐系统,借鉴模型框架以及工程中优秀的解决方案从而应用于实际项目。首先讲了下用户、广告主和抖音这一类视频平台三者之间的关系:就是平台将视频资源作为商品免费卖给用户,同时将用户作为商品有偿卖给广告主,仅此而已。平台想获取更高的收益就必须提升广告的转化效率,而前提是吸引用户增加观看视频的时长,这里就涉及到视...

  • 大数据架构师从入门到精通 学习必看宝典

    经常有初学者在博客和QQ问我,自己想往大数据方向发展,该学哪些技术,学习路线是什么样的,觉得大数据很火,就业很好,薪资很高。如果自己很迷茫,为了这些原因想往大数据方向发展,也可以,那么我就想问一下,你的专业是什么,对于计算机/软件,你的兴趣是什么?是计算机专业,对操作系统、硬件、网络、服务器感兴趣?是软件专业,对软件开发、编程、写代码感兴趣?还是数学、统计学专业,对数据和数字特别感兴趣。 6...

  • 面试刷题11-15

    【用友】一面(8.22)(电话)复盘(24min) 自我介绍 当前在校情况 项目情况 设计模式 IO相关 socket、tomcat、Netty、dubbo MySQl 引擎之间的区别,索引原理 redis缓存 ES 搜索引擎 性能监控的日志 线程安全 AOP 泛型 作用、原理 【用友】HR面(8.27)(视频)复盘(17min) 自我介绍 项目情况 职业规划 经受过最大的挫折,怎么克服的 ...

  • 献给那些浮躁的年轻人

    本文转载自https://blog.csdn.net/gneveek/article/details/8690657 年龄,那是一种对时间的焦虑。张爱玲一句“出名要趁早”,害了不知多少人。人是靠价值相互认同的,而不是年龄;一个人要知道自己想要什么,才能做成事情。别着急,你还年轻,喜欢的事情大可以努力去做,没有钱途也没关系。毕竟,你还年轻啊! 【1】上周在南京出差,深夜拖着疲惫去跟朋友见面,畅...

  • 面试字节跳动,被怼的体无完肤!

    点击上方“阿拉奇学Java”,选择“置顶或者星标” 优质文章第一时间送达! 知乎三级狗 | 作者:三级狗 |http://mrw.so/56CkE0 人们都说,这个世界上有两种人注定单身,一种是太优秀的,另一种是太平凡的。 我一听呀?那我这岂不是就不优秀了吗,于是毅然决然和女朋友分了手。 人们都说,互联网寒冬来了,这个时候还在大面积招人的公司,必然是牛逼的公司。而这个时候勇敢跳槽的人,必然是...

  • 一位资深大牛给予java初学者的建议

    Java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是你是如何学习Java的,能不能给点建议?今天我是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容甚至是一些书籍。这一部分的内容,同样适用于一些希望转行到Java的同学。   在大家看之前,我要先声明两点。1、由于我本人是Java后端开发出身,因此所推荐的学习内容是Java...

  • 秒杀策略总结

    一般商家在做活动的时候,经常会遇到各种不怀好意的DDOS攻击(利用无辜的吃瓜群众夺取资源),导致真正的我们无法获得服务!所以说高防IP还是很有必要的。 搞活动就意味着人多,接入SLB,对多台云服务器进行流量分发,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 基于SLB价格以及灵活性考虑后面我们接入Nginx做限流分发,来保障后端服务的正常运行。 后端秒杀...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。