Налаштування AWS DynamoDB для NoSQL-сховища

Пікове навантаження ламає запис, а відмови б'ють по виручці та репутації сервісу. Ми налаштовуємо AWS DynamoDB під ключ: проєктуємо схему даних і ключі доступу, закладаємо запас за навантаженням і зрозумілі регламенти експлуатації. Скорочуємо час на підготовку сховища до піків і прибираємо цілий клас відмов запису.
Часті запитання

Чому AWS DynamoDB деградує під навантаженням

Найчастіше Amazon DynamoDB деградує не через обсяг даних, а через форму трафіку. Якщо ключ розділу вибрано за «зручною» ознакою — статус, тип документа, дата без суфікса — весь потік іде в один гарячий розділ, а решта простоюють.

Далі спрацьовує обмеження пропускної здатності: частина записів отримує відмову, клієнт повторює їх, і навантаження на той самий розділ подвоюється.

Друге типове джерело — читання повним скануванням таблиці замість точкових запитів за ключем. Такий запит проходить увесь набір елементів, затримка відгуку зростає лінійно разом із таблицею, а під піковим трафіком конкурує за ту саму ємність, що й робочі операції.

Зовні це виглядає як «сховище стало гальмувати на рівному місці», хоча схема та дані не змінювалися.

Окрема історія — індекси, яких немає під реальні сценарії доступу. Запити йдуть за неключовими полями, фільтрація відбувається вже після вибірки, і замість одного звернення до потрібного розділу система перебирає десятки.

Вторинний індекс, доданий постфактум, потребує перебудови та змінює профіль запису — проєктувати його потрібно разом зі схемою доступу, а не після перших скарг.

Пікові сплески добивають картину: затримка запису зростає, операції йдуть у повтор, повтори складаються в лавину, і таблиця перестає приймати навантаження, яке раніше тримала.

Розбираємо, як це закривається — від вибору ключа розділу до режиму ємності та моніторингу гарячих розділів.

Ефект від перебудованої схеми даних і доступу

Зміни після перебудови схеми видно не у звітах, а в поведінці сховища під навантаженням. Нижче — те, що ми замірюємо на прийманні: один і той самий набір сценаріїв прогониться до і після, на однаковому профілі трафіку.

Нижче — ефекти, які AWS DynamoDB дає саме завдяки схемі даних і моделі доступу, а не завдяки докупленій потужності.

Час відгуку на гарячих запитах

Ключ розділу вибрано так, що читання йде в одну партицію замість проходу по таблиці з фільтрацією.

Час відгуку на сценарії «замовлення — оплата — статус» скоротився в рази, а розрив між типовою та рідкісною повільною відповіддю звузився: важкі хвости перестали бути нормою, і зовнішні таймаути на клієнті більше не спрацьовують.

Клас відмов запису зник

Раніше сезонний пік призводив до відмов запису: операції понад ліміт на розділ відхилялися, і дані доводилося досилати вручну.

Після рознесення навантаження за ключами та коректно заданого режиму ємності цей клас відмов зник — піки проходять штатно, без ручних наздоганяльних задач і звірки розбіжностей.

Передбачуване навантаження та запас за пропускною здатністю

Ємність налаштована на цільове використання з автоматичним масштабуванням за фактом і буфером на сплеск.

Графік споживання перестав бути пилкоподібним, запас за пропускною здатністю видно заздалегідь, і додавання навантаження більше не потребує ручного втручання в момент піку — лише планового перегляду цільових значень.

Зростання обсягу даних без перебудови сховища

Дані розкладено за складеними ключами, а старі записи йдуть за політикою зберігання. Таблиці зростають лінійно, тому зростання обсягу даних не потребує перенесення схеми, зупинки сервісу або окремого проєкту міграції — новий сезон просто додає записів.

Режими роботи AWS DynamoDB і коли вони підходять

Профіль навантаження вирішує більше, ніж схема таблиці: один і той самий набір даних на рівному потоці та на різких піках поводиться по-різному.

AWS DynamoDB розділяє це за незалежними налаштуваннями — режим ємності, вторинні індекси, реплікація між регіонами, кешувальний шар, потік змін, — і їхнє поєднання визначає, де з’являться відмови читання та зайві звернення до диска.

Порівняння варіантів

Варіант Коли підходить Обмеження
Ємність за запитом Непередбачуваний трафік, запуск продукту Дорожче за рівного високого навантаження, немає ручного запасу
Виділена ємність з автомасштабуванням Прогнозований графік, стабільний потік Потрібні пороги та моніторинг, на різкому сплеску можливий тротлінг
Вторинний індекс (локальний або глобальний) Інший ключ доступу, вибірки за атрибутами Власна ємність, кількість індексів і розмір ключа обмежені
Глобальні таблиці Читання поруч із користувачем, захист від відмови регіону Затримка реплікації, конфлікти під час запису в обидва регіони
Потік змін Денормалізація, вивантаження, реакція на правки Вікно зберігання обмежене, порядок лише в межах ключа
Кешувальний шар Гарячі повторювані читання Інвалідація, ризик застарілих даних, зайвий вузол

На практиці шари комбінують: виділена ємність під рівний потік, глобальний індекс під вибірки за атрибутами, потік змін для синхронізації, кеш на найгарячіші читання.

Перед вибором знімаємо профіль: співвідношення читань і записів, розподіл за ключами, частку запитів не за основним ключем.

Порядок робіт: аудит схеми даних і ключів доступу

Аудит до правок дешевший, ніж перебудова таблиць після запуску: у DynamoDB схема вбудована в ключі, і на працюючих даних її змінюють лише перенесенням. Тому спочатку розбираємо, як застосунок реально звертається до сховища, і тільки потім чіпаємо налаштування.

  1. Знімаємо профіль запитів — за журналами та кодом дивимося, які звернення йдуть, з якою частотою, що потрапляє в умову вибірки і що повертається цілком.
  2. Розбираємо поточну схему: перевіряємо, чи рівномірно ключ розділу розподіляє навантаження і чи віддає ключ сортування потрібні діапазони без повного перебору.
  3. Проєктуємо індекси під конкретні шаблони вибірки: локальні — у межах одного розділу, глобальні — для решти, стежачи, щоб кожен індекс не здорожував запис.
  4. Налаштовуємо права: окрема роль на кожен сервіс, лише необхідні дії та лише потрібні таблиці й індекси, без спільних ключів доступу в конфігурації.
  5. Проводимо навантажувальну перевірку: прогонимо реальні шаблони на цільовому обсязі, дивимося затримки та частку помилок на піку, поведінку при вичерпанні виділеної ємності.
  6. Фіксуємо регламент і передаємо команді: схеми таблиць та індексів, опис ролей, правила іменування, точки моніторингу та порядок зміни схеми.

Далі команда додає нові шаблони запитів, спираючись на готові ключі та індекси, замість того щоб перебудовувати структуру таблиць.

Схеми таблиць, політики доступу та регламенти

Після запуску сховища на DynamoDB у команди замовника залишається не набір скріншотів, а комплект артефактів: за ними новий інженер піднімає таблиці в іншому середовищі та розуміє, чому модель доступу влаштована саме так.

Документи лежать у репозиторії поруч із кодом і змінюються разом з інфраструктурою, а не окремим файлом на диску.

  • Описи таблиць та індексів — ключ партиції та сортування, склад вторинних індексів і обґрунтування вибору: нові запити не призводять до повного сканування бази.
  • Ролі та політики доступу — окремі ролі для сервісів, інженерів і складальних конвеєрів, права за принципом мінімальної необхідності, розділення читання та запису між середовищами.
  • Налаштування шифрування — що закрито в стані спокою та під час передавання, де зберігаються ключі, хто відповідає за їхню ротацію.
  • Схема реплікації — які регіони отримують копію даних, яка затримка поширення і за яким правилом трафік перемикається при відмові.
  • Регламент резервного копіювання та відновлення — розклад знімків, глибина зберігання, регулярна перевірка відновлення на тестовому контурі із заміром часу.
  • Порядок розбору інцидентів — контрольовані метрики затримок і відмов, пороги оповіщень, відповідальні та порядок ескалації.
  • Журнал змін схеми — як додаються атрибути й індекси без зупинки запису і хто погоджує правку.

Кейс: пікове навантаження без відмов запису

До: перекіс за розділами та відмови на піку

Навантаження на запис ішло хвилями: нічні пакетні завдання та денні сплески замовлень били в той самий діапазон ключів. Частина розділів таблиці AWS DynamoDB постійно впиралася в стелю пропускної здатності, поки сусідні простоювали.

На піку це оберталося відмовами запису та повторними спробами, а час відгуку запису на «хвості» сягав 900 мс — фронт показував помилки оформлення замовлення, і замовлення доводилося дотягувати вручну.

Після: вирівняне навантаження та триразове зростання обсягу

Спочатку переробили модель даних: гарячий ключ розбили на складений із суфіксом-«сіллю», щоб записи розходилися за розділами, а важкі вибірки аналітики вивели на розріджені індекси.

Потім перевели таблицю на автоматичне масштабування за фактичним споживанням і увімкнули потік змін — фонові читання перестали конкурувати з прикладними запитами за ті самі розділи.

Окремо налаштували збір метрик споживання за кожним розділом і попередження про зростання кількості повторів, щоб перекіс було видно до піку, а не після.

Час відгуку запису на «хвості» знизився з 900 до 140 мс, частка відмов запису на піку — з 3,2% до нуля, а розкид споживання між розділами пішов з десятиразового до дворазового.

Обсяг даних за той самий період зріс утричі: без зміни платформи, без ручного секціонування та без переписування застосунку.

Клас відмов «вперлися в ліміт на гарячому ключі» закрито на рівні схеми даних, тому повертається лише при зміні профілю навантаження — тоді ми повторюємо перевірку розподілу ключів.

Що робити, якщо таблиця вже розгорнута і в ній є дані

У DynamoDB ключ розділу та ключ сортування фіксуються при створенні таблиці, і змінити їх на місці не можна — міграція схеми завжди означає перенесення даних у нову таблицю.

Це не блокує сервіс: поки копія наповнюється, застосунок продовжує працювати зі старою таблицею, а нова існує паралельно.

Переведення без простою будується на двох потоках одразу. Нова таблиця створюється поруч, і застосунок отримує подвійний запис: кожна зміна лягає і в стару, і в нову, тому розбіжність не накопичується.

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

Зворотна сумісність тримається на шарі доступу, а не на коді запису. Читання спочатку йде в нову таблицю, за відсутності запису — у стару, і частка переведеного читання зростає поступово, за метриками помилок і затримок.

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

З індексами та режимом ємності простіше: глобальний індекс додається й видаляється на працюючій таблиці, але змінює профіль запису, тому його вводять заздалегідь і перевіряють на копії трафіку.

Режим ємності перемикається без перестворення — важливо лише, щоб він збігався з характером навантаження, інакше піки йдуть в обмеження запитів. Локальний індекс змінити не можна: лише через нову таблицю, і це ще один аргумент зробити перенесення один раз.

Відкат на будь-якому кроці — це повернення читання на стару таблицю. Вона залишається живою до підтвердженої стабільності, тому вікно відкату вимірюється хвилинами, а не відновленням із резервної копії.

Сумніви та обмеження: розбираємо за пунктами

Технічні сумніви зазвичай спливають уже на етапі оцінки — і це нормально: їх дешевше зняти до міграції, ніж після. Нижче — питання, які замовники ставлять найчастіше під час обговорення AWS DynamoDB, і наша відповідь на кожне.

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

Наскільки складно потім змінити режим ємності?

Перехід між виділеною пропускною здатністю та режимом за вимогою виконується без простою і без перестворення таблиці — змінюється лише спосіб розподілу ємності та логіка автомасштабування. Зворотне перемикання теж підтримується, тому вибраний режим не замикає вас в одному варіанті.

Чим небезпечні повні сканування таблиці?

Сканування читає весь набір даних: час відповіді зростає лінійно разом з обсягом, а споживання ємності б’є по сусідніх запитах.

Ми зводимо такі звернення до мінімуму — доступ за ключем, вторинні індекси під конкретні шаблони вибірки, обмеження прав на сканування для сервісних облікових записів.

Чи вистачить схеми ключів на зростання?

Схему проєктуємо від шаблонів доступу, а не від структури об’єктів: перевіряємо розподіл записів за розділами, щоб зростання обсягу не створювало «гарячих» ключів і не впиралося в один сегмент.

Запас закладаємо з розрахунком на порядок більше поточного обсягу — перебудова ключів на живій таблиці потребує окремої міграції даних.

Хто відповідає за розмежування прав?

Ролі та політики доступу налаштовуємо ми: окремі облікові записи для сервісів і інженерів, мінімально необхідні дозволи, журналювання звернень до даних. Будь-яка зміна прав проходить погодження та фіксується в конфігурації — доступ не наростає стихійно з часом.

Обговоримо задачу: що потрібно від вас і як ми почнемо

Щоб повернутися з оцінкою та планом, а не із загальними словами, нам потрібні ввідні щодо навантаження та зрозумілі сценарії доступу до даних.

Чим точніше опишете профіль, тим менше припущень закладемо в схему ключів і режим ємності таблиць DynamoDB — переробка моделі після запуску коштує дорожче, ніж розбір до нього.

Що корисно надіслати або розповісти на дзвінку:

  • профіль навантаження: середня та пікова інтенсивність запитів, добові й тижневі сплески, очікуване зростання обсягу;
  • сценарії читання та запису: які запити переважають, за якими ключами шукають, чи потрібні вибірки за діапазоном і агрегати;
  • приклади сутностей або поточна схема: поля, зв’язки, розміри записів і строки їх зберігання;
  • вимоги до відмовостійкості: допустимий час недоступності, чи потрібні резервні копії та відновлення на точку в часі;
  • доступи та середовища: скільки середовищ, хто і як звертається до бази, чи є обмеження щодо розмежування ролей;
  • обмеження: вікна для змін, порядок погоджень, чи потрібна міграція наявних даних.

Якщо частина ввідних поки невідома — це нормально, знімемо їх на розборі. Далі фіксуємо схему ключів та індексів, порядок міграції й відкату, склад робіт і критерії приймання. Опишіть задачу — повернемося з оцінкою та планом і запропонуємо дату старту робіт.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139