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 相关文章推荐
Mozilla 表达式 __noSuchMethod__
Apr 05 Javascript
javascript Array.sort() 跨浏览器下需要考虑的问题
Dec 07 Javascript
JQuery操作tr和td内容的方法实例
Mar 06 Javascript
javascript使用定时函数实现跳转到某个页面
Dec 25 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
Apr 01 Javascript
在Ubuntu系统上安装Node.JS的教程
Oct 15 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
Dec 26 Javascript
详解JS对象封装的常用方式
Dec 30 Javascript
angularjs ui-router中路由的二级嵌套
Mar 10 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
May 08 jQuery
只有 20 行的 JavaScript 模板引擎实例详解
May 11 Javascript
vue 在单页面应用里使用二级套嵌路由
Dec 19 Vue.js
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
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
php 显示指定路径下的图片
2009/10/29 PHP
JavaScript 读取元素的CSS信息的代码
2010/02/07 Javascript
该如何加载google-analytics(或其他第三方)的JS
2010/05/13 Javascript
javaScript如何处理从java后台返回的list
2014/04/24 Javascript
使用时间戳解决ie缓存的问题
2014/08/20 Javascript
使用VS开发 Node.js指南
2015/01/06 Javascript
js HTML5 Canvas绘制转盘抽奖
2020/09/13 Javascript
js中开关变量使用实例
2017/02/24 Javascript
nodejs个人博客开发第五步 分配数据
2017/04/12 NodeJs
vue.js内部自定义指令与全局自定义指令的实现详解(利用directive)
2017/07/11 Javascript
使用Fullpage插件快速开发整屏翻页的页面
2017/09/13 Javascript
vue iview组件表格 render函数的使用方法详解
2018/03/15 Javascript
Vue组件中prop属性使用说明实例代码详解
2018/05/31 Javascript
浅谈vuex actions和mutation的异曲同工
2018/12/13 Javascript
js打开word文档预览操作示例【不是下载】
2019/05/23 Javascript
vuex 多模块时 模块内部的mutation和action的调用方式
2020/07/24 Javascript
[03:22]DAC最前线(第二期)—DOTA2亚洲邀请赛主赛场周边及线路探访
2015/01/24 DOTA
[03:14]辉夜杯主赛事 12月25日每日之星
2015/12/26 DOTA
python 通过logging写入日志到文件和控制台的实例
2018/04/28 Python
django 使用 request 获取浏览器发送的参数示例代码
2018/06/11 Python
python3中函数参数的四种简单用法
2018/07/09 Python
python logging重复记录日志问题的解决方法
2018/07/12 Python
深入理解Django自定义信号(signals)
2018/10/15 Python
pandas 透视表中文字段排序方法
2018/11/16 Python
python生成器与迭代器详解
2019/01/01 Python
python操作gitlab API过程解析
2019/12/27 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
2020/02/26 Python
python3 xpath和requests应用详解
2020/03/06 Python
详解Css3新特性应用之过渡与动画
2017/01/10 HTML / CSS
彪马美国官网:PUMA美国
2017/03/09 全球购物
美国婴童服装市场上的领先品牌:Carter’s
2018/02/08 全球购物
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
大学生军训广播稿
2014/01/24 职场文书
奉献爱心演讲稿
2014/09/04 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书