Redis6.0 Client-Side缓存是什么
前言
Redis在其6.0版本中加入了Client-side caching的支持,开启该功能后,Redis可以将指定的key-value缓存在客户端侧,这样当客户端发起请求时,如果客户端侧存在缓存,则无需请求Redis Server端。
Why Client-side Caching?
+-------------+ +----------+
| | ------- GET user:1234 -------> | |
| Application | | Database |
| | <---- username = Alice ------- | |
+-------------+ +----------+
一些场景下,Redis的一些热点数据需要高频访问,但是并不会频繁的更新,这种数据存储在Redis中,会对Redis的读有一定的压力,因此,将这种数据存储在客户端侧进行缓存,当需要读取时,直接从客户端侧的内存中读取,可以大幅度减轻Redis的读压力,当数据发生变更时,Redis Server通知Client,更新Client Cache。
+-------------+ +----------+
| | | |
| Application | ( No chat needed ) | Database |
| | | |
+-------------+ +----------+
| Local cache |
| |
| user:1234 = |
| username |
| Alice |
+-------------+
Why Not Pub/Sub?
在早期的Redis版本中,一些业务场景,我们一定也会考虑到将一些不常变化的热点数据,存储在本地内存中,使用例如Caffeine Cache等Localcache,定时周期频率读取最新的值,更新Localcache,或者使用Redis Pub/Sub,当key值发生更新时,通知整个集群更新Localcache。
使用Pub/Sub对于旧版本Redis来说,没有实现Client-side caching时,是一种解决方案,但是此种方案存在弊端,
首先Pub/Sub不可靠,如果部分集群中的Client没有收到Pub的通知,Localcache可能没有更新;
其次,对网络压力巨大,当Client Node非常多的时候,网络可能会出现阻塞,CPU压力也会增大,同时Client端需要自行实现Localcache的更新逻辑。
How to use it?
Redis Client-side Caching命令如下:
CLIENT TRACKING <ON | OFF> [REDIRECT client-id] [PREFIX prefix [PREFIX prefix ...]] [BCAST] [OPTIN] [OPTOUT] [NOLOOP]
客户端默认不开启 track 模式,我们需要在获取执行指令之前执行开启命令:
CLIENT TRACKING ON
+OK
GET foo
"bar"
默认情况下,Client开启Tracking后,Redis Server端会对所有的Client端请求查询的key开启Tracking,当 key的值发现变化时会发送失效信息给客户端 (invalidation message
)。
server -> client: Invalidate foo
默认情况下,对所有的请求查询的key开启Tracking,这显然是不合适的,更多的场景下,我们只希望追踪部分热点且不经常变化的key,Redis支持对仅对特定的key开启手动追踪:
CLIENT TRACKING ON OPTIN // 开启特定key追踪选项CLIENT CACHING YES // get请求前加入该命令
+OK
GET foo
"bar"
手动追踪模式下,需要用户在每次进行get命令之前,执行追踪的命令,这样的好处是非常的精确,但是也有点繁琐,Redis还提供了另一种追踪模式,即广播模式
CLIENT TRACKING ON BCAST PREFIX object: PREFIX user:
广播模式下,需要用户指定需要追踪的key的前缀,当key发生变化时,Redis Server端会发出广播通知全部订阅了该前缀key的客户端。
需要注意的是,在这个模式下,如果用户没有指定PREFIX
,那么服务端会给客户端广播所有 key 的失效情况,如果 key 被频繁修改,服务端会发送大量的失效广播消息,这就会消耗大量的网络带宽资源,这是非常危险的一个行为,需要特别注意。
How to implement?
上面的篇幅我们简单介绍了Redis的客户端侧缓存如何开启,本小节我们来看一下Redis是如何实现的,在展开这个问题之前,我们可以思考一下,如果我们是Redis的设计者,我们该如何实现该功能?
很简单我们会想到,搞一个Array存一下嘛,对吧O(∩_∩)O,把需要追踪的key存一下,当key收到set之类的命令后,看一下Tracking Array中有没有,如果有,通知订阅的Client。
事实上,对于手动追踪模式,Redis的确是这样实现的,Redis内部使用了Invalidation Table存储Tracking Key Data,也可以叫做Tracking Table,其内部使用LRU淘汰机制维护,当Table内的key数量达到最大值,会移除最老的记录,同时触发该记录已过期的通知给客户端。
在Invalidation Table中,Redis存储了Tracking key的指针地址与客户端之间的映射关系,使用了一种基数树(radix tree)的数据结构,因为键对象的指针就是内存地址,也就是长整型数据。客户端缓存的相关操作就是对该数据的增删改查:
对于广播模式,实现的原理也是相似的,不过Redis并不是使用Invalidation Table存储,而是使用Prefixes Table存储key的前缀值与Client之间的关系:
Problem
以上,我们简单了解了Redis的Client-side caching的使用方式与实现机制,这是一个非常好的功能,可以帮助我们更加高效的使用Redis,但是其也有对应的问题。
在Redis的官方文档中,Client-side caching功能并未提及Master/Slave 与 Cluster集群模式的特别支持,这意味着,Client端需要对key的Tracking做出特别的适配,而在Redis Cluster集群模式下,连接状态信息是分散在不同的节点上的,难以实现集中管理。
Redis的客户端Jedis、lettuce与Redisson均不提供Client-side caching相关支持,lettuce的committer在Github中关于对Client-side caching问题做出了回复:
There are a few challenges to address:
- Re-apply
CLIENT TRACKING
settings upon reconnect: While that is primary a resiliency feature, in Master/Replica or Cluster mode that is a must since we don’t get hold easily of cluster connections. We also need to apply tracking settings when creating a new connection- Topology changes: Whenever the topology changes, we need to adapt to that. Meaning also that we need to carry over tracking settings. More over, how does the migration path look like when in Redis Cluster a slot assignment gets migrated to a new node? What about the server side, does it carry over also all touched keys? I assume not so reconfiguration can cause dropped notifications since the new server is no longer aware of the key subscriptions from the old server. While this could be done (with a lot of effort) on the client side, I think that is too complex.
- Finally, I don’t have time to do that in the near future nor I see how I can do that alone in 2021.
有一些挑战需要解决:
重新连接时重新应用客户端跟踪设置:虽然这主要是一个弹性功能,但在主/复制或群集模式下,这是必须的,因为我们不容易掌握群集连接。我们还需要在创建新连接时应用跟踪设置
拓扑变化:每当拓扑结构发生变化时,我们都需要适应这种变化。这也意味着我们需要沿用跟踪设置。此外,当 Redis 集群中的插槽分配迁移到新节点时,迁移路径是怎样的?在服务器端,是否也会继承所有被触及的密钥?我认为不会,因此重新配置可能会导致通知丢失,因为新服务器不再知道旧服务器的密钥订阅。虽然这可以在客户端完成(需要付出很多努力),但我认为这太复杂了。
最后,我近期没有时间去做这件事,我也不知道 2021 年我如何能单独完成这件事。
对于我们普通开发者,希望在生产环境中使用Client-side caching,也许还需要观望后续Java Redis Client社区的支持情况。
相关文章:

Redis6.0 Client-Side缓存是什么
前言 Redis在其6.0版本中加入了Client-side caching的支持,开启该功能后,Redis可以将指定的key-value缓存在客户端侧,这样当客户端发起请求时,如果客户端侧存在缓存,则无需请求Redis Server端。 Why Client-side Cac…...

Leetcode—1572.矩阵对角线元素的和【简单】
2023每日刷题(七十三) Leetcode—1572.矩阵对角线元素的和 实现代码 class Solution { public:int diagonalSum(vector<vector<int>>& mat) {int n mat.size();if(n 1) {return mat[0][0];}int sum 0;int i 0, j n - 1;while(i &…...
基于SpringBoot的二手手机商城系统的设计与实现
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的二手手机商城系统的设计…...
OpenFeign相关面试题及答案
1、什么是OpenFeign,它如何简化远程服务调用? OpenFeign是一个声明式的Web服务客户端,它使得编写HTTP客户端变得更加容易。它属于Spring Cloud Netflix项目的一部分,可以与Spring Boot应用轻松集成。通过使用OpenFeign࿰…...

c盘扩容时,d盘无法删除卷问题
C盘扩容时,磁盘管理中D盘右键无法删除卷的原因 首先,D盘下文件夹为空,但是显示可用空间不是100%,经过排查,发现是虚拟内存设置在了D盘导致无法删除卷,这里只需要将虚拟内存放到其他盘,如E盘即可…...
NumPy 中级教程——广播(Broadcasting)
Python NumPy 中级教程:广播(Broadcasting) 在 NumPy 中,广播是一种强大的机制,它允许不同形状的数组在进行操作时,自动进行形状的调整,使得它们能够完成一致的运算。广播使得对数组的操作更加…...

python-39-flask+nginx+Gunicorn的组合应用
flask nginx Gunicorn 王炸 1 flasknginxgunicornsupervisor 1.1 myapp.py from flask import Flask app Flask(__name__)app.route("/") def test_link():return "the link is very good"if __name__"__main__":app.run()默认是5000端口…...

C#-CSC编译环境搭建
一.Microsoft .NET Framework 确保系统中安装Microsoft .NET Framework相关版本下载 .NET Framework 4.7 | 免费官方下载 (microsoft.com)https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/net47 二.编译环境搭建 已经集成编译工具csc.exe,归档至gitcode,实现us…...

【JVM】一文掌握JVM垃圾回收机制
作为Java程序员,除了业务逻辑以外,随着更深入的了解,都无法避免的会接触到JVM以及垃圾回收相关知识。JVM调优是一个听起来很可怕,实际上很简单的事。 感到可怕,是因为垃圾回收相关机制都在JVM的C++层实现,我们在Java开发中看不见摸不着;而实际很简单,是因为它说到底,也…...

【AIGC风格prompt】风格类绘画风格的提示词技巧
风格类绘画风格的提示词展示 主题:首先需要确定绘画的主题,例如动物、自然景观、人物等。 描述:根据主题提供详细的描述,包括颜色、情感、场景等。 绘画细节:描述绘画中的细节,例如表情、纹理、光影等。 场…...
vue exceljs json数据转excel
json数据转excel 有时候我们会遇到这样一个需求,就是将数据转成excel下载,这一般都是由后端来处理,使用插件poi轻松搞定。如果只有少量数据,那么能不能避免调用后端接口,前端直接处理呢? 答案是ÿ…...

Navicat for MySQL 创建函数——报错1418
解决方法 1查看是否开启了创建函数的功能 输入下面语句查看是否开启了创建函数的功能 show variables like %func%; 下面为创建函数功能为开启的查询结果 如果不是上面的结果可以用下面的语句修改为开启 set GLOBAL log_bin_trust_function_creatorstrue; //或 set GLOBAL …...

java球队信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java Web球队信息管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5…...

设计模式(4)--对象行为(7)--观察者
1. 意图 定义对象间的一种一对多的依赖关系, 当一个对象的状态改变时,所有依赖于它的对象都得到通知并被自动更新。 2. 四种角色 抽象目标(Subject)、具体目标(Concrete Subject)、抽象观察者(Observer)、 具体观察者(Concrete Observer) 3. 优点 3.1 …...

MySQL所有常见问题
一、事务 定义:一组操作要么全部成功,要么全部失败,目的是为了保证数据最终的一致性 在MySQL中,提供了一系列事务相关的命令: start transaction | begin | begin work:开启一个事务commit:提交一个事务rollback:回滚一个事务事务的ACID 原子性(Atomicity):当前事…...
锐捷交换机配置 SNMP
配置步骤 ( SNMP v2 ) 步骤一 -- 创建共同体(Community) ruijie(config)#snmp-server community test rw # rw 为读和写口令ruijie(config)#snmp-server community public ro # ro 为只读和写口令这里的共同体为“test”,通常只读口令和读写口令单独配置,提升安…...

Windows 10 安装和开启VNCServer 服务
Windows 10 安装和开启VNCServer 服务 登录云服务器 使用本地RDP登录到配置VNCServer服务的Windows10系统的云服务器。 下载VNC Server安装包 打开官网下载VNCServer安装包 URL:https://www.realvnc.com/en/connect/download/vnc/windows/ 安装VNC Server 双击…...

js遍历后端返回的集合将条件相同的放入同一个数组内
项目场景: echarts折线图需要根据条件动态展示多条不同曲线 解决方案: 后端直接将使用sql将数据查询出来返回即可,因为我这里不是Java使用的C#不是很熟练后台不好写逻辑,所以在前端js完成的 代码如下: function createline(villagename, buildingname…...

GcExcel:DsExcel 7.0 for Java Crack
GcExcel:DsExcel 7.0-高速 Java Excel 电子表格 API 库 Document Solutions for Excel(DsExcel,以前称为 GcExcel)Java 版允许您在 Java 应用程序中以编程方式创建、编辑、导入和导出 Excel 电子表格。几乎可以部署在任何地方。 创建、加载、…...
基于SpringBoot的职业生涯规划系统
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的职业生涯规划系统,java…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...