Рубрики
Uncategorized

Deep Div: нахождение оптимальных распределений ресурсов для ваших функций лямбда

Как мы можем оптимизировать функции без сервера без опережения всего или рефакторинга нашего кода? В этой статье рассматривается подход, ориентированный на данные с данными, основанный на настройке мощности AWS Lambda и вводит ментальную структуру, чтобы подумать с точки зрения категорий рабочей нагрузки и шаблонов затрат / производительности. Помечено с AWS, программированием, безверенно, DEVOPS.

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

Вы также можете также достичь улучшений затрат и производительности, в отношении более традиционных вычислительных платформ.

В то же время лучшие практики, которые позволяют создавать хорошо архивационные серверы без прослушивания безвесочных приложений, развивались за последние пять лет. Многие методы появились такими, как избегать «монолитных» функций, оптимизируя зависимости времени выполнения, минимум кода, отфильтровывая неинтересные события, внешняя оркестровка и т. Д. Вы можете прочитать о многих из этих практик в AWS безсердный прикладной объектив Whitepaper (последнее обновление: DEC 2019).

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

Я имею в виду оптимизацию распределения ресурсов ваших функций лямбда.

Aws adambda распределение ресурсов (власть)

Вы можете выделить память для каждой отдельной функции Lambda, от 128 МБ до 3 ГБ памяти.

Прежде чем перестать читать, потому что «Кто заботится о использовании памяти?» Позвольте мне уточнить, что это гораздо более уместно поговорить о сила а не память. Потому что с большей памятью Также приходит более процессор, пропускная способность ввода/вывода и т. Д. Отказ

Так что для остальной части этой статьи я собираюсь называть это властью. Когда я говорю «512 МБ мощности», он будет соответствовать 512 МБ памяти для вашей функции лямбда.

Так почему же имеет значение?

Это имеет значение, потому что больше мощности означает, что ваша функция может работать быстрее. А с aws lambda, более быстрые казни означает более дешевые казни. Поскольку вы заряжаются через интервалы 100 мс, уменьшение времени выполнения часто снижает стоимость среднего выполнения.

Например, давайте предположим, что путем удвоения мощности вашей ламбда-функции от 128 МБ до 256 МБ вы можете уменьшить время выполнения от 310 мс до 160 мс. Таким образом, вы сократили аккредитный момент от 400 до 200 мс, достигая 49% повышения производительности для той же стоимости. Если вы снова удвоите питание до 512 МБ, вы можете уменьшить время выполнения еще дальше от 160 до 90 мс. Таким образом, вы снова сократили бюллерминированное время с 200 мс до 100 мс, достигая еще 44% повышения производительности. Всего, в частности, улучшение производительности 71%, не изменив единую строку кода, по той же стоимости.

Я понимаю, что эти цифры довольно трудно разобрать и визуализировать в вашем уме, поэтому вот график:

Синяя линия представляет наше среднее время выполнения: на 49% ниже при 256 МБ и на 71% ниже на 512 МБ. Поскольку стоимость исполнения лямбда пропорциональна распределению памяти, мы рассчитывали потратить больше. Но потому что мы прыгаем вниз до 200 мс и 100 мс соответственно, оранжевая линия (стоимость) постоянна.

Что, если мне не нужна вся эта память?

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

Как правило, заповедовая память означает, что вы тратите ресурсы. Но помните, здесь память означает питание 🚀

Наша функция может потребоваться только 50 МБ памяти, чтобы запустить правильно, и все же мы распределите 512 МБ, поэтому он будет работать быстрее для тех же денег. В других случаях ваша функция может стать быстрее и дешевле.

Отлично, но как я могу проверить это на практике?

Я спросил себя тот же самый вопрос в 2017 году. Однажды (27 марта, около 6 вечера Cest), я начал работать над автоматической настройкой процесса настройки мощности, так что моя команда И я, наконец, мог принять решения, ориентированные на данные, а не догадываться.

Познакомьтесь с AWS LAMBDA Power Turning: github.com/alexcasalboni/aws-lambda-power-tuning 🎉.

AWS Lambda Power Turning — это инструмент с открытым исходным кодом, который помогает вам визуализировать и тонкую настройку конфигурации питания функций Lambda.

Он работает в вашей учетной записи AWS — работает с помощью функций AWS PAP-функций — и поддерживает несколько стратегий оптимизации и использовать случаи использования.

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

Этот процесс возможен в разумное время, потому что для оптимизации есть только одно измерение. Сегодня существует 46 различных значений питания на выбор, и инструмент позволяет выбрать, какие значения вы хотите проверить. В большинстве случаев вы также можете позволить себе выполнять все выполнения параллельно, чтобы общий исполнение занимает всего несколько секунд — в зависимости от средней продолжительности вашей функции.

Вот то, что вам нужно, чтобы начать с настройкой Lambda Power Tuning:

  1. Разверните приложение Power Tuning через репозиторий приложений без сервеса (SAR) — Есть другие варианты развертывания документировано здесь (Например, lumigo cli или Lambda Power Tuner Ui Несомненно
  2. Запустите состояние станка через веб-консоль или API — вот где вы предоставляете свою функцию ARN и еще несколько вариантов
  3. Ждать результатов исполнения — Вы найдете оптимальную мощность здесь
  4. Вы также получите удобство URL визуализации — Вот как вы найдете сладость визуально, прежде чем вы полностью автоматизируете процесс

Как визуально находить сладкое место?

Давайте посмотрим на два примера ниже.

Красная кривая всегда (AVG) время выполнения, в то время как синяя кривая всегда (AVG) стоимость выполнения.

В обоих случаях я проверяю шесть общих значений питания: 128 МБ, 256 МБ, 512 МБ, 1 ГБ и т. Д.

Пример 1.

В этом примере я включающуюся настраивать долговечную и интенсивную функцию CPU. Он проходит через 35 секунд при 128 МБ и примерно через 3 секунды при 1,5 ГБ. Кривая затрат довольно плоская и уменьшается немного до 1,5 ГБ, затем увеличивается на 3 ГБ.

Оптимальное значение мощности составляет 1,5 ГБ, потому что это 11x быстрее, а на 14% дешевле по отношению к 128 МБ.

Пример 2.

Среднее время выполнения выходит с 2,4 секунды при 128 МБ до около 300 мс при 1 ГБ. В то же время стоимость остается именно то же самое. Поэтому мы бегаем 8x быстрее для той же стоимости.

Прежде чем мы продолжим с большим количеством примеров …

Помните : Возможно, нам не понадобится 1 ГБ или 1,5 ГБ памяти для запуска двух функций выше, но не имеет значения, потому что в обоих случаях мы получаем гораздо лучшую производительность для подобных (или даже ниже) стоимости.

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

  1. Две оси Y (скорость и стоимость) независимы друг от друга, поэтому точка, когда две кривые пересекаются друг друга, не обязательно является оптимальным значением.
  2. Не предполагайте, что значения непроверенных мощностей (например, 768 МБ) соответствуют интерполированному значению кривой — тестирование дополнительных значений мощности в между ними может выявить неожиданные шаблоны.

Как выглядит государственный вход/выход/выход?

Вот минимальный вход:

{
    "lambdaARN": "your-lambda-function-arn",
    "num": 50
}

Но я очень поощряю вас проверить некоторые другие варианты ввода (полную документацию здесь ):

{
    "lambdaARN": "your-lambda-function-arn",
    "num": 50,
    "parallelInvocation": true,
    "payload": {"your": "payload"},
    "powerValues": [128, 256, 512, 1024, 1536, 3008],
    "strategy": "speed",
    "dryRun": false
}

Для особых случаев использования — например, если вам необходимо функционировать настроиться на настройку по боковым эффектам или различной полезной нагрузке — вы можете предоставить весовые полезные нагрузки или функции Pre/Post-обработки.

Вот что будет выглядеть вывод (полная документация здесь ):

{
  "results": {
    "power": "512",
    "cost": 0.0000002083,
    "duration": 2.906,
    "stateMachine": {
      "executionCost": 0.00045,
      "lambdaCost": 0.0005252,
      "visualization": "https://lambda-power-tuning.show/#"
    }
  }
}

сила , Стоимость и Продолжительность представляют оптимальное значение мощности и соответствующие средние затраты и время выполнения.

Статумахин Содержит подробную информацию о сам исполнение состояния машины, такого как стоимость, связанные с функциями шага и лямбда. Эта информация особенно полезна, если вы хотите отслеживать расходы на оптимизацию без сюрпризов — хотя, как правило, мы говорим около 0,001 доллара за весь исполнение (за исключением дополнительных затрат, что ваша функция может генерировать вызововные услуги).

Последнее, но не менее важное, вы найдете URL-адрес визуализации (под лямбда-power-tuning.show), Статический сайт с открытым исходным кодом Хозяин AWS усиливает консоль. Если вы не посетите этот URL, ничего не происходит. Но даже когда вы посещаете URL, нет абсолютно никаких данных общих данных на любой внешний сервер или услугу. Упомянутый выше содержит только необработанные числа, необходимые для визуализации клиента, без какой-либо дополнительной информации о вашем идентификаторе учетной записи, имени функции или параметрах настройки. Вы также можете создать свой сайт пользовательских визуализации и предоставить его в развертывании времени в качестве параметра CloudFormation.

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

В зависимости от того, что делает ваша функция, вы найдете совершенно разные шаблоны затрат/производительности. Со временем вы сможете выявить с первого взгляда, какие функции могут принести пользу большему из Power-Tuning, и что вряд ли принесет пользу.

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

Стоимость/производительность

Я подготовил коротколист из 6 узоров, которые вы можете столкнуться с вашими функциями.

Давайте посмотрим на некоторые образцы функций лямбда и их соответствующие результаты настройки мощности. Если вы хотите развернуть их все, вы найдете Образец кода и шаблон Сэма здесь Отказ

1) NO-OP (манипуляция тривиальными данными)

Когда я говорю функции NO-OP, я имею в виду функции, которые делают очень мало, и они чаще встречаются, чем вы думаете. Это довольно часто бывает, что функция лямбда вызывается другими сервисами для настройки их поведения, и все, что вам нужно, это некоторые тривиальные манипулирования данными. Может быть, пара Если S или простое преобразование формата — без вызовов API или длительные задачи.

Вот простой пример:

def lambda_handler(event, context):
    print("NOOP")
    response = 'OK'
    if event['something'] == 'KO':
        response = 'KO'
    return {
        'output': response
    }

Такая функция никогда не превысит 100 мс времени исполнения. Поэтому мы ожидаем, что его средняя стоимость увеличивается линейно с властью.

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Несмотря на то, что нет способа сделать никаких функций без OP дешевле, иногда вы можете заставить их работать 3-5x быстрее. В этом случае, возможно, стоит рассматривать 256 МБ мощности, поэтому он проходит менее чем за 2 мс вместо 5 мс. Если ваша функция делает что-то более простое Если Вы можете увидеть более значительную падение — например, от 30 мс до 10 мс.

Есть ли смысл платить немного больше, чтобы пробежать 20 мс быстрее? По-разному:)

Если ваша система состоит из 5-10 микроэнергии, которые необходимо разговаривать друг с другом, брить от 20 мс от каждого микросима, может ускорить общий ответ API на воспринимаемой суммой, что приводит к лучшему UX.

С другой стороны, если эта функция полностью асинхронана, и не влияет на опыт вашего конечного пользователя, вы, вероятно, хотите сделать его как можно дешевле (128 МБ).

2) CPU-связанный (Numpy)

Эта функция требует numpy , очень распространенная библиотека Python для научных вычислений — которая доступна как официальный Лямбда слой Отказ

import numpy as np

# make this execution reproducible
np.random.seed(10)

def lambda_handler(event, context):
    # create a random matrix (1500x1500)
    matrix = np.random.rand(1500, 1500)

    # invert it (this is CPU-intensive!)
    inverted_matrix = np.linalg.inv(matrix)

    print(inverted_matrix)
    return {'OK': 'OK'}

Функция создает случайную матрицу (1500 строк, 1500 столбцов), а затем отвлекает его.

Таким образом, мы говорим о очень интенсивном процессе процессора, который требует почти 10 секунд до 128 МБ мощности.

Хорошая новость в том, что она будет работать Многое быстрее с большим количеством памяти. Насколько быстрее? Проверьте таблицу ниже.

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Да, он будет работать почти 21 раз быстрее (2100%) с 3 ГБ мощности. И это для увеличения затрат всего 23%.

Позвольте мне повторить это: мы можем запустить эту функцию в 450 мс вместо 10 секунд, если мы довольны оплатой на 23% больше.

Если вы не можете позволить себе увеличение стоимости 23%, вы все еще можете пройти 2 раза быстрее для увеличения затрат на 1% (256 МБ). Или 4x быстрее для увеличения стоимости 5% (512 МБ). Или 7x быстрее для повышения стоимости 9% (1 ГБ).

Стоит ли оно того? По-разному:)

Если вам нужно разоблачить это как синхронный API, вы, вероятно, хотите, чтобы он пробел менее чем за секунду.

Если это просто часть некоторого асинхронного ETL или ML тренировки, вы можете быть полностью хорошо с 5 или 10 секунд.

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

Примечание : числа выше не учитывают холодные запуска. По умолчанию Lambda Power Turning игнорирует холодные казни, поэтому все эти средние не предвзяты. Это позволяет рассуждать о крупнейшем большинстве (теплых) казнях.

3) CPU-связанные (простые номера)

Давайте рассмотрим еще одну длинную функцию. Эта функция также использует Numpy для вычисления первых 1М простых чисел для 1K раз в ряд.

import numpy as np

def lambda_handler(event, context):
    # do the same thing 1k times in a row
    for i in range(1000):
        # compute the first 1M prime numbers
        primes = compute_primes_up_to(1000000)
    return {'OK': 'OK'}

def compute_primes_up_to(n):
    # this is the fastest single-threaded algorithm I could find =)
    # from https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    sieve = np.ones(int(n/3) + (n%6==2), dtype=np.bool)
    sieve[0] = False
    for i in range(int(int(n**0.5)/3+1)):
        if sieve[i]:
            k=3*i+1|1
            sieve[   int((k*k)/3)      ::2*k] = False
            sieve[int((k*k+4*k-2*k*(i&1))/3)::2*k] = False
    return np.r_[2,3,((3*np.nonzero(sieve)[0]+1)|1)]

Функция занимает почти 35 секунд, чтобы работать только с 128 МБ мощности.

Но хорошие новости снова! Мы можем заставить его запустить Многое Многое быстрее с большим количеством памяти. Насколько быстрее? Проверьте таблицу ниже.

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Да, он будет работать более 14x быстрее (1400%) с 1,5 ГБ мощности. И это со стоимостью Уменьшить 13,9%.

Позвольте мне повторить это: мы можем запустить эту функцию за 2 секунды вместо 35 секунд, в то же время мы сделаем это дешевле запустить.

Мы могли бы сделать его еще быстрее (17x быстрее вместо 14x) с 3 ГБ мощности, но, к сожалению, алгоритм, который я нашел в Stackoverflow, не может использовать достаточно колодец мультирезы (вы получаете два ядра выше 1,8 ГБ мощности), поэтому мы закончимся Расходы на 43% больше.

Это может иметь смысл в некоторых краевых случаях, но я все равно рекомендую придерживаться 1,5 ГБ.

Пока не…

Если не было еще более оптимальное значение мощности между 1,5 ГБ и 3 ГБ. Мы не тестируем все возможные значения мощности. Мы пытаемся только 6 из них, только потому, что их легко запомнить.

Что произойдет, если мы проверим все возможные значения? Мы знаем, что наш лучший вариант на сегодняшний день 1,5 ГБ, но мы можем найти что-то еще лучше (быстрее и дешевле), если мы увеличиваем гранулярность вокруг него.

{
    "lambdaARN": "your-lambda-function-arn",
    ....
    "powerValues": "ALL",
    ....
}

Вот что произойдет, если вы проверяете все возможные значения:

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Оказывается (глобальная) сладкое пятно составляет 1,8 ГБ — что позволяет нам работать 16x быстрее и на 12,5% дешевле.

Или мы могли бы выбрать 2112 МБ, который является 17x быстрее для той же стоимости 128 МБ (еще 20 мс медленнее, чем 3 ГБ, но для лучшего затрата AVG).

Помните : Когда вы видите увеличение или уменьшение тренда (стоимость или скорость), вероятно, он будет продолжаться некоторое время и для значений питания, которые вы не тестируете. Как правило, я бы предположил увеличить вашу настройку гранулярности, чтобы найти все глобально оптимальные значения.

4) Сетевой (3-й партийный API)

Давайте перейдем и поговорим о первом сетевом примере. Эта функция взаимодействует с внешним API, API, который публично и не размещен на AWS: API звездных войн Отказ

import json
import urllib.request

# this is my (public) third-party API
URL = 'https://swapi.dev/api/people/?format=json'

def lambda_handler(event, context):
    # prepare request
    req = urllib.request.Request(URL)

    # fetch and parse JSON
    with urllib.request.urlopen(req) as response:
        json_response = json.loads(response.read())

    # extract value from JSON response
    count = json_response['count']

    return {
        'count': count,
    }

Функция выполняет запрос на получение, чтобы получить количество символов, доступных через API звездных войн (мы могли бы использовать официальную библиотеку Swapi-Python для интерфейса более высокого уровня, но это не было точкой).

Как мы могли бы предсказать, производительность этого внешнего API не влияет на мощность нашей функции лямбда. Несмотря на то, что дополнительная мощность означает больше ввода/вывода Пропускная способность, мы выбираем только 5 КБ данных, поэтому большая часть времени выполнения проводится в ожидании ответа, а не передающих данные.

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Красная кривая выше довольно плоская, а синяя кривая всегда увеличивается, что означает, что мы не можем сделать много, чтобы ускорить эту функцию или сделать ее дешевле.

Мы могли бы сэкономить 50-100 миллисекунд с дополнительной мощностью, но обычно этого недостаточно, чтобы уменьшить стоимость или сохранить ее постоянным.

В этом случае мы можем запустить немного быстрее с 256 МБ или 512 МБ мощности — до 16% быстрее, если мы рады тройной стоимостью среднего исполнения.

Стоит ли оно того? По-разному.

Если ваш ежемесячный законопроект Lambda — это что-то вроде 20 долларов, как вы относитесь к снижению его до 60 долларов и запустите функцию, обращенную к клиенту на 15-20% быстрее? Я бы подумал об этом.

Если это не API, обращенная к клиентам, я бы придерживался 128 МБ и сделать его как можно дешевле. И могут быть другие факторы в пьесе, когда дело доходит до сторонних API. Например, вам может потребоваться соблюдать какой-то ограничение скорости; Если вы выполняете партии API, вызовы в серии, функция, которая работает медленнее, может быть хорошей вещью.

5) Сетевой связанный (3x Dynamodb запросы)

Этот шаблон довольно распространен. Каждый раз, когда наша функция использует AWS SDK, чтобы вызвать несколько услуг AWS и координировать некоторую бизнес-логику. Мы все еще говорим о связанной с сетевой функции, но показывает другой шаблон. В этом случае мы выполняем три Dynamodb: GetITem Запросы в последовательности, но тот же шаблон держит с другими услугами, такими как SNS или SQS.

import boto3

dynamodb = boto3.client('dynamodb')

def lambda_handler(event, context):

    # three identical queries in series
    # this is just an example
    # usually you'd have 3 different queries :)
    for i in range(3):
        response = dynamodb.get_item(
            TableName='my-table',
            Key={
                'id': {
                    'S': 'test-id',
                }
            }
        )
        message = response['Item']['message']

    return {
        'message': message,
    }

Мы говорим о услугах AWS, вполне вероятно, работающих в том же регионе AWS. Таким образом, наши вызовы API вообще не покинут центр обработки данных.

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

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Функция проходит около 350 мс при 128 МБ, 160 мс при 256 МБ и 45 мс при 512 МБ.

На практике каждый раз, когда мы удваиваем свою власть, мы также вдвое время вдвое время, что привело к постоянной цене до 512 МБ.

После этого мы не можем сделать это дешевле, поэтому 512 МБ — наше сладкое место.

Но мы могли бы получить дополнительные 40% улучшения производительности (время выполнения 28 мс) на 3 ГБ, если мы готовы заплатить 6 раза больше. Как обычно, этот компромисс зависит от вас, и это зависит от ваших деловых приоритетов. Мое предложение состоит в том, чтобы принять мышление, ориентированное на данные, и оцените ваши варианты в случае.

6) Сетевой связанный (S3 скачать — 150 МБ)

Это не очень распространенный шаблон, так как загрузка больших объектов от S3 не является типичным требованием. Но иногда вам действительно нужно скачать большое изображение/видео или модель обучения машины, либо потому, что она не поместится в вашем пакете развертывания, либо потому, что вы получаете ссылку на него во входном событии для обработки.

import os
import boto3

s3 = boto3.client('s3')

# from the Amazon Customer Reviews Dataset
# https://s3.amazonaws.com/amazon-reviews-pds/readme.html
BUCKET = 'amazon-reviews-pds'
KEY = 'tsv/amazon_reviews_us_Watches_v1_00.tsv.gz'
LOCAL_FILE = '/tmp/test.gz'

def lambda_handler(event, context):
    # download 150MB (single thread)
    s3.download_file(BUCKET, KEY, LOCAL_FILE)
    bytes = os.stat(LOCAL_FILE).st_size

    total = bytes / 1024 / 1024
    unit = 'MB'
    if total > 1024:
        total = total / 1024
        unit = 'GB'

    # print "Downloaded 150MB"
    print("Downloaded %s%s" % (round(total, 2), unit))
    return {'OK': 'OK'}

Поскольку мы пытаемся хранить много данных в памяти, мы не будем тестировать более низкие конфигурации памяти, такие как 128 МБ и 256 МБ.

На первый взгляд, шаблон затрат/производительности выглядит очень похоже на нашему примеру для сетевого типа: дополнительная мощность, похоже, не улучшает производительность. Время выполнения довольно ровно, около 5 секунд, поэтому стоимость всегда увеличивается пропорционально выделенной мощности (на 3 ГБ почти 5 раза дороже в среднем).

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

С этой таблицы похоже, что мы не можем сделать многое, чтобы улучшить стоимость и производительность. Если мы пойдем на 1 ГБ власти, мы пройдем на 23% быстрее для увеличения затрат на 55%.

Можем ли мы сделать лучше, чем это?

Хорошая новость: такая рабочая нагрузка будет работать намного быстрее с очень простым изменением кода:

# download 150MB from S3 with 10 threads
transfer_config = boto3.s3.transfer.TransferConfig(max_concurrency=10)
s3.download_file(BUCKET, KEY, LOCAL_FILE, Config=transfer_config)

С новым кодом выше, мы просто предоставляем пользовательские TransferConfig объект для включения мультипоток.

Теперь весь процесс будет проходить намного быстрее путем параллелизма загрузки файла с несколькими потоками, тем более что мы получаем два ядра выше 1,8 ГБ мощности.

Вот новая картина стоимости/производительности:

(Нажмите на изображение, чтобы открыть интерактивную визуализацию)

Не только шаблон очень отличается, но абсолютные числа тоже намного лучше. Мы проводим через 4,5 секунды при минимальной мощности (что уже на 10% быстрее, чем то, что мы могли сделать до максимальной мощности). Но тогда становится еще лучше: мы бегите еще на 40% быстрее на уровне 1 ГБ для увеличения затрат на 23%.

Удивительно, удивительно мы бегаем почти 4 ранее (1,1 секунды) на 3 ГБ мощности. И это для той же стоимости (+ 5%) относительно однопоточного кода на 512 МБ.

Позвольте мне перефразировать это: добавление одной строки кода позволило нам запустить 4 раза быстрее для ту же стоимости.

И если производительность не имела значения в этом случае, то же изменение позволит нам сделать эту функцию на 45% быстрее И 47% дешевле с минимальной мощностью (512 МБ).

Я считаю, что это также интересный пример, где выбирает конкретный язык программирования, может привести к лучшему характеристику без использования дополнительных библиотек или зависимостей (Примечание: вы можете достичь то же самое в Java с утилитой или в Node.js S3 Управляемый модуль скачать ).

Выводы

Мы глубоко глубоко в пользу Power-Tuning для AWS Lambda: это помогает вам оптимизировать свои функции Lambda для производительности или стоимости. Иногда оба.

Помните, что память означает мощность, и нет такой вещи, как воспоминания о превзошении памяти с aws lambda. Всегда существует оптимальное значение, которое представляет наилучшее компромисс между временем исполнения и стоимостью выполнения.

Я также представил психические рамки, чтобы подумать с точки зрения категорий рабочей нагрузки и шаблонов затрат/производительности, поэтому вы сможете предсказать, какой шаблон применяется к вашей функции, когда вы их кодируете. Это поможет вам приоритетировать, какие функции могут стоить оптимизировать и настройку Power-Tuning.

AWS LAMBDA Power Tuning — это открытый источник и очень дешево для бега. Он предоставит информацию и визуализацию, вам необходимо принять решение, ориентированное на данные с данными.

Спасибо за чтение, и дайте мне знать, если вы найдете новые захватывающие узоры при настройке ваших функций.

Оригинал: «https://dev.to/aws/deep-dive-finding-the-optimal-resources-allocation-for-your-lambda-functions-35a6»