node.js - Redis发布内存泄漏?

标签 node.js redis

我知道已经有很多这样的问题,但我没有找到适合我实现的问题。 我在 Node.js 环境中使用 redis,感觉 redis.publish 正在泄漏一些内存。我希望它是某种“背压”的东西,就像在这里看到的: Node redis publisher consuming too much memory

但据我理解:Node需要在同步上下文中释放那种压力,否则不会调用Node事件循环,也不会调用GC。

我的程序是这样的:

const websocketApi = new WebsocketApi()
const currentState = {}

websocketApi.connect()
websocketApi.on('open', () => {
  channels.map((channel) => websocketApi.subscribeChannel(channel))
})

websocketApi.on('message', (message) => {
  const ob = JSON.parse(message)

  if (currentState[ob.id]) {
    currentState[ob.id] = update(currentState[ob.id], ob.data)
  } else {
    currentState[ob.id] = ob.data
  }

  const payload = {
    channel: ob.id,
    info: currentState[ob.id],
    timestamp: Date.now(),
    type: 'newData'
  }
  // when i remove this part, the memory is stable
  redisClient.publish(payload.channel, JSON.stringify(payload))
})
// to reconnect in case of error
websocketApi.on('close', () =>
  websocketApi.connect())

似乎消息之间的距离太近了,所以它没有时间释放 redis.publish 中的字符串。

你知道这段代码有什么问题吗?

编辑:更具体地说,当我对我的应用程序进行内存转储时,我可以观察到什么:

  • 内存中充满了字符串,这些字符串是我的字符串化 JSON 有效负载,以及通过 Redis 本身发送的消息“ block ”。他们的 ref 被保存在 redis 客户端内部,称为 chunk 的变量中。 一些字符串有效负载仍在发布,但我创建它们的速度更快。

  • 当我不通过 Redis 发布消息时,“currentState”变量增长到一个点,然后不再增长。它显然对 RAM 有很大的影响,但这是意料之中的。其余的很好,应用程序稳定在 400mb 左右,它在 redis 发布者中爆炸(PM2 重新启动它导致它达到最大 RAM 容量)

  • 我的感觉是,我要求 Redis 发布更多它可以处理的方式,而 Redis 没有时间完成发布消息。它仍然拥有所有的上下文,所以它不会释放任何东西。我可能需要某种“队列”来让 Redis 释放一些上下文并完成消息的发布。这真的有可能还是我疯了?

基本上,我程序中的每个循环都是“独立的”。是否可以拥有与我拥有的循环一样多的 redis 客户端?这是一个更好的主意吗? (恕我直言, Node 是单线程的,所以它无济于事,但它可能有助于 V8 更好地跟踪内存引用和释放内存)

最佳答案

如果客户端因为尚未连接或连接失败或连接失败而未连接,则 redis 客户端会缓冲命令。

确保您可以连接到redis 服务器。确保您的程序已连接到服务器。我建议向 redisClient.on('connect') 添加一个监听器,如果它没有发出,则客户端从未连接。

如果您已连接,客户端不应缓冲,但要使问题尽快出现,请禁用离线队列,将选项 enable_offline_queue: false 传递给 createClient 这将导致在未连接时尝试发送命令失败。

您应该将错误监听器附加到 redisClient:redisClient.on('error', console.error.bind(console))。这可能会产生一条消息,说明客户端缓冲的原因。

关于node.js - Redis发布内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53943451/

相关文章:

javascript - MongoDB 使用 node-mongodb-native 排序

ruby - 如何保存和展示 Dashing 的历史值?

redis - 当redis在kubernetes中使用时,redis URI是什么?

redis - Heroku 崩溃(似乎是 Sidekiq/Redis )

php - 在 zScan Redis 中设置偏移量和限制

node.js - 没有操作系统依赖性的nodejs中的PDF到文本提取器

javascript - 使用 nodemailer 发送多封单独的电子邮件时出现问题

javascript - 在Javascript中获取文件夹和文件列表的最佳方法

node.js - 将 Web 应用程序从 Visual Studio Code 部署到 Azure 应用服务

redis - 按小时在 Redis 中存储和检索记录