Архівація бази даних: чому довгострокові рішення кращі за короткострокові
Всім привіт, мене звати Віктор. Я — керівник розробки продуктів у фінтех-компанії Solid, яка допомагає бізнесам приймати платежі онлайн по всьому світу. Ми працюємо з величезними обсягами транзакцій і знаємо, що поступове збільшення бази даних постійно зменшує швидкість роботи системи. Остання є однією з важливих метрик для платіжного провайдера. Саме тому наша команда розробила власне довгострокове рішення для оптимальної архівації даних.
Чому важлива архівація даних
Для початку короткий приклад з життя платіжного процесингу. При кожній оплаті платіжний шлюз генерує велику кількість даних: ордера, транзакції, рахунок від банку... Вся ця інформація записується у базу даних (БД), яка постійно збільшується.
Інтенсивність користування системою також прямо пропорційно впливає на об’єм даних. Але не всі дані однаково корисні. Одна справа, коли ми провели платіж і записали інформацію, а через декілька місяців клієнт вирішив зробити рефанд (повернути гроші покупцю). У такому випадку ми раціонально використовуємо дані з першого платежу.
Але, якщо транзакція була проведена більше
Щоб пришвидшити роботу платіжного шлюзу, потрібне логічне рішення ситуації — вилучення застарілих даних і переміщення їх до іншого сховища. Дана стаття саме про архівацію таких даних.
Поширеним рішенням оптимізації БД є використання індексів. Ось тут можна прочитати про степи по бусту продуктивності бази, в тому числі і за допомогою використання індексу.
Побудова індексів вирішує проблему повільних запитів. Так, індекси можуть бути корисними, якщо треба вирішити ситуацію швидко. Але у довгостроковій перспективі це рішення не допоможе — час на виконання запитів буде постійно зростати, продукт буде гірше працювати, збільшуючи апаратні ресурси. Крім того індекс впливає на вставку і оновлення даних. Тому так важливо переформатувати роботу системи і не перевантажувати її непотрібними даними
3 кроки до оптимальної архівації БД
Щоб зрозуміти наш шлях, спочатку варто розповісти про ввідні задачі, аналіз ситуації і робочий процес, а вже у наступному розділі буде гайд зі створення самої системи архівації даних.
Варто зауважити, що даний кейс ми вирішуємо для AWS PostgreSQL. Отже, 3 етапи:
1 крок. Технічне завдання: вимоги та обмеження
а) Процес архівації не повинен навантажувати продову БД, яку використовує система. Запити на вибірку та перенос даних не мають впливати на проведення платежів.
б) Фізичний обсяг БД повинен стати меншим. Завдяки цьому зменшуються витрати на зберігання даних, прискорюється перенесення БД, швидше створюються бекапи і зменшується час їх розгортки.
в) Дані старіші
г) Процес архівації не повинен змінювати структуру таблиць та здійснювати операції над наявними даними, які необхідні для процесингу.
ґ) Потрібна можливість верифікації результатів скрипта архівації. Це важливо, оскільки ми працюємо безпосередньо з продовою БД і помилки неприпустимі.
2 крок. Пошук рішення. Від чого і чому відмовилися
Підхід 1.
Можна зробити воркер, який буде обирати батчами старі дані, а потім вставляти в архівну БД та видаляти з поточної. Але це сумнівний підхід. Чому він не спрацює:
- постійне навантаження на БД;
- для зменшення фактичного розміру потрібно робити full vacuum, а це призводить до локів;
- відсутня можливість перевірки результату роботи воркера (тільки за фактом видалення).
Підхід 2.
Дещо кращий варіант з партиціюванням — розподілом даних у дочірні таблиці за певною ознакою: датою створення, іменем, тощо. Наприклад, юзери з березня потрапляють в одну таблицю, юзери з травня — в іншу.
Ми розділили дані за часом створення транзакції, отримавши 24 таблиці (за умови архівації всіх даних, старіших за два роки). Щоб таким чином архівувати дані, треба витягувати стару таблицю і проводити архівацію. Але в нашому випадку і цей підхід не працює. Ми відмовилися від такого рішення через низку недоліків:
- первинне розподілення даних на партиції — не менш складна задача;
- на кожну таблицю буде 25 партицій. Вибірка даних сповільнюється, оскільки потрібно шукати в кожній партиції (ключ партиціювання created_at не бере участі в умовах вибірки);
- обмеження унікальності працює лише в рамках однієї партиції, що ускладнює підтримку консистентності даних.
3 крок. Рішення, яке задовольняє всі вимоги
Після низки експериментів та брейнштормів ми все ж таки знайшли рішення, яке відповідає всім нашим потребам. Складається воно з таких частин:
1. Підготовка
У першу чергу для роботи нам потрібна репліка продуктової бази даних. Репліку ми використовуємо для того, щоб не зачепити роботу продуктової бази даних.
Далі створюємо нову БД. У майбутньому саме з нею будуть працювати додатки.
В новій БД створюється схема даних і готується тригер. Тригер створюється, щоб розливати вхідні дані на 2 таблиці — операційні дані (2 роки) і архівні дані (більше
Наступним кроком налаштовуємо і запускаємо переливання даних за допомогою DMS від AWS (докладніше про Database Migration Service).
Важливо зауважити, що на першому етапі перенесення даних в нову БД треба вимикати всі наявні тригери, крім новоствореного. Це потрібно, щоб дані переливалися без мутації і сайд ефектів «as is». Коли DMS перейде в режим синхронізації, тригери варто знову увімкнути. Для цього ми використовуємо механізм Postgres — session_replication_role
Коли основний етап переливки даних завершився і таска DMS перейшла в режим синхронізації, приходить час наступного кроку.
2. Архівація
На цьому моменті в нашій новій базі дані вже розділені на операційні і архівні за таблицями. Тому ми переносимо дані з архівних таблиць в окреме сховище і видаляємо архівні таблиці.
3. Перевірка
На цьому етапі нова база даних ідентична до продуктової (за винятком відсутності архівних даних). Зараз саме час в цьому переконатися. Базу можна підключити до окремого нового інстанса додатка, запустити тести і переконатися, що все готово до роботи на продуктовому оточенні.
4. Перемикання
Найвідповідальніший етап. Перемикаємо роботу програми на нову базу даних. Завдяки працюючій тасці DMS, дані синхронізуються в реальному часі і ми можемо поступово переключати додатки один за одним.
Після того, як всі програми почали працювати з новою БД, ми перевіряємо, що більше ніхто не підключений до старої БД. Потім зупиняємо таски DMS і вимикаємо її. Через N часу ми її видаляємо.
Переваги такого рішення:
- не торкаємося поточної продової БД;
- маємо час на перевірку нової БД;
- дропаємо таблиці з застарілими даними;
- зменшуємо фактичний розмір БД.
В принципі усе відносно просто і саме таке рішення ми вважаємо оптимальним.
Гайд зі створення системи архівації даних
Правильна автоматизація і налагодження процесу архівації виключають людський фактор. Саме тому ми написали програму, яка виконує все вищезгадане. У двох словах про саму автоматизацію.
Скрипт був написаний на golang з використанням патерну Chain of responsibility. При першому запуску у нас є івент, який містить в собі поточний стан системи. Далі він передається від команди до команди, продукуючи нову базу даних. Створюється актуальна схема, виконуються міграції, вмикається тригер і запускається завдання DMS.
Сама програма постачається як консольний утиліт і включає в себе 2 команди:
- Створює нову БД і робить підготовку схеми, запускає DMS таски, чекає переходу переливки в режим доливання та переносить дані в архівну БД.
- Перемикає додатки на роботу з новою БД шляхом оновлення енвів і рестарту додатків. Також ця команда видаляє інстанси, що створені на
1-му кроці для запуску DMS.
Між першою та другою командами ми проводимо регресивне тестування додатків при роботі з новою БД. Якщо все ок, то приймаємо рішення перемикатися і запускаємо
Все це ми будемо проводити раз на місяць і таким чином не допускати збільшення нашої операційної бази.
Підсумок та порада
Більшість людей не аналізує реальну доцільність зберігання тієї чи іншої інформації у БД. Зростання бази негативно впливає на продуктивність. В результаті постійного додавання апаратних ресурсів ми врешті-решт зіткнемося з низкою проблем: брак коштів; відсутність місця для обслуговування БД; бекапи будуть тривати годинами, тощо. Індекси борються лише з повільними запитами, але не вирішують корінь проблеми.
Тому після всіх протестованих підходів я рекомендую оцінювати архівацію БД як довгострокове рішення. Цей підхід завжди працює і допомагає побудувати ефективну систему для безперебійного скейлінгу продукту.
Дякую за увагу. Буду вдячним, якщо поділитеся в коментах своїми думками по темі.
43 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів