В последнее время мы наблюдаем рост использования памяти некоторыми функциями, что привело к появлению Process exited before completing request
и новому экземпляру лямбда-выражения.
Впервые мы заметили это 11.09.2018 в 12:43:06. Незадолго до этого мы провели развертывание, изменив среду выполнения с dotnetcore2.0 на 2.1. Никаких других значительных изменений в коде, которые могли вызвать утечку памяти, внесено не было, и до этого развертывания он работал без ошибок.
Я воспроизвел ошибку с помощью следующего кода:
public class DynamoDBTrigger
{
private IAmazonDynamoDB _ddbClient;
public DynamoDBTrigger()
{
_ddbClient = new AmazonDynamoDBClient();
}
[LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
public void Process(DynamoDBEvent ev, ILambdaContext context)
{
foreach (var record in ev.Records)
{
var item = Convert(record.Dynamodb.NewImage);
context.Logger.Log(JsonConvert.SerializeObject(item));
}
}
private Item Convert(Dictionary<string, AttributeValue> attributeMap)
{
using (var context = new DynamoDBContext(_ddbClient))
{
var doc = Document.FromAttributeMap(attributeMap);
return context.FromDocument<Item>(doc, new DynamoDBOperationConfig { OverrideTableName = Environment.GetEnvironmentVariable("Table") });
}
}
}
Я записываю одну строку в секунду в таблицу запуска, и я вижу увеличение памяти примерно на 1 МБ за 3 вызова, что приводит к тому, что она некоторое время остается на 128 МБ, прежде чем регистрировать это:
START RequestId: 3e5acba1-36fd-4a3a-bf84-659c5488437b Version: $LATEST
END RequestId: 3e5acba1-36fd-4a3a-bf84-659c5488437b
REPORT RequestId: 3e5acba1-36fd-4a3a-bf84-659c5488437b Duration: 2293.32 ms Billed Duration: 2300 ms Memory Size: 128 MB Max Memory Used: 128 MB
RequestId: 3e5acba1-36fd-4a3a-bf84-659c5488437b Process exited before completing request
Я пробовал, и то же самое происходит с конфигурацией 256 МБ, и увеличение кажется линейным.
Я наблюдал аналогичную вещь с прокси-сервером API Gateway Lambda, который использует точку входа ApiGatewayProxyFunction
. В этом случае объем памяти увеличивается линейно, пока не достигнет предела, на котором она остается некоторое время, прежде чем ASP.NET, похоже, захочет очистить часть памяти:
Выделив три наблюдения:
1) высокая продолжительность вызова до и после сборки мусора
2) Максимальный объем используемой памяти упал с 128 МБ до 68 МБ.
3) Используется тот же поток журнала, поэтому экземпляр лямбда не отбрасывается
Я чувствую, что мы ничего не меняли и не добавляли новых пакетов. Возможно ли, что выпуск .NET Core 2.1.4 примерно в то же время на прошлой неделе мог вызвать это изменение в поведении?
Я также заметил повторяющийся узор. Когда я выполняю публикацию лямбда-выражения C #, а затем запускаю его и смотрю на потребление памяти, оно имеет значение, скажем, 74 МБ. Когда я просто переиздаю его снова, без изменений, без перекомпиляции, он будет работать с меньшим потреблением памяти, скажем, 66 МБ.
Я также вижу, что проекты, которые были в порядке, теперь превышают ограничение в 128 МБ, и процесс преждевременно завершается.
128 МБ едва ли могут запустить процесс, не говоря уже о его эффективном запуске. Недавно протестировав производительность холодного запуска для относительно простой реализации лямбда-прокси ASP.NET Core с использованием каждого доступного лимита памяти, я могу с уверенностью сказать, что комментаторы до меня ломают GC на протяжении всего жизненного цикла запроса и вызывают собственные проблемы с памятью.
Они будут наблюдать низкие холодные запуски, составляющие одну цифру, и время отклика от миллисекунды до миллисекунды, если они увеличат свой предел памяти до уровня, подходящего для потребностей в памяти их приложения, который минимизирует время запуска и выполнения без увеличения затрат на начать / выполнить.
У меня лямбда с памятью 3 ГБ. Но я тоже вижу ту же проблему. Вначале мой процесс занимает около 1,5 Гб, но постепенно продолжает увеличиваться. Иногда один и тот же ввод потребляет совершенно разные объемы памяти (что приводит к завершению работы). В моем коде нет ничего случайного, что привело бы к изменению потребления памяти.
@twopointzero 128 МБ было достаточно для лямбда-
Я согласен с тем, что 128 МБ недостаточно для лямбда-прокси ASP.NET, но при этом не используется Microsoft.AspNetCore.App
Это как-то связано с тем, что контейнер остается теплым даже после завершения функции. Вместо возврата "" ноль. просто запаникуйте, и это решит проблему. Я знаю, что это взлом, но так оно и есть, банкомат.
Кто-нибудь все еще сталкивается с этой проблемой в текущих версиях лямбды?
На этот вопрос не было ответа в течение 2 недель. Если вы хотите оставить эту проблему открытой, просто оставьте комментарий ниже, и автоматическое закрытие будет отменено.
Самый полезный комментарий
Я также заметил повторяющийся узор. Когда я выполняю публикацию лямбда-выражения C #, а затем запускаю его и смотрю на потребление памяти, оно имеет значение, скажем, 74 МБ. Когда я просто переиздаю его снова, без изменений, без перекомпиляции, он будет работать с меньшим потреблением памяти, скажем, 66 МБ.
Я также вижу, что проекты, которые были в порядке, теперь превышают ограничение в 128 МБ, и процесс преждевременно завершается.