Исправление антишаблона производительности с помощью DynamoDB (и извлеченные уроки)

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

Что такое DynamoDB?

DynamoDB — это полностью управляемая база данных NoSQL от Amazon Web Services.

В отличие от реляционных баз данных, которые хранят свои данные в структурированных строках и столбцах, данные Dynamo хранятся в парах ключ-значение. Это означает, что данные, которые вы храните в Dynamo, являются неструктурированными по сравнению с теми, которые вы обычно видите в реляционной базе данных. Единственная схема, которую вы должны определить, — это ключи вашей таблицы: ключ раздела и ключ сортировки. Помимо этого, ваши данные могут быть бессхемными (хотя ваше приложение все равно должно знать, как с ними работать).

Моя ошибка

В моем проекте я использую Python и обращаюсь к Dynamo через библиотеку boto3. Это работает на AWS Lambda. В моем коде есть модель данных, collection, для которой мне нужно было выполнить основные операции CRUD (Create, Read, Update, Delete).

Мой код выглядел примерно так:

Вы видите мою ошибку?

При каждой операции с базой данных я заново инициализировал ресурс boto3 и таблицу Dynamo.

Это было легко сделать (особенно с GitHub Copilot, который, по сути, писал эти функции за меня), и я не задумывался об этом в то время. Однако, просматривая код, мой жених, Майлз Лоффлер, указал мне на то, что это фактически анти-паттерн при работе с клиентами boto3, особенно на Lambda.

Примечание: Хотя я столкнулся с этим анти-паттерном при работе с Dynamo, из-за природы операций CRUD — вы можете столкнуться с ним в любой момент, когда вы повторно инициализируете один и тот же ресурс boto3 снова и снова!

Как я это исправил

К счастью, это было легко исправить, и исправление сделало мой код в целом лучше!

Я создал новый файл utilities для обработки соединений с базой данных и добавил следующие функции:

Затем я рефакторизовал свои функции CRUD, чтобы просто использовать get_dynamo_table вместо прямого использования boto3.

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

Что это дало?

Это внесло четыре основных отличия в мой код:

Производительность

Это, очевидно, самое важное!

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

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

А вот трассировка тех же двух действий (удаление и запрос) через приложение с применением этого изменения:

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

Чистота

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

Тестируемость

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

Возможность повторного использования

Новые функции в utils.db вообще не заботятся об имени таблицы — оно извлекается функцией get_dynamo_table_name в настройках. По мере роста моего проекта этот код можно будет повторно использовать в других Lambdas, которые могут использовать различные таблицы Dynamo.


Как я уже упоминал выше, я довольно новичок в использовании DynamoDB от Amazon — и я все еще учусь!

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