node上的redis调用优化示例详解


Posted in Javascript onOctober 30, 2018

前言

如果一个 Node 应用有多台服务器或多个进程在跑,每个进程都拥有自己的内存空间,各个进程之间的数据共享就显得非常重要。

使用数据库是一个解决数据共享的方案,但一些临时性、高并发的数据并不太适合直接写入数据库,比如 session。

引入 Redis 可以解决数据共享的问题,也因为 Redis 是基于内存存储的特点,有着非常高的性能,可以大大降低数据库读写的压力,提升应用的整体性能。

Redis 还可以用来:缓存复杂的数据库查询结果,做自增长统计,暂存用户操作状态等功能。

最近负责的node项目在高并发的情况下性能表现非常的差,rt基本会在7 80ms甚至100ms以上,由于对外提供了dubbo接口,所以经常导致上游应用和自己的dubbo线程池耗尽,所以花了一点时间排查了一番,才发现原来自己的node功力还有很长的路要走啊~之后node的文章可能会越来越多~

最蠢的方式

先来看看我最早是怎么用的呢:

for(let i = 0; i < params.length; i++) {
 redisKey = getKey(params.id);
 let value = await redis.exec('get', redisKey);
}

这就是我最原始的调用方法,就是在for循环里不断的去await结果的请求,这样的结果就是每一个请求都需要等待上一个请求完成再去执行,只要在高流量的时候有一部分请求rt很高,就会引起雪崩的反应。

使用Promise.all优化请求

经过了一阵谷歌之后,我发现可以通过Promise.all的形式来进行请求链路的优化:

for(let i = 0; i < params.length; i++) {
redisKey = getKey(params.id);
 arr.push(redis.exec('get', redisKey))
}
await Promise.all(arr);

上面的第一种方式被我司的node大神严重吐槽了10分钟,然后告诉我,使用Promise.all的方式可以很有效的优化这种连续的网络请求,我赶紧将代码改完并上线。

自信满满的上线之后,迎来的确实现实无情的打击,在高流量的时刻,报警依然不断,我一边和领导说“没事,我再看看”,心里一边想着辞职报告该怎么写。

redis的正确使用姿势

在继续经过了一系列的谷歌之后,我才发现原来的是对redis的理解太浅了,针对于业务上的需求,我不假思索的只知道使用最简单的set和get,而redis对于set和get这样的命令是一条命令一个tcp请求,在业务场景上确实不太合理,于是我使用谷歌告诉我的pipeline机制去改造现有的get请求:

let batch = await RedisClient.getClient().batch();
for(let i = 0; i < params.length; i++) {
 batch.get(redisKey);
}
batch.exec();

对于pipeline机制大家可以看这篇文章。在使用pipeline之后,便秘一下就通畅了,再也没有报警过,终于可以不用辞职了。

再后面的日子里,我觉得认真的研究一下redis这个东西,保证让上面的问题不再发生,于是我发现其实还是有一种更加简单的方案的,那就是使用mget:

for(let i = 0; i < params.length; i++) {
 redisKey = getKey(params.id);
 arr.push(redisKey);
}
let value = await redis.exec('mget', arr);

使用mget进行批量的查询,这是redis里比较常见的一种方式了~

总结一下

在对以上四种方式进行了对比之后得出了数据上的结论:

在一个200次的循环中调用redis请求,第一种最蠢的方案大概是8000ms左右,第二种Promise.all的方案大概在2000ms左右,而第三和第四种方案,大概只需要几十ms就能完成,这真的是质的飞跃啊。

这个线上血淋淋的案例让我决定真的要好好的研究一下redis,不能再轻视它导致犯错。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript去除字符串中所有标点符号和提取纯文本的正则
Jun 07 Javascript
js实现右下角提示框的方法
Feb 03 Javascript
如何屏蔽防止别的网站嵌入框架代码
Aug 24 Javascript
浅谈Sublime Text 3运行JavaScript控制台
Jun 06 Javascript
bootstrap fileinput组件整合Springmvc上传图片到本地磁盘
May 11 Javascript
AngularJs点击状态值改变背景色的实例
Dec 18 Javascript
在vue里使用codemirror遇到的问题
Nov 01 Javascript
Puppeteer 爬取动态生成的网页实战
Nov 14 Javascript
vue2.0项目集成Cesium的实现方法
Jul 30 Javascript
vue 实现滚动到底部翻页效果(pc端)
Jul 31 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
Jul 17 Javascript
JavaScript实现切换多张图片
Jan 27 Javascript
elementUI 设置input的只读或禁用的方法
Oct 30 #Javascript
Vue.js 父子组件通信的十种方式
Oct 30 #Javascript
vue通过style或者class改变样式的实例代码
Oct 30 #Javascript
vue通过cookie获取用户登录信息的思路详解
Oct 30 #Javascript
微信小程序实现左滑修改、删除功能
Oct 19 #Javascript
小程序实现列表删除功能
Oct 30 #Javascript
require.js 加载过程与使用方法介绍
Oct 30 #Javascript
You might like
《超神学院》霸气归来, 天使彦上演维多利亚的秘密
2020/03/02 国漫
PHP中substr_count()函数获取子字符串出现次数的方法
2016/01/07 PHP
PHP数组函数知识汇总
2016/05/12 PHP
浅谈PHP正则中的捕获组与非捕获组
2016/07/18 PHP
PHP7 新特性详细介绍
2016/09/06 PHP
PHP中类的自动加载的方法
2017/03/17 PHP
看了就知道什么是JSON
2007/12/09 Javascript
js利用与或运算符优先级实现if else条件判断表达式
2010/04/15 Javascript
js 弹出新页面避免被浏览器、ad拦截的一种新方法
2014/04/30 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
2016/10/05 Javascript
浅谈Angular中ngModel的$render
2016/10/24 Javascript
Angular在一个页面中使用两个ng-app的方法(二)
2017/02/20 Javascript
js中innerText/textContent和innerHTML与target和currentTarget的区别
2019/01/21 Javascript
Vue可自定义tab组件用法实例
2019/10/24 Javascript
解决vue请求接口第一次成功,第二次失败问题
2020/09/08 Javascript
[01:18]DOTA2超级联赛专访hanci ForLove淘汰感言曝光
2013/06/04 DOTA
[02:18]DOTA2英雄基础教程 育母蜘蛛
2014/01/20 DOTA
tornado捕获和处理404错误的方法
2014/02/26 Python
详解C++编程中一元运算符的重载
2016/01/19 Python
Python中shapefile转换geojson的示例
2019/01/03 Python
pyqt 实现为长内容添加滑轮 scrollArea
2019/06/19 Python
python实现函数极小值
2019/07/10 Python
python实现马丁策略回测3000只股票的实例代码
2021/01/22 Python
css3实现wifi信号逐渐增强效果实例
2017/08/09 HTML / CSS
HTML5的自定义属性data-*详细介绍和JS操作实例
2014/04/10 HTML / CSS
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
Nordgreen台湾官网:极简北欧设计手表
2019/08/21 全球购物
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
火锅店创业计划书范文
2014/02/02 职场文书
高中毕业自我评价
2014/02/08 职场文书
合作协议书
2014/04/23 职场文书
英语分层教学实施方案
2014/06/15 职场文书
房屋租赁合同协议书范本
2014/10/19 职场文书
2014年敬老院工作总结
2014/12/08 职场文书
2019升学宴主持词范本5篇
2019/10/09 职场文书
Python打包exe时各种异常处理方案总结
2021/05/18 Python