@raiboon

Какие есть подходы для стабилизации потребляемой памяти в го-приложении?

Как можно стабилизировать потребление памяти сервисами, чтобы они всегда потребляли плюс-минус одинаковое количество памяти?
Работаю в большой компании, есть свой кластер k8s.
У меня во владении не очень нагруженные микросервисы, в среднем он потребляет десятки мегабайт, но периодически приходят пользователи и нагрузка неконтролируемо растет, есть легкие запросы, а есть когда пользователь запрашивает кучу данных (с максимальным limit в интерфейсе) и если таких много - сервис падает по оом.
Что делать?
С одной стороны, кубоадмины не хотят выделять больше ресурсов - в среднем потребление мизерное, предлагают разбираться с потреблением памяти самостоятельно и грозятся, что скоро закрутят гайки, и нельзя будет поставить лимит отличным от реквеста.
Можно, конечно, пойти административным ресурсов и выделят столько, сколько попрошу.
Но вот все-равно, непонятно, сколько-то просить.
Может есть какие-то подходы для стабилизации потребления памяти?
Вообще непонятно, сколько ресурсов требовать, если нагрузка непостоянная. Сейчас оно работает за счет того, что лимиты выставлены в среднее мизерное потребление памяти 32-64 мб, но лимиты выкручены в гигабайт, что пока один сервис отвечает большим чанокм данных, другим вряд ли понадобится эта память. Но есть что-то в этом неправильное.
  • Вопрос задан
  • 166 просмотров
Пригласить эксперта
Ответы на вопрос 2
Lynn
@Lynn
nginx, js, css
Что бы потреблять меньше памяти надо потреблять меньше памяти.

Поскольку в вопросе никакой конкретики нет, то вот вам общие соображения:

Например если у вас запросили 1000 элементов, то не вычитывать из базы всю 1000, а прочитать 10, отправить часть ответа, прочитать следующие 10 и так далее.

Второй подход, ограничить одновременные «тяжёлые» запросы — если вы уже обрабатываете «тяжёлый» запрос, то второй такой запрос надо поставить в очередь и начать обрабатывать только после завершения первого.
Ответ написан
Комментировать
WinPooh32
@WinPooh32
Stack Overflow answer searching expert
Если нужно мутировать много строк, то не используйте строки, а работайте с байтами. Пакет bytes в помощь.

Используйте sync.Pool для уменьшения количества аллокаций.

Ограничивайте количество одновременных запросов. Тут могу посоветовать использовать семафор с весами. Идея в том, чтобы задать каждому запросу свой вес и при переполнении семафора остановить обработку новых запросов до тех пор, пока ресурс не освободится. Здесь главное ввести лимит на максимальное количество соединений, после которого можно и дропать запросы (сейчас у вас по сути то же самое происходит, но из-за падения сервиса, что намного хуже).

В самом крайнем случае можно попросить рантайм освободить занятую память:
runtime.GC()
debug.FreeOSMemory()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы