Я знаю, что таких вопросов уже много, но я не нашел такой, который соответствовал бы моей реализации.Я использую redis в окружении Node.js, и кажется, что 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.
Есть ли у вас какие-либо представления о том, что не так в этом коде?
РЕДАКТИРОВАТЬ: более конкретно, что я могу наблюдать, когда я делаю дамп памяти моего приложения:
Память заполнена строкой, которые являются моими полезными нагрузками Stringified JSON, и "кусками"сообщения, которые отправляются через сам Redis.Их ссылка хранится внутри клиента redis в переменных, называемых чанком.Некоторые строковые данные по-прежнему освобождаются, но я создаю их намного быстрее.
Когда я не публикую сообщения через Redis, переменная "currentState" будет расти до тех пор, пока не произойдет точкарасти больше.Очевидно, это сильно влияет на оперативную память, но это ожидаемо.В остальном все в порядке, и приложение стабильно около 400 МБ, и оно взрывается, когда издатель Redis (PM2 перезапускает его, потому что он достигает максимальной емкости ОЗУ)
Мне кажется, что я спрашиваю Redisопубликовать больше, чем он может обработать, и Redis не имеет времени, чтобы закончить публиковать сообщения.Он по-прежнему содержит весь контекст, поэтому ничего не выпускает.Мне может понадобиться какая-то «очередь», чтобы позволить redis освободить некоторый контекст и завершить публикацию сообщений.Это действительно возможность, или я схожу с ума?
По сути, каждый цикл в моей программе "независим".Можно ли иметь столько клиентов Redis, сколько у меня есть петли?это лучшая идея?(ИМХО, узел однопоточный, поэтому это не поможет, но может помочь V8 лучше отслеживать ссылки на память и освобождать память)