开场留言不要吝啬你的赞美。如果有人做得好,给他积极的反馈,这也是一种利他主义。此外,少关注投票为“表扬”的事情,多关注投票为“交易”的事情。判断一个人牛不牛逼,不是有多少人在网上夸他,而是有多少人愿意和他交易、欣赏、支付、下单。因为夸奖太便宜了,愿意和他交易才是真正的信任。为什么需要客户端缓存Redis的TrackingFeature?实现代码在:https://github.com/antirez/redis/blob/unstable/src/tracking.c。很多公司使用Redis作为缓存系统,大大提高了数据访问的性能。为了进一步处理热点数据,Redis客户端会缓存一些热点数据,以应对“吃瓜事件”。比如《这该死的996祝福》、《吴亦凡慷慨入狱》、《时间管理大师》、《思聪不能舔我就打我》、《吴秀波的爱情,可以进监狱的那种》。..除了使用Redis缓存避免直接访问数据库外,还会增加更多的缓存层,比如使用Memcachced作为热点数据的本地缓存:首先在Memcachced中查询数据,命中则直接返回。如果Memcachced未命中,它会再次从Redis中查询,如果命中,它会返回数据并将这些数据保存在Memcachced中。如果Redis未命中,则去MySQL中查询,依次在Redis和Memcachced中设置。访问本地内存的性能势必会比通过网络访问Redis更快,所以这种模式可以大大降低获取数据的延迟,可以减轻Redis的负载,提高性能。访问Redis获取数据,服务器响应。查询Redis使用客户端缓存,应用程序将获取的热门数据存储在应用程序中,无需再次通过网络访问Redis。应该缓存什么我们不应该缓存不断变化的键。我们不应该缓存很少请求的键。我们希望缓存频繁请求并以合理的速率更改的键。对于没有稳定变化率的例子,比如一个不断被INCR修改的全局计数器,它不应该被缓存。客户端缓存实现原理客户端缓存实现原理代码又老又湿,Redis中的数据被修改或失效。如何及时同步通知客户端失效?自己实现太复杂了。Redis实现了一个称为跟踪的服务器辅助客户端缓存。客户端缓存的命令为:CLIENTTRACKINGON|OFF[REDIRECTclient-id][PREFIXprefix][BCAST][OPTIN][OPTOUT][NOLOOP]Redis6.0实现了Tracking功能,提供了两种模式来解决这个问题,使用RESP3协议version普通模式和广播模式,转发模式使用RESP2协议版本。在正常模式下,启用跟踪后,Redis会“记住”每个客户端请求的键,并在键的值发生变化时向客户端发送失效消息(invalidationmessage)。失效信息可以通过RESP3协议发送给发出请求的客户端,或者转发给不同连接上的客户端(支持RESP2+Pub/Sub)。服务器端将客户端访问的key和key对应的clientID列表信息保存在一个全局唯一的表(TrackingTable)中。当表已满时,它将删除最旧的记录并触发通知客户端该记录已过期结束。每个Redis客户端都有一个唯一的数字ID。TrackingTable存储每个ClientID。当连接断开时,该ID对应的记录被清除。TrackingTable表中记录的Key信息不考虑属于哪个数据库。虽然访问了db1的key,但是当db2中的同名key被修改时,客户端会收到过期提示,但是这样会降低系统的复杂度和表数量的存储数据。代码又老又湿,能说说TrackingTable的原理吗?Redis服务器使用TrackingTable在普通模式下存储客户端数据。它的数据类型是基数树(radixtree)。基数树是一种用于稀疏长整数数据搜索的多叉搜索树,可以快速完成映射,节省空间。Redis使用它来存储键指针和客户端ID之间的映射。因为key对象的指针是内存地址,也就是长整型数据。clientcache的相关操作是对数据进行增删改查:图片来源-程序员李小兵注意服务端只会对记录的key上报invalidatemessage,即服务端发送了invalidatemessage给客户端一次之后,如果再次修改key,服务器不会再向客户端发送invalidate报文。只有下次客户端再次执行只读命令并被跟踪时,才会发送下一条消息通知。客户端默认不开启跟踪模式。获取执行命令前我们需要先执行enable命令:CLIENTTRACKINGON|OFF+OKGETuser:211$3公众号:码哥字节广播模式(BCAST)当广播模式(broadcasting)开启后,服务器没有记忆给定客户端访问了哪些密钥,因此此模式在服务器端根本不消耗内存。在这种模式下,服务器会将所有密钥的失效广播给客户端。如果频繁修改密钥,服务器会发送大量的失效广播报文,消耗大量的网络带宽资源。因此,在实际应用中,我们设置客户端进行注册,只跟踪指定前缀的key。当注册跟踪的键前缀匹配被修改时,服务器将向所有与该键前缀相关的客户端广播失效消息。clienttrackingonbcastprefixuser,一种监听带前缀键的广播模式,非常符合我们对键的命名约定。在实际应用中,我们会为同一个服务下的key设置相同的服务名前缀,这样我们就可以很方便的使用广播方式。图片来源-程序员李小兵直播模式与普通模式类似。Redis使用PrefixTable以广播方式存储客户端数据,它存储了**prefixstringpointer和(要通知的key和clientID)**的映射关系。转发模式,普通模式和广播模式,需要客户端使用RESP3协议,RESP3协议是Redis6.0新启用的协议。对于使用RESP2协议的客户端,需要另一种模式来实现客户端缓存:重定向模式(redirect)。RESP2不能直接PUSH失效消息,所以需要另外一个支持RESP3协议的客户端告诉服务器通过Pus/Sub通知RESP2客户端失效消息。在重定向模式下,想要收到失效消息通知的客户端需要执行订阅命令SUBSCRIBE专门订阅通道_redis_:invalidate来发送失效消息。同时,使用另一个客户端,执行CLIENTTRACKING命令,设置服务器使用RESP2协议将失效报文转发给客户端。图片来源——程序员李小兵假设客户端B想要获取失效消息,但是客户端B只支持RESP2协议,客户端A支持RESP3协议。我们可以分别在客户端B和A上执行SUBSCRIBE和CLIENTTRACKING,如下://客户端B执行,客户端B的ID号为606SUBSCRIBE_redis_:invalidate//客户端A执行CLIENTTRACKINGONBCASTREDIRECT606B客户端可以通过_redis_:invalidate通道已收到无效消息。本文转载自微信公众号“代码字节”,可通过以下二维码关注。转载本文请联系码哥字节公众号。
