node.js - nodejs 队列大数组内存溢出

 晦涩的爱情嵌 发布于 2022-10-30 22:39

报错如下
FATAL ERROR: CALL_AND_RETRY_0 Allocation failed - process out of memory

我的代码

connection.query('select * from `table` limit 100000', function(err, rows, fields) {
数据库里的链接大概做了个队列 就是 不断取数据 大概每次做 1W 大多时候 运行不稳定 出如上报错

var array = [1,2,3,4];
function check()
{
if(array.length > 0)
var url = array.pop();
load(url);
}}
function load(url)
{
http.get(url, function(res){
check();
)
}}

http://stackoverflow.com/ques... 跟这个情况类似
请问怎么解决比较好 能不能不断清楚内存的垃圾?

1 个回答
    • 如果我没数错的话,你是一次性取出10万条,如果估算你的一行记录是10K的话,10万条的话,大概就是1个G的内存,所以出现OOM

    • 对于这种问题最好的处理方式就是流处理,你会需要这个方法的,把每一次的highWaterMark设置成1万,比方说你总共有100万条数据要取出来,你也不用自己去控制了你代码下面的array和load,写好每次处理1万的ReadStream

    • TALK IS CHEAP, SHOW ME THE CODE

    const SQL_SINGLE_RETURN_ROWS = 20000
    const resStream = new Readable({ highWaterMark: SQL_SINGLE_RETURN_ROWS, objectMode: true })
    resStream.on('data', () => {
    })
    resStream.on('end', () => {
        // stream end 
    })
    const SQL = 'select * from `table` limit 100000'
    const query = connection.query(SQL).stream({ highWaterMark: SQL_SINGLE_RETURN_ROWS / 2 })
    query.pipe(resStream)
    query.on('error', e => console.error(e))
    query.on('end', () => {
      // if you need release conn 
      // connection.release()
    })
    • 伪代码如上所示,untest根据自己实际业务改改

    注:最好设置ReadStreamhighWaterMark比mysql的读数据的stream要大一些,要不然数据来不及consumer的话会丢失数据的哟!!

    2022-11-12 01:42 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有