Реализация систем, управляемых событиями с помощью потоков AWS Lambda и DynamoDB

Реализация систем, управляемых событиями с помощью потоков AWS Lambda и DynamoDB

22 июня 2025 г.

По мере того, как облачные архитектуры становятся нормой, разработчики все чаще обращаются к дизайну, управляемую событиями, для создания масштабируемых и слабо связанных приложений. Один мощный шаблон в этом пространстве используетAWS Lambdaв сочетании сDynamoDB потокиПолем Эта настройка позволяет в реальном времени без серверов ответов на изменения данных без опроса или ручного управления инфраструктурой.

В этой статье объясняется, как реализовать систему, управляемую событиями, используя потоки DynamoDB и AWS Lambda. Пошаговый пример реализации с использованием LocalStack также включен для демонстрации того, как архитектура может быть смоделирована локально для целей разработки и тестирования.

Зачем идти на мероприятии?

Архитектуры, управляемые событиями, предлагают несколько ключевых преимуществ:

  • Масштабируемость:Параллельное выполнение и упругое вычисление
  • Свободная связь:Компоненты общаются через события, а не обдуманные интеграции
  • Отзывчивость:Почти в реальном времени обработка изменений

В сочетании с серверами, такими как AWS Lambda, эти преимущества переводятся в системы, которые являются экономически эффективными, устойчивыми и простыми в обслуживании.

Системная архитектура

Вот основная идея:

  1. Таблица DynamoDB настроена с включенными потоками.
  2. Когда строка вставлена, обновлена ​​или удалена, генерируется запись потока.
  3. AWS Lambda вызывается автоматически с партией этих записей.
  4. Lambda обрабатывает данные и запускает нижестоящие рабочие процессы (например, обмен сообщениями, аналитика, обновления).

Общий вариант использования

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

  • Таблица DynamoDB обновляется.
  • Функция Lambda запускается через поток.
  • Lambda проверяет обновление, регистрирует его и выдвигает уведомления.

Он полностью автоматизирован и не требует сервера для обслуживания.

Шаги внедрения

Шаг 1: Включить потоки DynamoDB

Включите потоки для вашей таблицы с соответствующим типом представления:

"StreamSpecification": {

  "StreamEnabled": true,

  "StreamViewType": "NEW_AND_OLD_IMAGES"

}

Шаг 2: Подключите лямбду к потоку

Используя консоль AWS или инфраструктуру в качестве кода (например, SAM, CDK), создайте отображение источника событий между потоком ARN и вашей Lambda.


Шаг 3: Напишите обработчик Lambda

Вот базовый пример Node.js:

exports.handler = async (event) => {

  for (const record of event.Records) {

    const newImage = AWS.DynamoDB.Converter.unmarshall(record.dynamodb.NewImage);

    console.log('Processing update:', newImage);

    // Run your business logic

  }

};


Шаг 4: Добавьте устойчивость

  • Повторение повторения: Настройте DLQS (Dead Letters Ofeues) для неудачных сообщений.
  • Идемпотентность: Логика дизайна, чтобы безопасно обрабатывать дублирующие поставки.
  • Мониторинг: Используйте CloudWatch и рентгеновский рост, чтобы отслеживать и вызовы журнала.

Оперативное понимание и лучшие практики

  • Используйте подготовленную параллелизм для чувствительных к задержке Lambdas.
  • Настройка размера партии и параллелизм.
  • Используйте журналы CloudWatch, метрики и рентген.
  • Сохраняйте выполнение функции за несколько секунд.
  • Потоки DynamoDB не гарантируют глобальное упорядочение событий в осколках. Системы должны быть разработаны, чтобы переносить и правильно обрабатывать обработку событий вне порядка.
  • Потоковые записи сохраняются максимум 24 часа. Потребители вниз по течению должны быстро обрабатывать события, чтобы избежать потери данных.
  • Убедитесь, что IAM Роли и политики тесно подходят. Чрезвычайные конфигурации могут представлять риски безопасности, особенно когда Lambdas взаимодействуют с несколькими службами AWS.


Когда этот шаблон подходит

  • Вы должны ответить на изменения данных почти в режиме реального времени без опроса.
  • Рабочая нагрузка без хранения и очень масштабируемой, что делает ее идеальной для выполнения без сервера.
  • Решение должно легко интегрироваться с другими службами AWS, такими как SNS, SQS или функции Step.


Когда рассмотреть другие подходы

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

Доказательство концепции с использованием LocalStack

Предварительные условия

  • Docker - https://www.docker.com
  • AWS CLI - https://aws.amazon.com/cli/
  • Awslocal CLI - PIP установка AwsCli -Local
  • Python 3.9+

Шаг 1: Docker Compose Setup

Create a docker-compose.yml file in your project root:

version: '3.8'

services:

  localstack:

    image: localstack/localstack

    ports:

      - "4566:4566"  # LocalStack Gateway

      - "4510-4559:4510-4559"  # External services

    environment:

      - SERVICES=lambda,dynamodb

      - DEFAULT_REGION=us-east-1

      - DATA_DIR=/tmp/localstack/data

    volumes:

      - /var/run/docker.sock:/var/run/docker.sock

      - ./lambda-localstack-project:/lambda-localstack-project

    networks:

      - localstack-network

networks:

  localstack-network:

    driver: bridge

Затем разверните LocalStack:

docker-compose up -d


Шаг 2: Создайте таблицу DynamoDB с включенными потоками

awslocal dynamodb create-table \

  --table-name UserProfileTable \

  --attribute-definitions AttributeName=id,AttributeType=S \

  --key-schema AttributeName=id,KeyType=HASH \

  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \

  --billing-mode PAY_PER_REQUEST

Шаг 3: Напишите обработчик Lambda

Создайте файл с названиемhandler.py:

import json

def lambda_handler(event, context):

    """

    Lambda function to process DynamoDB stream events and print them.

    """

    print("Received event:")

    print(json.dumps(event, indent=2))



    for record in event.get('Records', []):

        print(f"Event ID: {record.get('eventID')}")

        print(f"Event Name: {record.get('eventName')}")

        print(f"DynamoDB Record: {json.dumps(record.get('dynamodb'), indent=2)}")

    return {

        'statusCode': 200,

        'body': 'Event processed successfully'

    }

Шаг 4: Упакуйте функцию Lambda

zip -r my-lambda-function.zip handler.py


Шаг 5: Создайте функцию лямбды

awslocal lambda create-function \

  --function-name my-lambda-function \

  --runtime python3.9 \

  --role arn:aws:iam::000000000000:role/execution_role \

  --handler handler.lambda_handler \

  --zip-file fileb://function.zip \

  --timeout 30

Шаг 6: Получите поток ARN

awslocal dynamodb describe-table \

  --table-name UserProfileTable \

  --query "Table.LatestStreamArn" \

  --output text

Шаг 7: Создать картирование источника событий

awslocal lambda create-event-source-mapping \

  --function-name my-lambda-function \

  --event-source <stream_arn> \

  --batch-size 1 \

  --starting-position TRIM_HORIZON

Заменить `<stream_arn>`С значением, возвращенным с предыдущего шага.


Шаг 8: Добавьте запись в таблицу

awslocal dynamodb put-item \

  --table-name UserProfileTable \

  --item '{"id": {"S": "123"}, "name": {"S": "John Doe"}}'

Шаг 9: Проверьте журналы Docker, чтобы увидеть сообщение, напечатанное функцией Lambda

Это должно быть что -то вроде ниже:

Полученное мероприятие:

{

  "Records": [

    {

      "eventID": "98fba2f7",

      "eventName": "INSERT",

      "dynamodb": {

        "ApproximateCreationDateTime": 1749085375.0,

        "Keys": {

          "id": {

            "S": "123"

          }

        },

        "NewImage": {

          "id": {

            "S": "123"

          },

          "name": {

            "S": "John Doe"

          }

        },

        "SequenceNumber": "49663951772781148680876496028644551281859231867278983170",

        "SizeBytes": 42,

        "StreamViewType": "NEW_AND_OLD_IMAGES"

      },

      "eventSourceARN": "arn:aws:dynamodb:us-east-1:000000000000:table/UserProfileTable/stream/2025-06-05T01:00:30.711",

      "eventSource": "aws:dynamodb",

      "awsRegion": "us-east-1",

      "eventVersion": "1.1"

    }

  ]

}

Event ID: 98fba2f7

Event Name: INSERT

DynamoDB Record: {

  "ApproximateCreationDateTime": 1749085375.0,

  "Keys": {

    "id": {

      "S": "123"

    }

  },

  "NewImage": {

    "id": {

      "S": "123"

    },

    "name": {

      "S": "John Doe"

    }

  },

  "SequenceNumber": "49663951772781148680876496028644551281859231867278983170",

  "SizeBytes": 42,

  "StreamViewType": "NEW_AND_OLD_IMAGES"

}

Краткое содержание

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

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

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

С этим фундаментом вы хорошо полагаете, чтобы расширить архитектуру, интегрируя дополнительные услуги AWS, такие как SNS, SQS, Eventbridge или Step Functs, чтобы поддержать более сложные рабочие процессы и масштабируемость корпоративного класса.

Заключение

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

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

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

Дальнейшее чтение

  • DynamoDB Streams -https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/streams.html
  • AWS Lambda Source Source Mappings -https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapp.html
  • Строительство Idempotent Lambdas -https://aws.amazon.com/blogs/compute/building-idempotent-applications-on-aws/


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE