【问题标题】:Memory usage of node-influx when queryingnode-influx 查询时的内存使用情况
【发布时间】:2021-06-19 04:59:09
【问题描述】:

我使用 node-influx 和 influx.query(...) 使用太多堆。

在我的应用程序中,我有类似的东西

const data = await influx.query(`SELECT "f_power" as "power", "nature", "scope", "participantId"
    FROM "power"
    WHERE
    "nature" =~  /^Conso$|^Prod$|^Autoconso$/ AND
    "source" =~ /^$|^One$|^Two AND
    "participantId" =~ /${participantIdFilter.join('|')}/ AND
    "time" >= '${req.query.dateFrom}' AND
    "time" <= '${req.query.dateTo}'
    GROUP BY "timestamp"
`);

wb = dataToWb(data)

XLSX.writeFile(wb, filename);

数据是一个大约50M的结果集(I used this code) 而且这个方法使用的堆大约是350M(我用的是process.memoryUsage().heapUsed)

我对这两个值之间的差异感到惊讶... 那么是否有可能使这个查询的资源消耗更少?

其实我是用data来制作xlsx文件的。并且该文件的生成导致节点进程内存不足。方法 XLSX.writeFile(wb, filename) 使用大约 100M。这还不够填满我的 512M RAM。所以我认为这是流入查询使用的堆,GC 永远不会收集它。

其实我不明白为什么一代人会犯这个错误。为什么 V8 不能释放在另一个上下文中执行的方法使用的内存?

【问题讨论】:

    标签: node.js memory memory-leaks influxdb


    【解决方案1】:

    node-influx(1.x 客户端)读取整个响应,将其解析为 JSON,并将其转换为结果(数据数组)。在处理响应期间,堆上有更多的中间对象。您还应该在查询之前和之后运行节点垃圾收集器,以更好地估计它需要多少堆。现在,您只能通过减少结果列或行(按限制、时间或聚合)来控制结果内存使用情况。您还可以连接具有较小结果的查询,以减少临时对象导致的最大堆使用量。当然,这是由代码的时间和复杂性来支付的。

    使用 2.x 客户端 (https://github.com/influxdata/influxdb-client-js) 可以减少内存使用量。它不创建中间 JSON 对象,内部处理结果为更小的块,它有一个类似 observable 的 API,让用户决定如何表示结果行。它使用 FLUX 作为查询语言,需要 InfluxDB 2.x 或 InfluxDB 1.8(启用 2.x API)。

    【讨论】:

    • 我已经修改了我的问题。如果查询函数使用的内存是中间对象,如果内存达到V8限制,则在执行我的下一个方法期间,GC应该将其清除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多