当前位置: 首页 > news >正文

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 。

总结

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

相关文章:

Redis批量获取缓存的方法

使用multiGet方法 优点&#xff1a;简单易用&#xff0c;适用于获取少量键的场景。 缺点&#xff1a;当获取的键数量较多时&#xff0c;可能会因为网络延迟导致性能下降。此外&#xff0c;如果某个键不存在&#xff0c;对应的返回值会是null&#xff0c;需要额外处理。 其他…...

MySQL配置文件中server-id的作用是什么

作用一&#xff1a; 通过 server-id 可以用来唯一标识主从复制环境中的一个服务器&#xff0c; 作用二&#xff1a; 再进行主从复制的过程中&#xff0c;会传递二进制日志文件&#xff0c;server-id 帮助MySQL确定哪些日志属于哪个服务器&#xff0c;从而确保日志正确地路由到相…...

Docker入门之构建

Docker构建概述 Docker Build 实现了客户端-服务器架构&#xff0c;其中&#xff1a; 客户端&#xff1a;Buildx 是用于运行和管理构建的客户端和用户界面。服务器&#xff1a;BuildKit 是处理构建执行的服务器或构建器。 当您调用构建时&#xff0c;Buildx 客户端会向 Bui…...

StarRocks数据库在SQL语句中解析JSON字符串

StarRocks数据库在SQL语句中解析JSON字符串 -- 使用数据库 use sr_test; -- 删除表 drop table ts_usr; -- 创建表 CREATE TABLE ts_usr ( uid bigint NOT NULL COMMENT "用户id", uname varchar(64) NULL COMMENT "用户名", ujson varchar(1024) NULL CO…...

RabbitMq-队列交换机绑定关系优化为枚举注册

&#x1f4da;目录 &#x1f4da;简介:&#x1f680;比较&#x1f4a8;通常注册&#x1f308;优化后注册 ✍️代码&#x1f4ab;自动注册的关键代码 &#x1f4da;简介: 该项目介绍&#xff0c;rabbitMq消息中间件&#xff0c;对队列的注册&#xff0c;交换机的注册&#xff0c…...

施磊C++ | 项目实战 | 手写移植SGI STL二级空间配置器内存池 项目源码

手写移植SGI STL二级空间配置器内存池 项目源码 笔者建议配合这两篇博客进行学习 侯捷 | C | 内存管理 | 学习笔记&#xff08;二&#xff09;:第二章节 std::allocator-CSDN博客 施磊C | 项目实战 | SGI STL二级空间配置器源码剖析-CSDN博客 文章目录 手写移植SGI STL二级空…...

C++ | Leetcode C++题解之第507题完美数

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

Git快速上手

概述 Git 是一个免费且开源的分布式版本控制系统&#xff0c;被广泛用于软件开发中的代码版本控制。通过使用 Git&#xff0c;开发者可以高效地追踪文件的变化历史&#xff0c;并支持多人协作开发。本教程将带你快速了解 Git 的基本概念和操作&#xff0c;帮助你开始使用 Git …...

宝塔如何部署Django项目(前后端分离篇)

一、环境安装 1、安装相关软件 点击软件商店&#xff0c;安装下面软件 一、宝塔部署前端 1、打包Vue项目 打开Vue3项目&#xff0c;输入下面打包命令&#xff0c;对Vue项目进行打包&#xff0c; npm run build 2、部署前端 点击宝塔的网站&#xff0c;在PHP项目里点击添加…...

JavaScript解析JSON对象及JSON字符串

1、问题概述&#xff1f; JavaScript解析JSON对象是常用功能之一。 此处我们要明确JSON对象和JSON字符串的区别&#xff1f;否则会给我们的解析带来困扰。 主要实现如下功能&#xff1a; 1、JavaScript解析JSON字符串和JSON对象? 2、JavaScript解析JSON数组? 3、JavaSc…...

Elasticsearch 构建实时数据可视化应用

Elasticsearch 构建实时数据可视化应用 Elasticsearch 构建实时数据可视化应用一、构建实时数据可视化应用的基本原则1. 数据采集2. 数据处理和清洗3. 数据存储和索引4. 数据可视化展示二、实时数据可视化应用数据存储和检索功能基于Elasticsearch构建实时数据搜索和过滤功能El…...

NVR批量管理软件/平台EasyNVR多个NVR同时管理:H.265与H.264编码优势和差异深度剖析

在数字化安防领域&#xff0c;视频监控系统正逐步成为各行各业不可或缺的一部分。随着技术的不断进步&#xff0c;传统的视频监控系统已经难以满足日益复杂和多变的监控需求。下面我们谈及NVR批量管理软件/平台EasyNVR平台H.265与H.264编码优势及差异。 一、EasyNVR视频汇聚平台…...

C/C++(六)多态

本文将介绍C的另一个基于继承的重要且复杂的机制&#xff0c;多态。 一、多态的概念 多态&#xff0c;就是多种形态&#xff0c;通俗来说就是不同的对象去完成某个行为&#xff0c;会产生不同的状态。 多态严格意义上分为静态多态与动态多态&#xff0c;我们平常说的多态一般…...

汽车及零配件企业海量文件数据如何管

汽车行业特点 汽车行业是工业企业皇冠上的一颗明珠&#xff0c;在国民经济中占据着举足轻重的地位。汽车行业具备技术密集、创新速度快、供应链复杂等特点&#xff0c;具体体现为&#xff1a; 技术密集&#xff1a;汽车行业是技术密集型行业&#xff0c;覆盖机械、电子、软件、…...

【AI学习】Mamba学习(十二):深入理解S4模型

#1024程序员节&#xff5c;征文# HiPPO的学习暂告一段落&#xff0c;按照“HiPPO->S4->Mamba 演化历程”&#xff0c;接着学习S4。 S4对应的论文&#xff1a;《Efficiently Modeling Long Sequences with Structured State Spaces》 文章链接&#xff1a;https://ar5iv…...

linux入门之必掌握知识点

#1024程序员节&#xff5c;征文# Linux基础 top命令详解 top命令是用来查看进程系统资源使用情况的工具&#xff0c;它可以动态的现实。 top命令执行后&#xff0c;按大写M可以按内存使用情况进行排序&#xff0c;大写P可以按CPU使用情况进行排序&#xff0c;大写H可以显示线…...

【Web.路由]——路由原理

这篇文章&#xff0c;我们来讲一讲什么是路由。 路由是 将用户请求地址映射为一个请求委托的过程&#xff0c;负责匹配传入的Http请求&#xff0c;然后将这些请求发送到应用的可执行终结点。 这里需要注意一个内容&#xff0c;发送到应用的可执行终结点。 路由的分类&#x…...

Spring Boot技术在中小企业设备管理中的应用

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

Lua表(Table)

软考鸭微信小程序 过软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 Lua中的表&#xff08;table&#xff09;是一种核心数据结构&#xff0c;它既是数组也是字典&#xff0c;能够存储多种类型的数据&#xff0c;包括数字、字符…...

51单片机应用开发(进阶)---外部中断(按键+数码管显示0-F)

实现目标 1、巩固数码管、外部中断知识 2、具体实现&#xff1a;按键K4&#xff08;INT1&#xff09;每按一次&#xff0c;数码管从0依次递增显示至F&#xff0c;再按则循环显示。 一、共阳数码管 1.1 共阳数码管结构 1.2 共阳数码管码表 共阳不带小数点0-F段码为&#xff…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...