Redis批量获取缓存的方法

使用multiGet方法

优点:简单易用,适用于获取少量键的场景。

缺点:当获取的键数量较多时,可能会因为网络延迟导致性能下降。此外,如果某个键不存在,对应的返回值会是null,需要额外处理。

其他说明:

multiGet方法适合处理的键的数量并没有一个严格的限制,但是它的性能会随着键的数量增加而逐渐下降。这是因为multiGet方法会将所有的键在一次请求中发送到Redis服务器,如果键的数量非常多,可能会导致以下几个问题:

  1. 网络延迟:如果键的数量很多,那么构建请求和接收响应所需的时间会增加,这可能导致网络延迟成为性能瓶颈。
  2. 响应体大小:如果这些键对应的值都比较大,那么一次multiGet请求的响应体可能会非常大,这不仅会占用大量的网络带宽,还可能对客户端和服务器的内存造成压力。
  3. Redis服务器压力:如果大量的multiGet请求同时发送到Redis服务器,尤其是在键的数量很多的情况下,可能会对服务器造成较大的压力,影响其他操作的性能。
  4. 超时风险:在高负载或者网络条件不佳的情况下,大量的键可能会导致multiGet请求超时。

在实践中,如果需要获取的键的数量在几十个到几百个,通常使用multiGet方法不会出现性能问题。但是,如果键的数量达到几千个或者更多,可能就需要考虑其他策略,比如:

  1. 分批获取:将大量的键分成多个批次,每批次使用multiGet获取一部分键的值。
  2. 使用scan命令:对于需要匹配模式的大量键,使用scan命令进行迭代获取。
  3. 使用管道:对于写入操作,可以使用管道(pipeline)来减少网络往返次数,提高效率。

总的来说,是否使用multiGet方法以及适合处理多少键,需要根据实际的应用场景和性能测试来决定。在不确定的情况下,建议进行性能测试,以确定在特定的环境下最佳的操作方式。

/*** 测试StringRedisTemplate.opsForValue().multiGet方法* * @author 付聪* @time 2024-10-11 15:36:26*/
@Test
public void testMultiGet() {List<String> keys = Arrays.asList("test-multiGet:key1", "test-multiGet:key2", "test-multiGet:key3");Integer i = 1;for (String key : keys) {stringRedisTemplate.opsForValue().set(key, "test-multiGet:value" + i++, 1, TimeUnit.HOURS);}List<String> values = stringRedisTemplate.opsForValue().multiGet(keys);PrintUtil.println(StrUtil.format("values:{}", values));
}

使用executePipelined方法

优点:可以显著减少网络往返次数,提高批量操作的性能。适用于执行大量独立的写入或读取操作。

缺点:编程模型相对复杂,需要手动管理命令的发送和结果的收集。此外,如果操作非常频繁,可能会对Redis服务器造成压力。

/*** 测试StringRedisTemplate.executePipelined方法** @author 付聪* @time 2024-10-11 15:36:26*/
@Test
public void testExecutePipelined() {List<String> keys = Arrays.asList("test-executePipelined:key1", "test-executePipelined:key2", "test-executePipelined:key3");Integer i = 1;for (String key : keys) {stringRedisTemplate.opsForValue().set(key, "test-executePipelined:value" + i++, 1, TimeUnit.HOURS);}/**** 该函数使用stringRedisTemplate执行管道操作,批量获取多个键对应的值。具体步骤如下:* 使用executePipelined方法执行管道操作。* 定义一个RedisCallback匿名类,重写doInRedis方法。* RedisCallback#doInRedis是Spring Data Redis中的一个接口方法,其作用是在Redis连接上执行自定义的Redis操作。具体来说:* 参数:RedisConnection connection,表示当前的Redis连接。* 返回值:可以是任意类型,通常用于返回操作的结果。* 用途:* 提供对底层Redis连接的直接访问,允许执行更复杂的或自定义的Redis命令。* 可以在事务或管道中使用,提高性能和效率。* 通过实现doInRedis方法,开发者可以在Redis连接上执行任意的Redis命令,从而实现更灵活的Redis操作。* 在doInRedis方法中,遍历keys列表,对每个键调用connection.get(key.getBytes())获取其值。* 返回null,因为doInRedis方法的返回值不会影响最终结果。* executePipelined方法返回一个包含所有获取到的值的列表values。**/List<Object> values = stringRedisTemplate.executePipelined(new RedisCallback<String>() {@Overridepublic String doInRedis(RedisConnection connection) throws DataAccessException {for (String key : keys) {connection.get(key.getBytes());}// 返回null,因为结果已经通过executePipelined返回。return null;}});PrintUtil.println(StrUtil.format("values:{}", values));
}

使用管道可以减少网络延迟,提高Redis的操作效率。但是,需要注意的是,管道中的命令不能包含事务性的命令,如MULTIEXEC,否则会抛出异常 。

使用scan方法

优点:可以迭代地获取匹配特定模式的键,适用于需要匹配大量键的场景,且不会阻塞Redis服务器。

缺点scan命令返回的是游标,需要多次迭代才能获取所有匹配的键,且每次迭代返回的键数量有限,可能需要多次迭代才能获取全部数据。此外,scan命令在处理大量数据时效率较低。

/*** 测试scan方法** @author 付聪* @time 2024-10-18 10:09:38*/
@Test
public void testScan() {List<String> keys = Arrays.asList("test-scan:key1", "test-scan:key2", "test-scan:key3");Integer i = 1;for (String key : keys) {stringRedisTemplate.opsForValue().set(key, "test-scan:value" + i++, 1, TimeUnit.HOURS);}/**** 该函数通过stringRedisTemplate执行一个Redis操作,具体功能如下:* (RedisCallback<Set<String>>) 是一个类型转换操作,作用如下:* 将lambda表达式转换为RedisCallback<Set<String>>类型。* RedisCallback是Spring Data Redis提供的一个接口,用于执行自定义的Redis操作。* 通过这个转换,可以将lambda表达式传递给stringRedisTemplate.execute方法,从而在Redis连接上下文中执行自定义的逻辑。* 使用connection.scan方法扫描Redis中匹配模式test-scan:*的所有键。* count(100) 的作用是:* 设置每次扫描操作返回的最大元素数量为100。* 这个参数可以控制每次scan操作返回的键的数量,减少单次操作的数据量,提高性能和响应速度。* 如果不设置count,默认值通常为10。设置为100可以在一次扫描中返回更多的键,减少总的扫描次数。* 将扫描结果中的每个键转换为字符串并添加到result集合中。* 最终返回包含所有匹配键的字符串集合。**/Set<String> values = stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {Set<String> result = new HashSet<>();Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match("test-scan:*").count(100).build());while (cursor.hasNext()) {result.add(new String(cursor.next()));}return result;});PrintUtil.println(StrUtil.format("values:{}", values));
}

使用scan方法可以避免keys命令可能带来的性能问题,但是需要注意调节count的值,避免产生和keys命令类似的效果,可能会阻塞Redis 。

总结

每种方法都有其适用场景,可以根据实际需求和性能测试结果选择最合适的方法。

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

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

相关文章

k8s部署使用有状态服务statefulset部署eureka集群,需登录认证

一、构建eureka集群镜像 1、编写dockerfile文件&#xff0c;此处基础镜像为arm版本&#xff0c;eureka目录中文件内容&#xff1a;application-dev.yml、Dockerfile、eureka-server-1.0-SNAPSHOT.jar(添加登录认证模块&#xff0c;文章最后附上下载连接) FROM mdsol/java8-j…

Vue入门示例

今天滴学习目标&#xff01;&#xff01;&#xff01; 示例简介HTML内容主体区域输入框列表区域统计和清空 JS引入Vue.js库定义Vue实例el选项data选项methods选项 示例简介 HTML内容 本次实例讲解的是v-for、v-on、v-model来写这小小的实例&#xff0c;下面是实例的效果图&am…

OQE-OPTICAL AND QUANTUM ELECTRONICS

文章目录 一、征稿简介二、重要信息三、服务简述四、投稿须知五、联系咨询 一、征稿简介 二、重要信息 期刊官网&#xff1a;https://ais.cn/u/3eEJNv 三、服务简述 四、投稿须知 1.在线投稿&#xff1a;由艾思科蓝支持在线投稿&#xff0c;请将文章全文投稿至艾思科蓝投稿系…

国家能源集团携手海康威视研发攻克融合光谱煤质快检技术

10月24日&#xff0c;在国家能源集团准能集团黑岱沟露天煤矿&#xff0c;安装于准能选煤厂785商品煤胶带机中部的煤质快检核心设备&#xff0c;正在对当天装车外运的商品煤煤质进行实时检测。仅两分钟后&#xff0c;涵盖发热量、水分、灰分、硫分等多项指标的数据信息已传输到到…

在xml 中 不等式 做转义处理的问题

对于这种要做转义处理&#xff0c;<![CDATA[ < ]]>

LeetCode_509. 斐波那契数_java

1、题目 509. 斐波那契数https://leetcode.cn/problems/fibonacci-number/ 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#…

Discuz 论坛开发一套传奇发布站与传奇开服表

Discuz 论坛开发一套传奇发布站与传奇开服表 随着互联网技术的飞速发展&#xff0c;网络游戏已成为人们休闲娱乐的重要方式之一。在众多网络游戏中&#xff0c;传奇系列以其独特的魅力吸引了大量忠实玩家。为了满足这些玩家的需求&#xff0c;并促进游戏信息的交流与分享&…

密码学原理

1.1 加密算法 Tags: 1、加密算法分类 2、对称算法 <原理、特征、算法> 3、非对称算法 <原理、特征、算法> 4、对称算法vs非对称算法 <结合体> 1、加密算法概述&#xff1a; 用于对用户数据进行加密&#xff0c;常用算法有DES、3DES、AES、RSA、DH算法。根据密…

合约门合同全生命周期管理系统:企业合同管理的数字化转型之道

合约门合同全生命周期管理系统&#xff1a;企业合同管理的数字化转型之道 1. 引言 在现代企业中&#xff0c;合同管理已经不再是简单的文件存储和审批流程&#xff0c;而是企业合规性、风险管理和业务流程的关键环节之一。随着企业规模的扩大和合同数量的增加&#xff0c;传统…

Linux下MySQL8.x的编译安装与使用

Linux下MySQL的安装与配置 1. 安装环境初始化 1.1 查看是否安装过MySQL 如果使用rpm安装, 检查一下RPM PACKAGE rpm -qa | grep -i mysql # -i 忽略大小写 # 或者 yum list installed | grep mysql如果存在mysql-libs的旧版本包&#xff0c;显示如下 #存在 [rootlocalhost ~]…

NavMesh只制作可移动的导航网,清除多余不可走区域

只制作可移动的导航网。它使存储文件大小减小并提高性能。它消除了迁移到随机区域的问题。添加链接描述 1.如何使用 2.创建一个包含“NavMeshCleaner”组件的对象。Andadd指向可定制区域。 按住控制键并单击添加点。如果要移动它&#xff0c;请按 输入上的control键并单击。您…

信息安全工程师(55)网络安全漏洞概述

一、定义 网络安全漏洞&#xff0c;又称为脆弱性&#xff0c;是网络安全信息系统中与安全策略相冲突的缺陷&#xff0c;这种缺陷也称为安全隐患。漏洞可能导致机密性受损、完整性破坏、可用性降低、抗抵赖性缺失、可控性下降、真实性不保等问题。 二、分类 网络安全漏洞可以根据…

桥接模式,外界与主机通,与虚拟机不通

一 二 在此选择Windows与外界连接的网卡&#xff0c;通过有线连就选有线网卡&#xff0c;通过无线连就选无线网卡。 三 如果需要设置固定IP&#xff0c;则选择"Manual"进行设置。我这边根据实际需要&#xff0c;走无线的时候用DHCP&#xff0c;走有线的时候设固定IP…

C#中的委托、匿名方法、Lambda、Action和Func

委托 委托概述 委托是存有对某个方法的引用的一种引用类型变量。定义方法的类型&#xff0c;可以把一个方法当作另一方法的参数。所有的委托&#xff08;Delegate&#xff09;都派生自 System.Delegate 类。委托声明决定了可由该委托引用的方法。 # 声明委托类型 委托类型声…

Golang | Leetcode Golang题解之第507题完美数

题目&#xff1a; 题解&#xff1a; func checkPerfectNumber(num int) bool {if num 1 {return false}sum : 1for d : 2; d*d < num; d {if num%d 0 {sum dif d*d < num {sum num / d}}}return sum num }

一文掌握Kubernates核心组件,构建智能容器管理集群

1.Kubernates简要概述 Kubernates&#xff08;常称为K8s&#xff0c;因省略了“ubernate”中的8个字符&#xff09;是Google开源的容器编排平台&#xff0c;专为简化和自动化应用服务的部署、扩展和管理而设计。它将应用与底层的服务器抽象开来&#xff0c;提供了自动化的机制…

怎么提取pdf的某一页?批量提取pdf的某一页的简单方法

怎么提取pdf的某一页&#xff1f;在日常工作与学习中&#xff0c;我们经常会遇到各式各样的PDF文件&#xff0c;它们以其良好的兼容性和稳定性&#xff0c;成为了信息传输和存储的首选格式。然而&#xff0c;在浩瀚的文档海洋中&#xff0c;有时某个PDF文件中的某一页内容尤为重…

Docker存储

前提条件 拥有docker环境&#xff0c;可参考&#xff1a;Docker的安装掌握容器的使用&#xff0c;可参考&#xff1a;Docker容器的使用掌握镜像的使用&#xff0c;可参考&#xff1a;Docker镜像的使用 Docker存储的问题 容器是隔离环境&#xff0c;容器内程序的文件、配置、运…

自动发现-实现运维管理自动化

nVisual-Discovery是一款自动化工具软件&#xff0c;通过多种自动发现技术&#xff0c;协助运维管理人员快速建立可视化的网络文档&#xff0c;提升网络管理的效率与准确性。 01 IP扫描发现 当我们新接手一个网络运维项目&#xff0c;通常缺乏精准的网络文档数据&#xff0c;…

vue3+ts实时播放视频,视频分屏

使用vue3以及播放视频组件Jessibuca Jessibuca地址 使用循环个数来实现分屏 效果图&#xff0c;四屏 九屏 dom代码 <div class"icon"><div class"icon-box"><span class"text">分屏&#xff1a;</span><el-icon …