Сравнение использования памяти AWS ECS Fargate и локального Docker

Мы используем задачи AWS Fargate ECS для нашего микросервиса spring webflux java 11. Мы используем java-образ FROM gcr.io/distroless/java:11. Когда наше приложение докеризовано локально и развернуто как образ внутри контейнера докеров, использование памяти довольно эффективно, и мы можем видеть, что использование кучи никогда не превышает 50%.

Однако когда мы развертываем тот же образ, используя тот же файл dockerfile в AWS Fargate в качестве задачи ECS, AWS Dashbaord показывает совершенно другую картину. Использование памяти никогда не снижается, а журналы Cloudwatch вообще не показывают проблем с OutOfMemory. В AWS ECS после развертывания мы провели тест на пиковую нагрузку, стресс-тест, после которого использование памяти достигло 94%, а затем провели тест на выдержку в течение 6 часов. Использование памяти по-прежнему составляло 94% без каких-либо ошибок OOM. Память сбор мусора происходит постоянно и не дает приложению уйти в OOM. Но остается на уровне 94%.

Для локального тестирования использования памяти приложением мы используем Visual VM. Мы также пытаемся подключиться к удаленной задаче ECS в AWS Fargate с помощью Amazon ECS Exec, но эта работа еще не завершена.

Мы видели ту же проблему с другими микросервисами в нашем и других кластерах. Как только она достигает максимального числа, она никогда не прекращается. Пожалуйста, помогите, если кто-то сталкивался с той же проблемой ранее.

Изменить от 10.10.2022: мы подключились к задаче AWS Fargate ECS с помощью Amazon ECS Exec, и ниже приведены результаты.

Мы проанализировали журналы GC задачи AWS ECS Fargate и смогли увидеть сообщения. Он использует GC по умолчанию, т.е. Simple GC. Мы продолжаем получать «Ошибка приостановки выделения молодого поколения», что означает, что памяти, выделенной для молодого поколения, недостаточно, и, следовательно, происходит сбой GC.

[2022-10-09T13:33:45.401+0000][1120.447s][info][gc] GC(1417) Полная пауза (ошибка распределения) 793M->196M(1093M) 410,170 мс [2022-10-09T13:33:45.403+0000][1120.449s][info][gc] GC(1416) Pause Young (Ошибка распределения) 1052M->196M(1067M) 460,286 мс

Мы внесли некоторые изменения в код, связанные с тем, что byteArray дважды копировался в память, и память уменьшилась, но ненамного.

      /app # ps -o pid,rss
PID   RSS
    1 1.4g
   16  16m
   30  27m
  515  23m
  524  688
 1655    4
/app # ps -o pid,rss
PID   RSS
    1 1.4g
   16  15m
   30  27m
  515  22m
  524  688
 1710    4

Даже после полного gc, как показано ниже, память не убывает:

2022-10-09T13:39:13.460+0000][1448.505s][info][gc] GC(1961) Полная пауза (ошибка распределения) 797M->243M(1097M) 502,836 мс

Одно важное наблюдение заключалось в том, что после запуска проверки кучи сработал полный сборщик мусора, и даже это не очистило память. Он показывает 679M->149M, но команда ps -o pid,rss не показывает падение, как и AWS Container Insights. график

2022-10-09T13:54:50.424+0000][2385.469s][info][gc] GC(1967) Pause Full (GC, инициированный проверкой кучи) 679M->149M(1047M) 448,686 мс [2022-10-09T13:56:20.344+0000][2475.390s][info][gc] GC(1968) Полная пауза (GC, инициированная проверкой кучи) 181M->119M(999M) 448,699 мс

1 ответ

Как вы запускаете его локально, устанавливаете ли вы какие-либо параметры (процессор/память) для контейнера, который вы запускаете? В Fargate есть несколько уровней конфигураций ресурсов (размер задачи и количество ресурсов, которые вы назначаете контейнеру — подробнее читайте в этом блоге ).Еще одна вещь, которую следует учитывать, это то, что с Fargate вы можете попасть на инстанс с >> емкостью, превышающей размер задачи, который вы настроили. Fargate создаст контрольную группу, которая упакует ваши контейнеры до этого размера, но некоторые старые программы (и версии Java) не поддерживают контрольную группу, и они могут предположить, что объем памяти, который у вас есть, равен памяти, доступной в экземпляре (которую вы не вижу), а не размер задачи (и cgroup), который был настроен.

У меня нет точного ответа (и это не уместилось в комментарии), но это может быть областью, которую вы можете исследовать (возможность выполнить в контейнере должна помочь - ECS exec отлично подходит для этого).

Другие вопросы по тегам