Redis循环慢接口优化
原慢接口
List<String> keys = new ArrayList<>(Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"));
List<String> res = new ArrayList<>();
for (String key : keys) {
String value = (String) redisTemplate.opsForValue().get(key);
if (value == null) {
value = dataMapper.getValueFromDB(key);
redisTemplate.opsForValue().set(key, value, 60 * 60, TimeUnit.SECONDS);
res.add(value);
}
}
return res;
原因分析
当keys 数据过大,
RTT时间会变大。
多个Redis命令之间会有往返时间消耗。

使用MGET、Pipelined可以减少
RTT时间首次进入此代码域,由于缓存为空,全部走数据库,也会导致接口变慢。
解决方式
Pipelined、MGET 能批量获取数据,但注意元素个数
Pipelined
注意:Redis集群部署时,不同的key可能对应不同实例节点,不能被处理。
List<String> keys = new ArrayList<>(Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"));
List<String> res = new ArrayList<>();
List list = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
for (String key : keys) {
connection.get(key.getBytes());
}
return null;
});
// 缓存不存在的keys
List<String> nullKeys = new ArrayList<>();
for (int i = 0; i < keys.size(); i++) {
if (list.get(i) == null) {
nullKeys.add(keys.get(i));
} else {
res.add((String) list.get(i));
}
}
// 缓存中不存在的值调用 数据库批量查询
Map<String, String> values = dataMapper.getBatchValue(nullKeys);
// 添加返回值,并更新缓存
values.forEach((key, value) -> {
redisTemplate.opsForValue().set(key, value, 60 * 60, TimeUnit.SECONDS);
res.add(value);
});
return res;
MGET
List<String> keys = new ArrayList<>(Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"));
List<String> res = new ArrayList<>();
List list = redisTemplate.opsForValue().multiGet(keys);
// 缓存不存在的keys
List<String> nullKeys = new ArrayList<>();
for (int i = 0; i < keys.size(); i++) {
if (list.get(i) == null) {
nullKeys.add(keys.get(i));
} else {
res.add((String) list.get(i));
}
}
// 缓存中不存在的值调用 数据库批量查询
Map<String, String> values = dataMapper.getBatchValue(nullKeys);
// 添加返回值,并更新缓存
values.forEach((key, value) -> {
redisTemplate.opsForValue().set(key, value, 60 * 60, TimeUnit.SECONDS);
res.add(value);
});
return res;
Redis循环慢接口优化的更多相关文章
- 单一接口优化过程全记录(主要涉及Redis)
接口优化过程记录 问题背景 某个接口耗时长(247ms),但里面逻辑不算复杂,只进行了简单的对象引用以及操作了多次Redis 步骤1:链路追踪,确定业务耗时点 接口里通过链路追踪以及日志查询发现主要是 ...
- Redis数据导入工具优化过程总结
Redis数据导入工具优化过程总结 背景 使用C++开发了一个Redis数据导入工具 从oracle中将所有表数据导入到redis中: 不是单纯的数据导入,每条oracle中的原有记录,需要经过业务逻 ...
- 使用Nginx Lua实现redis高性能http接口
使用Nginx Lua实现redis高性能http接口 时间 -- :: 峰云就她了 原文 http://xiaorui.cc/2015/01/27/使用nginx-lua实现redis高性能http ...
- 【redis】redis实现API接口调用调用次数的限制
redis实现API接口调用调用次数的限制 参考地址:https://bbs.csdn.net/topics/391856106?page=1 参考地址:https://www.cnblogs.com ...
- ASP.NET Core WebApi基于Redis实现Token接口安全认证
一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebSer ...
- for循环实战性能优化之使用Map集合优化
笔者在<for循环实战性能优化>中提出了五种提升for循环性能的优化策略,这次我们在其中嵌套循环优化小循环驱动大循环的基础上,借助Map集合高效的查询性能来优化嵌套for循环 ...
- for循环实战性能优化
完成同样的功能,用不同的代码来实现,性能上可能会有比较大的差别,所以对于一些性能敏感的模块来说,对代码进行一定的优化还是很有必要的.今天就来说一下java代码优化的事情,今天主要聊一下对于for(wh ...
- Redis从出门到高可用--Redis复制原理与优化
Redis从出门到高可用–Redis复制原理与优化 单机有什么问题? 1.单机故障; 2.单机容量有瓶颈 3.单机有QPS瓶颈 主从复制:主机数据更新后根据配置和策略,自动同步到备机的master/s ...
- java关于for循环的效率优化
我们知道在实现一个功能的时候是可以使用不同的代码来实现的,那么相应的不同实现方法的性能肯定也是有差别的,所以我们在写一些对性能很敏感的模块的时候,对代码进行优化是很必要的,所以我们说一下for循环(w ...
- 移动端API接口优化的术和结果
最近一直在忙工作的事情,所以文章写得有些少. 有3-5篇文章都是写到一半然后被别的事情给打断了,所以,我得找个时间好好补补. 最近一直在关注移动端接口API的可用性问题,在移动时代这个做这个优化能产生 ...
随机推荐
- THREE.JS中 CubeTextureLoader 使用避坑
最近在跟着教程学THREE.JS,毕竟在现在的前端开发市场上,THREE.JS太火爆了. 今天学到"纹理"这一块的时候,跟着教程敲代码,发现自己的没有正确显示,百思不得其解,打开控 ...
- 用CSS border画一个铅笔
先上效果图 该例子来自 CSS世界 的书中项目 总结技巧如下: 巧用 border 和 伪元素 来 绘制层叠效果. 使用 transform-origin 来改变元素的轴心 使用 filter:dro ...
- SQL Server – 执行计划和各种 join 方式 (Execution plan & Join Pattern)
前言 我几乎从来没有遇到过性能问题, 毕竟项目真的太小了. 一般上只要用常识去建 index 就可以了. 但是这并不阻碍我对知识的追求. 这篇是关于一些性能优化和原理的内容. 纯属学习, 希望未来有机 ...
- react-pdf预览在线PDF的使用
1.在react项目中安装react-pdf依赖包 建议安装8.0.2版本的react-pdf,如果安装更高版本的可能出现一些浏览器的兼容性问题: npm install react-pdf@8.0. ...
- C++ STL(标准模版库)—— vector 与 迭代器
STL 基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称. STL 从广义上讲分为三类:algorithm(算法).containe ...
- 如何创建一个Java游戏客户端
创建一个完整的Java游戏客户端示例是一个相对复杂的任务,因为它通常涉及图形用户界面(GUI).事件处理.游戏逻辑等多个方面.为了简化,我将提供一个基于Java Swing的简单游戏客户端示例:一个简 ...
- 信创环境经典版SuerMap iManager启动崩溃
一.问题环境 操作系统:银河麒麟kylin V10 CPU:鲲鹏920 SuperMap iManager 10.2.1 硬件:16H64G机器 二.现象 磁盘和内存都有空闲,首次启动SuperMap ...
- 微信小程序上拉加载
下面是一个示例,在个人使用的过程中按自己需求进行更改 创建一个DataController控制器 php artisan make:controller DataController 创建一个Data ...
- Linux PSI--Pressure Stall Information
Google在在Android11及之后版本的LMKD中,使用了psi作为杀进程的策略,本文简单介绍下psi. 转载自使用PSI(Pressure Stall Information)监控服务器资源_ ...
- Java日期时间API系列14-----Jdk8中java.time包中的新的日期时间API类,java日期计算1,获取年月日时分秒等
通过Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析 ,可以看出java8设计非常好,实现接口Temporal, Tempora ...