Стратегии ключевых разделов DynamoDB для SaaS

Стратегии ключевых разделов DynamoDB для SaaS

24 марта 2022 г.

[Amazon DynamoDB] (https://aws.amazon.com/dynamodb/) — это полностью управляемая служба базы данных NoSQL, созданная для обеспечения масштабируемости и высокой производительности. Это одна из самых популярных баз данных, используемых в SaaS-компаниях, включая [Courier] (https://www.courier.com/). Мы выбрали DynamoDB по тем же причинам, что и все остальные: автомасштабирование, низкая стоимость, нулевое время простоя. Однако при масштабировании DynamoDB может вызвать серьезные проблемы с производительностью.


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


Наивный ключ раздела и проблема шумных соседей


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


Чтобы понять почему, нам нужно взглянуть на то, как хранится элемент DynamoDB и какие жесткие ограничения налагает служба. Во-первых, важно помнить, что DynamoDB хранит ваши данные в нескольких разделах. Каждый элемент в вашей таблице DynamoDB будет содержать первичный ключ, который будет включать в себя ключ раздела. Этот ключ раздела определяет раздел, в котором будет находиться этот элемент. Наконец, мы должны отметить, что каждый раздел может поддерживать максимум 3000 единиц емкости чтения (RCU) или 1000 единиц емкости записи (WCU). Если «горячая» секция превышает эти ограничения для жестких служб, то общая производительность таблицы может ухудшиться.


При первой разработке с DynamoDB часто возникает соблазн реализовать модель данных, которая использует идентификатор арендатора в качестве ключа раздела, что приводит к «проблеме шумных соседей». Когда один арендатор (или группа арендаторов) отправляет большое количество запросов, система извлекает большое количество записей из их раздела. В случае быстрого роста пользователей вполне вероятно, что вы увидите значительные всплески объема запросов от определенных арендаторов. Таким образом, этот всплеск запросов в конечном итоге приведет к блокировке всей таблицы, что замедлит работу системы и потенциально повлияет на всех пользователей.


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


Стратегия случайного разделения ключей


Первая и наиболее очевидная стратегия увеличения пропускной способности — использование случайного ключа раздела. Для данных арендаторов, которые не часто обновляются, эта стратегия позволяет нам вообще обойти проблемы пропускной способности при записи. В качестве примера рассмотрим приложение, которому необходимо сохранять входящие запросы арендатора в таблицу Dynamo. Ключ раздела будет иметь довольно высокую пропускную способность чтения и записи, если предположить, что request_id является случайным и имеет большое количество элементов. Каждый запрос, по сути, получает свой собственный раздел, и поэтому мы можем достичь 3000 чтений отдельных элементов запроса в секунду (при условии, что элемент имеет размер 4 КБ или меньше). Это чрезвычайно высокая пропускная способность чтения для объекта, такого как запрос API, и хорошо подходит для нашего варианта использования.


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


Стратегия использования ключа разделяемого раздела


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


Например, предположим, что мы хотим иметь возможность поддерживать 10 000 операций записи в секунду для данного арендатора. Если мы можем гарантировать, что каждый элемент имеет размер 4 КБ или меньше, и мы предполагаем, что диапазон осколков равен 10, то мы можем использовать простой генератор случайных чисел, учитывая выбранный нами диапазон, чтобы


dynamodb-partion-key-1


Затем во время записи элемента мы просто вычисляем сегмент для арендатора и добавляем его к ключу раздела.


dynamodb-partion-key-2


Дополнительные соображения


  • Сначала рассмотрите шаблоны доступа и требования приложений

  • Сохраняйте размер элемента менее 4 КБ и разгружайте полезную нагрузку на S3.

  • Остерегайтесь GSI и их способности регулировать стол


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