Бенчмаркинг .NET на AWS Lambda

Моей мотивацией для проведения бенчмарков всех вариантов компилятора, развертывания и времени выполнения было удовлетворение моего любопытства. Я видел различные записи в блогах, в которых рекомендовались одни настройки над другими, но они никогда не давали обоснования.

К сожалению, мы не можем использовать выдающийся инструмент BenchmarkDotNet с AWS Lambda. Поэтому я создал бенчмарк, чтобы собрать данные для всех вариантов развертывания и, надеюсь, определить «оптимальную» комбинацию.

Как упоминалось в первой статье этой серии, есть два разных случая, для которых мы можем оптимизировать: «Минимизация продолжительности холодного запуска» или «Минимизация эксплуатационных расходов». Теперь, когда основа заложена, мы можем формально описать, что это значит.

Оптимальные стратегии

  1. Чтобы минимизировать продолжительность холодного запуска, нам нужно минимизировать фазу INIT и первую фазу INVOKE. Оптимальная конфигурация обеспечивает наименьшую продолжительность обработки запроса, измеряемую в миллисекундах (мс). Для этого измерения мы полагаемся на данные, сообщаемые AWS Lambda в журналах. Это те же данные, которые используются для выставления счетов, и они являются наиболее точными из всех, к которым мы имеем доступ.

  2. Чтобы минимизировать стоимость выполнения, нам нужно минимизировать сумму всех фаз INVOKE (холодной и теплой), принимая во внимание конфигурацию памяти Lambda и архитектуру процессора. Оптимальная конфигурация дает наименьшую стоимость выполнения для 1 холодного запуска с последующими 100 теплыми вызовами. Выполнение AWS Lambe имеет чрезвычайно низкую удельную стоимость. Чтобы сделать число более интуитивно понятным, я решил представить стоимость выполнения в миллионных долях доллара, или микродолларах (µ$).

Варианты бенчмарков

Чтобы не оставить ни одного камня без внимания, система бенчмаркинга выполняет все возможные варианты следующих опций.

  • Многоуровневая компиляция: Вкл. и Выкл.
  • ReadyToRun: Вкл. и Выкл.
  • Память лямбды: 128 МБ, 256 МБ, 512 МБ, 1024 МБ, 1769 МБ и 5120 МБ.
  • Архитектура процессора: x86-64 и ARM64
  • Время выполнения .NET: .NET Core 3.1 и .NET 6
  • Pre-JIT .NET: Вкл. и Выкл.

Эти опции создают 192 уникальные комбинации, которые подвергаются бенчмаркингу.

Подход к бенчмаркингу

Лямбда-функция для каждого проекта измеряется при выполнении 100 холодных запусков. За каждым холодным запуском следует 100 теплых вызовов. Затем результаты усредняются.

Я обсуждал возможность использования медианы или перцентиля вместо среднего значения. Сложность заключается в том, чтобы объединить эти значения. Например, суммирование значения p99 для фазы INIT с p99 для первой фазы INVOKE кажется неправильным. Кроме того, в реальной жизни случаются выбросы. Я надеюсь, что 100 холодных и теплых вызовов достаточно, чтобы справедливо представить то, что следует ожидать в реальных ситуациях.

Тем не менее, необработанные измерения были записаны для каждого бенчмарка. Таким образом, можно проводить альтернативные анализы без необходимости повторного сбора данных.

Эталонные проекты

Мой интерес заключался в изучении того, как опции влияют на вычислительный аспект функций Lambda. Поэтому я выбрал только те проекты, которые не выполняют операций ввода-вывода.

Минимальная базовая линия

Проект Minimal устанавливает базовый уровень для всех проектов. Он не содержит бизнес-логики и включает только необходимые библиотеки.

Сериализаторы JSON

Сериализация JSON необходима практически для всех функций Lambda. В .NET 6 существует 3 распространенных подхода к решению этой задачи.

  1. NewtonsoftJson: использование Newtonsoft JSON.NET

  2. SourceGeneratorJson: использование генераторов исходников .NET 6 для разбора JSON

  3. SystemTextJson: использование System.Text.Json

AWS SDK

Большинство функций Lambda будут взаимодействовать с другими сервисами AWS через AWS SDK. Проект AwsSdk используется для оценки затрат на инициализацию SDK.

Утверждения верхнего уровня

Начиная с .NET 6, функции Lambda могут использовать утверждения верхнего уровня вместо объявления класса. Как это влияет на производительность?

  1. AwsNewtonsoftJson: использование AWS .NET SDK и Newtonsoft JSON.NET

  2. SampleAwsNewtonsoftTopLevel: использование AWS .NET SDK, Newtonsoft JSON.NET и утверждений верхнего уровня

  3. SampleAwsSystemTextJsonTopLevel: использование AWS .NET SDK, System.Text.Json и утверждений верхнего уровня.

Минимальный API

Также новым в .NET 6 является новый подход к выражению маршрутов ASP.NET с помощью утверждений верхнего уровня. Этот пример взят из сообщения в блоге об анонсе поддержки .NET 6 в AWS Lambda.

  1. SampleMinimalApi: использование ASP.NET Core Minimal API

Исследователь бенчмарков

Результаты бенчмарков были собраны в интерактивную таблицу Google. Не стесняйтесь исследовать данные как угодно и делать собственные выводы. Любые замечания по улучшению анализа или визуализации приветствуются.

Что дальше

Наконец, мы можем погрузиться в результаты и посмотреть, какие новые выводы мы можем сделать! Первое — это измерение базовой производительности. Хотя это не критично для производственного кода, это дает нам основу для работы.

Оцените статью
devanswers.ru
Добавить комментарий