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)的数据结构,因为键对象的指针就是内存地址,也就是长整型数据。客户端缓存的相关操作就是对该数据的增删改查:

tracking table

对于广播模式,实现的原理也是相似的,不过Redis并不是使用Invalidation Table存储,而是使用Prefixes Table存储key的前缀值与Client之间的关系:

Prefix Tracking Table

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:

  1. 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
  2. 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.
  3. 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社区的支持情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/581729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【每日一题】【12.24】 - 【12.28】

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 本周总结&#xff1a;本周的每日一题比较针对于数学问题的一个应用&#xff0c;如二元一次方程组的求解或者数组求和&#xff0c;同…

IDEA、VSCode等快速连接Github(Mac版)

问题描述 在本地书写✍️完代码后, 想要git push到Github上面, 出现延迟错误; 导致经常push不上去, 如下图所示; 解决方案 进入电脑终端; 输入下列命令; sudo vim /etc/hosts输入密码; 按下 I 键, 进行编辑操作; 将下列语句复制到空白区, 然后按下esc按键, 然后输入:wq即可…

矿泉水硝酸盐和溴酸盐超标解决工艺

在当今社会&#xff0c;人们对健康和优质生活的追求不断提升&#xff0c;使得瓶装饮用水的安全问题受到了广泛关注。溴酸盐和硝酸盐作为自然水体中常见的物质&#xff0c;若在矿泉水中含量过高&#xff0c;可能会对消费者的健康构成潜在威胁。因此&#xff0c;探究有效去除矿泉…

AR-HUD厂商发力下一代技术方案,vHOE为何赢得高度关注?

作为智能座舱的核心显示交互系统&#xff0c;AR-HUD正处于处于量产爆发前期&#xff0c;同时关于下一代技术方案的比拼也在全面升级。 根据《高工智能汽车研究院》数据显示&#xff0c;2023年1-9月&#xff0c;中国市场&#xff08;不含进出口&#xff09;乘用车前装标配W/AR …

双向链表基本操作及顺序和链表总结

目录 基本函数实现 链表声明 总的函数实现声明 创建一个节点 初始化链表 打印 尾插 尾删 头插 头删 查找 pos前插入 删除pos位置 销毁链表 顺序表和链表总结 基本函数实现 链表声明 typedef int DLTDataType;typedef struct DListNode {struct DListNode* nex…

POLL机制

文章目录 一、POLL机制1、应用场景2、执行流程 二、程序1、驱动程序2、测试应用程序 三、总结 一、POLL机制 1、应用场景 使用休眠-唤醒的方式等待某个事件发生时&#xff0c;有一个缺点&#xff1a;等待的时间可能很久。我们可以加上一个超时时间&#xff0c;这时就可以使用…

百度CTO王海峰:文心一言用户规模破1亿

▶ 写在前面▶ 飞桨开发者已达1070万▶ 文心一言用户规模破亿&#xff0c;日提问量快速增长 ▶ 写在前面 “文心一言用户规模突破 1 亿。”12 月 28日&#xff0c;百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰在第十届 WAVE SUMMIT 深度学习开发者大会上宣布…

Python初学者必须吃透的69个内置函数!

所谓内置函数&#xff0c;就是Python提供的, 可以直接拿来直接用的函数&#xff0c;比如大家熟悉的print&#xff0c;range、input等&#xff0c;也有不是很熟&#xff0c;但是很重要的&#xff0c;如enumerate、zip、join等&#xff0c;Python内置的这些函数非常精巧且强大的&…

外贸网站建站怎么做?海洋建站有哪些步骤?

外贸网站建站需要哪些资料&#xff1f;如何选择外贸建站系统&#xff1f; 外贸企业越来越重视在线业务&#xff0c;而拥有一个专业、高效的外贸网站已经成为成功开展国际贸易的关键一步。海洋建站将为您详细介绍如何进行外贸网站建站&#xff0c;让您的企业在全球市场中脱颖而…

C++ Qt开发:QItemDelegate自定义代理组件

老规矩&#xff0c;首先推荐好书&#xff1a; Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍…

浏览器Post请求出现413 Request Entity Too Large (Nginx)

环境 操作系统 window server 2016 前端项目 Vue2 Nginx-1.25.3 一、错误信息 前端是vue项目&#xff0c;打包后部署在Nginx上&#xff0c;前端post请求出现Request Entity Too Large错误信息。 ​这种问题一般是请求实体太大&#xff08;包含参数&#xff0c;文件等&#xf…

C语言-第十七周课堂总结-数组

找出矩阵中最大值所在的位置 程序解析-求矩阵的最大值 源程序段 二维数组 多维数组的空间想象 一维数组&#xff1a;一列长表或一个向量二维数组&#xff1a;一个表格或一个平面矩阵三维数组&#xff1a;三位空间的一个方阵多维数组&#xff1a;多维空间的一个数据矩阵 …

2019年全国学校POI数据

2019年全国学校POI数据 POI&#xff08;一般作为Point of Interest的缩写&#xff0c;也有Point of Information的说法&#xff09;&#xff0c;通常称作兴趣点&#xff0c;泛指互联网电子地图中的点类数据&#xff0c;基本包含名称、地址、坐标、类别四个属性&#xff1b;在GI…

如何利用树莓派与Nginx结合cpolar内网穿透工具实现公网访问内网web网站

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

QML —— ProgressBar示例(附完整源码)

示例 - 效果 实例 - 源码 import QtQuick 2.12 import QtQuick.Window 2.12import QtQuick.Layouts 1.12 import QtQuick.Controls 2.5Window {id: rootIdvisible: truewidth: 640height: 480title: qsTr("Hello World")Column{spacing: 40anchors.centerIn: parent…

车路协同中 CUDA 鱼眼相机矫正、检测、追踪

在车路协同中,鱼眼一般用来补充杆件下方的盲区,需要实现目标检测、追踪、定位。在目标追踪任务中,通常的球机或者枪机方案,无法避免人群遮挡的问题,从而导致较高的ID Swich,造成追踪不稳定。但是鱼眼相机的顶视角安装方式,天然缓解了遮挡的问题,从而实现杆件下方的盲区…

携手共进 探索生命|清华大学创融同学会走进生命系 共话细胞科技新未来

携手共进 探索生命&#xff5c;清华大学创融同学会走进生命系 共话细胞科技新未来 探索细胞产业新高度&#xff0c;赋予生命健康更多保障&#xff01;日前&#xff0c;清华大学创融同学会一行莅临全生命周期健康管理中心——生命系参观交流。生命系领导以及全体员工对来访贵宾…

【10】ES6:Promise 对象

一、同步和异步 1、JS 是单线程语言 JavaScript 是一门单线程的语言&#xff0c;因此同一个时间只能做一件事情&#xff0c;这意味着所有任务都需要排队&#xff0c;前一个任务执行完&#xff0c;才会执行下一个任务。但是&#xff0c;如果前一个任务的执行时间很长&#xff…

Python3 基本数据类型

Python 中的变量不需要声明。每个变量在使用前都必须赋值&#xff0c;变量赋值以后该变量才会被创建。 在 Python 中&#xff0c;变量就是变量&#xff0c;它没有类型&#xff0c;我们所说的"类型"是变量所指的内存中对象的类型。 等号&#xff08;&#xff09;用来…

关于时间与空间复杂度的学习

关于时间与空间复杂度的学习 算法时间复杂度定义标准算法度量单位渐近记号1、Θ&#xff08;big-theta&#xff09;2、O&#xff08;big-oh&#xff09;3、Ω&#xff08;big-omege&#xff09; 推导时间复杂度步骤与法则步骤法则 示例1.常数阶2、线性阶3、对数阶4、平方阶5、立…