首页 > 解决方案 > Redis 发布内存泄漏?

问题描述

我知道已经有很多这样的问题,但我找不到适合我的实施的问题。我在 Node.js 环境中使用 redis,感觉 redis.publish 正在泄漏一些内存。我希望它是某种“背压”的东西,就像在这里看到的那样: Node redis 发布者消耗太多内存

但据我理解: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 中保存的字符串。

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

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

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

标签: node.jsredis

解决方案


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

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

如果您已连接,客户端不应进行缓冲,但为了让问题尽快出现禁用离线队列,将选项传递enable_offline_queue: falsecreateClient此选项将导致在未连接时尝试发送命令失败。

您应该将错误侦听器附加到redisClient: redisClient.on('error', console.error.bind(console))。这可能会产生关于客户端为何缓冲的消息。


推荐阅读