tgoop.com/super_oleg_dev/217
Last Update:
Привет!
Как-то писал про серверные оптимизации ноды, и в частности про параметр --max-semi-space-size -
https://www.tgoop.com/super_oleg_dev/115
Часто появляются новые кейсы которые показывают сколько же нюансов в работе GC ноды.
Например, не так давно коллеги разбирались с частыми OOM рестартами приложения.
Оказалось, что в условиях ограниченных k8s лимитов, у этого приложения дефолтные значения --max-old-space-size были выше или примерно равны лимиту по памяти для подов этого приложения.
Чем больше параметр, тем меньше времени GC тратит на очистку неиспользуемой памяти при ее низком потреблении, что при выделенных 512mb памяти на под, и max-old-space-size размером в 1gb, позволит накопиться мусору и приведет к OOM.
Также, этот параметр не ограничивает все потребление памяти Node.js процессом, а только ее часть, то есть даже при выделенных 1gb памяти на под, значение max-old-space-size должно быть ниже 1gb, иначе приведет к OOM.
Хорошо написано про параметр в этом документе, предлагают ставить max-old-space-size примерно в 75% от доступной памяти - https://github.com/goldbergyoni/nodebestpractices/blob/master/sections/docker/memory-limit.md
Сегодня разбирался с обратной проблемой.
У приложения большое потребление памяти, долго работает GC, высокий лаг event loop.
Обнаружил что у коллег все стало сильно хуже когда подняли --max-old-space-size с 2gb до 4gb.
Погонял приложение локально, даже с кэшами ему нужно памяти сотни мегабайт, но никак не гигабайты. Правда важно учесть нюанс, что SSR запросы на больших страницах дорогие и по памяти, это могут быть мегабайты строк (HTML, стейт и прочее) в памяти на каждый запрос и конечно тут нужно иметь запас на случай нагрузок.
Еще раз погонял нагрузки на приложении уже с увеличенным --max-old-space-size, и увидел что сильно поднимается пиковое потребление памяти, 1-2 гигабайта легко, которые потом очищаются до пары сотен мегабайт.
Как это работает:
- приложению выделено слишком много памяти
- GC работает реже
- потребление памяти быстро повышается (на продакшене постоянные стабильные нагрузки)
- и тут GC начинает медленно работать, особенно заметно на major очистках!
То есть все логично, очень много не используемой памяти, и подчистить ее дело не быстрое. При этом, столько памяти приложению не нужно, и ее можно было очистить гораздо раньше, с гораздо меньшим налогом на CPU.
Теперь я хочу исследовать поподробнее, хорошая ли наша базовая рекомендация повышать дефолты --max-semi-space-size, так как этот параметр ведет к еще более заметному накоплению памяти между очистками, и будет ли корреляция с разными значения --max-old-space-size (хотя отвечают они за разные участки памяти, и на метриках по идее от изменения первого параметра я должен увидеть влияние на GC minor, а от второго на GC major).
И тут легко попасть в ситуацию, когда увеличение работы которую нужно сделать GC не компенсируется уменьшением частоты работы GC.
Что я собственно и увидел в сегодняшнем кейсе c повышенным значением --max-old-space-size, где GC и major и minor работать стали реже в два раза, но тяжелее чуть ли не в десяток раз (прикладываю графики)
BY SuperOleg dev notes

Share with your friend now:
tgoop.com/super_oleg_dev/217