Чому архітектура криптобіржі ламається на пікових навантаженнях
Біржа виглядає стійкою до першого сплеску. У спокійному режимі ядро торгів зіставляє заявки швидше, ніж учасники їх надсилають, і розрив між прийманням і підтвердженням непомітний.
Пікове навантаження на біржу — лістинг, різкий рух ціни, каскад ліквідацій — збільшує потік на порядок: черга на вході зростає, затримка виконання заявок сягає секунд, частина ордерів надходить за застарілою ціною.
Архітектура криптобіржі ламається не в одній точці: вузьке місце в ядрі торгів майже завжди пов’язане із сусідніми контурами. Книга заявок тримається в одному потоці — тільки так гарантовано детермінований порядок виконання, — і він же стає точкою серіалізації.
Усе, що потрапило в той самий цикл: перевірка коштів, резерви, запис угоди, — починає його гальмувати.
Друга лінія відмов — розрахунковий контур і розсилання ринкових даних. Поки перевірка балансу синхронна виконанню, кожна заявка чекає на підтвердження запису, і пропускна здатність упирається в сховище.
Підписки на оновлення стакана конкурують за ті самі ресурси, що й торгівля: переповнення черги розсилання додає затримку всім учасникам.
Відмова ядра на піку рідко залишається локальною. Якщо права сервісів не розділені, аналітика й адмінка читають ті самі таблиці, що й торгове ядро, і на піку конкурують із ним за блокування — каскад сягає скасування заявок.
Нижче розбираємо, як це закривається: розділенням гарячого шляху й допоміжних контурів, асинхронним записом, ізоляцією ресурсів і керованою деградацією замість повної відмови.
Ефект від перезбирання ядра: швидкість, стійкість, відмови
У переробленому ядрі торгів стакан не перераховується цілком на кожну подію — публікуються лише дельти, а читання відокремлено від запису. Через це продуктивність ядра торгів зростає разом із кількістю потоків-виконавців, а не впирається в одне блокування.
На історичних зрізах пікове навантаження тримається без зростання затримки відповіді: черга заявок перестала накопичуватися до кінця активної сесії.
Стійкість біржової платформи тепер спирається на детермінований журнал подій: стан піднімається відтворенням із останнього знімка плюс доганяння реплік.
Час відновлення після збою скоротився з десятків хвилин до одиниць — резервний вузол стартує з уже прогрітим стаканом і без ручної звірки балансів.
Заодно зник цілий клас відмов, пов’язаних із розсинхронізацією торгового розрахунку й обліку коштів.
Ідемпотентні операції та кворумний запис у журнал не дозволяють провести угоду двічі після перемикання, а деградація під навантаженням стала керованою: черга обмежується й уповільнює приймання замість падіння.
Баланси й довідники зберігаються в PostgreSQL, гарячі зрізи живуть у пам’яті, тому вивантаження й звітність не гальмують торги. Простій платформи в активні години вимірюється секундами й планується заздалегідь, а не трапляється раптово.
Варіанти архітектури криптобіржі: єдине ядро, кластер, гібрид
Єдине ядро — один активний вузол, який послідовно застосовує заявки: черга передбачувана, аудит простий, логіка виконання живе в одному місці.
Плата за це — пропускна здатність упирається в один потік, а перезапуск процесу зупиняє весь ринок і відкриває вікно розбору заявок після збою.
Кластерна схема розносить інструменти за незалежними групами й знімає стелю за навантаженням, зате додає міжгрупові операції: переказ коштів між рахунками, крос-маржинальні позиції, зведений стакан.
Їх доводиться узгоджувати окремо — і саме тут найчастіше спливають розбіжності балансів, які потім ловить звірка.
Гібридне ядро розводить два контури: торговий, де цінний час відгуку, і розрахунковий, де цінний стан балансу. Угоди сходяться у швидкому контурі, а списання й нарахування йдуть асинхронно через журнал операцій — розбіжність закриває звірка, а не зупинка торгів. Ціна рішення — узгодженість двох контурів і вищий поріг входу в підтримку.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Єдине ядро | Спотові торги, один-два десятки інструментів, мало пов’язаних рахунків | Масштабування лише вертикальне; відмова вузла зупиняє торги |
| Кластер із розбиттям за інструментами | Багато інструментів і нерівномірне навантаження, потрібен запас на пік | Міжгрупові операції та зведений стакан дорожчі, звірка складніша, більше точок відмови |
| Гібрид: торговий контур плюс розрахунковий | Висока частота заявок, пов’язані рахунки, жорсткі вимоги до звірки | Потрібен журнал операцій із повторюваною обробкою, два контури узгоджувати дорожче |
Порівнювати схеми має сенс за кількістю інструментів, часткою пов’язаних рахунків і вимогами до звірки — не за піковим навантаженням окремо від решти.
Етапи впровадження: від аудиту навантаження до передачі в експлуатацію
Етапи впровадження будуємо так, щоб кожне архітектурне рішення спиралося на виміряний профіль навантаження, а не на припущення. Спочатку аудит навантаження, потім зафіксована схема потоків заявок, і тільки після цього — налаштування ядра й навантажувальна перевірка. Передача в експлуатацію йде окремим етапом, із документацією та черговими регламентами.
- Аудит навантаження. Знімаємо фактичний профіль: піковий потік заявок, співвідношення операцій читання й запису, частку скасувань і правок, глибину стакана за інструментами. Тут же фіксуємо цільові показники й точки зростання, щоб не проєктувати наосліп.
- Схема потоків заявок. Прокладаємо шлях від точки входу до підтвердження: валідація, перевірка лімітів, зіставлення, перерахунок балансів, публікація ринкових даних. На схемі видно, де доречна черга, а де потрібна синхронна відповідь.
- Проєктування й налаштування ядра. Розділяємо зіставлення за інструментами, налаштовуємо черги, правила пріоритету й поведінку системи при перевантаженні. Окремо визначаємо, які вузли можна масштабувати горизонтально, а які тримають стан.
- Навантажувальна перевірка. Програємо реальний профіль трафіку й піки вище розрахункових, дивимося затримку на 99-му перцентилі, стабільність під тривалим навантаженням і поведінку при відмові окремого вузла. Розбіжності повертають нас на попередній крок.
- Перевірка безпеки й відмовостійкості. Розмежовуємо доступи, налаштовуємо зберігання й ротацію ключів, репетируємо відновлення з реплік. Фіксуємо регламент реакції на інцидент.
- Передача в експлуатацію. Віддаємо документацію, дашборди, алерти й інструкції для чергової зміни, проводимо навчання й залишаємося на зв’язку в період приробітку.
Комплект на виході: схеми, конфігурації, регламенти, документація
Роботи з архітектури криптобіржі закінчуються не демонстрацією, а пакетом артефактів, із яким команда експлуатації працює без нас. Нижче — що саме залишається у вас на руках і з якою деталізацією.
- Схема інтеграцій. Як пов’язані шлюз заявок, ядро зіставлення, сервіс балансів, ризик-контроль і виведення коштів: потоки даних, точки відмови, межі відповідальності сервісів.
- Конфігурації сервісів. Файли налаштувань з описом кожного параметра — ліміти черг, таймаути, пули з’єднань, повторні спроби — і окремими значеннями для середовищ розробки, передпродуктивного та продуктивного.
- Політики доступу. Ролі й області прав, розподіл обов’язків адміністратора, оператора й аудитора, порядок ротації ключів і правила роботи з холодним зберіганням.
- Регламент розгортання. Покроковий випуск версії, послідовність міграцій, процедура відкату й перелік перевірок після перезапуску.
- Моніторинг і оповіщення. Метрики: затримка обробки заявок, глибина стакана, розбіжність балансів, частка відмов. Для кожної — поріг, за якого черговий отримує повідомлення.
- План відновлення. Цільовий час і точка відновлення, перемикання на резервний контур, звірка реплік і розбір накопиченої черги.
- Експлуатаційна документація. Опис програмних інтерфейсів, лімітів і кодів помилок, інструкція для чергової зміни, журнал архітектурних рішень з обґрунтуванням компромісів.
Кожен документ прив’язаний до конкретного сервісу й версіонується разом із кодом — інакше пакет швидко перетворюється на архів неактуальних схем.
Кейс: як ядро торгів перестало втрачати заявки на піках
Клієнт — спотова площадка з власною книгою заявок. У спокійному режимі ядро торгів тримало навантаження, але на різких рухах ринку черга подій на вході роз’їжджалася: частина заявок не доходила до стакана, а угоди виконувалися за ціною гіршою за заявлену.
Причин виявилося три: синхронний запис журналу в потоці зіставлення, єдиний потік на всі інструменти й відсутність відсікання дублів при повторній доставці подій.
Що змінили в ядрі
Гарячий шлях звільнили від усього, крім зіставлення: події йдуть через кільцевий буфер, журнал пишеться окремим потоком пакетами, інструменти розведені за незалежними потоками.
Додали відтворення журналу — стан стакана піднімається до останнього підтвердженого запису, тому збій вузла більше не потребує ручної звірки.
Перемикання без зупинки торгів
Нове ядро запустили в тіньовому режимі: воно приймало ті самі події паралельно зі старим, а розбіжність за кожним інструментом рахувалася автоматично. Переводили по одному ринку, з миттєвим поверненням на попереднє ядро при відхиленні. Числа до й після знімали по одних і тих самих панелях у Grafana:
| Показник | До | Після |
|---|---|---|
| Заявки, що не дійшли до стакана на піках | 0,3 % | нуль |
| Час обробки заявки на піку | секунди | частки секунди |
| Звернення в підтримку щодо розбіжностей | десятки на добу | поодинокі |
| Повернення на попереднє ядро | планове вікно | секунди |
Відновлення перевіряли окремо: вузол піднімається з журналу й доганяє потік подій без зупинки торгів.
Чим відрізняється ядро торгів від розрахункового модуля і що змінювати першим?
Ядро торгів тримає стакан заявок і зіставляє їх у пам’яті, не знаючи про гроші користувача. Розрахунковий модуль нараховує й списує кошти, тримає локи під відкриті ордери й веде історію операцій.
Межа між ними — перше, що перевіряють під час аудиту архітектури криптобіржі: якщо ядро саме править баланси, будь-яка затримка в зіставленні перетворюється на розбіжність обліку.
Починати правки з ядра майже завжди помилка. Воно єдине місце, де збій видно відразу всім учасникам ринку, а відкат потребує зупинки торгів.
Спочатку фіксують інваріанти: детермінованість обробки однієї й тієї самої послідовності заявок, наскрізну нумерацію подій та ідемпотентність скасування.
Розрахунковий модуль змінюють першим — він ізольований, його можна продублювати, прогнати на історичних даних і звірити порядково.
Ключовий елемент тут — звірка балансів: кошти на рахунках користувачів мають сходитися із залишками на гарячих і холодних гаманцях та обсягом незакритих ордерів. Розбіжність — не привід панікувати, а сигнал, що подія загубилася або застосувалася двічі.
Порядок змін вибудовується від зворотного: спочатку спостережуваність — журнал подій, метрики черг і затримки відгуку, можливість програти день торгів заново.
Потім розрахунковий модуль, далі ядро зіставлення, ізольоване від зовнішніх викликів, і тільки після — доступ до ринкових даних.
Критерій готовності простий: ви вмикаєте тіньове ядро, порівнюєте його видачу з робочим і пояснюєте кожну розбіжність. Поки цього немає, змінювати логіку торгів рано. Розбираємо, як такий порядок лягає на ваш контур.
Технічні сумніви: доступи, аудит, міграція без простою
До старту замовник хоче зрозуміти три речі: хто має доступ до ключів і балансів, що залишається в журналах після кожної дії та чи можна переїхати на новий контур без зупинки торгів. Нижче — як ці питання закриваються архітектурно.
Відповіді — не «довіртеся нам», а відтворювані процедури: ролі описані конфігурацією, регламент — документом, переїзд — репетицією на копії даних. Усе перевіряється на стенді до виведення в прод.
Як розділяються права сервісів?
У кожного сервісу свій обліковий запис і тільки ті права, які потрібні для його задачі. Доступ до сховища ключів має лише сервіс підпису, решта звертаються до нього за заявкою.
Видача розширених прав йде через підтвердження другого інженера — самотужки ніхто не виведе кошти й не змінить ліміти.
Де зберігаються ключі та як ведеться журнал дій?
Ключі не потрапляють у код, конфіги й логи: вони лежать у захищеному сховищі, а гарячий контур обмежений лімітом на виведення. Кожна дія — вхід, зміна прав, підпис транзакції — пишеться в незмінюваний журнал із міткою часу та ініціатором, аномалії піднімають оповіщення черговому. Аудит безпеки проходить перед запуском і після змін у контурі підпису.
Чи реально мігрувати без зупинки торгів?
Так. Новий контур піднімається поряд, дані безперервно реплікуються, частина трафіку йде на нього тіньовим режимом і звіряється за результатами.
Перемикання займає секунди, і до нього залишається зворотний шлях: якщо метрики розходяться, трафік повертається на старий контур без втрати заявок.
Обговоримо задачу: що знадобиться від вас і з чого почнемо
Щоб оцінка строків і план робіт спиралися на факти, а не на здогади, нам потрібен зріз поточного стану й цільових вимог. Нижче — вихідні дані, які ми запитуємо на першому обговоренні задачі: частина вже описана у вашій документації, частину відновлюємо разом.
- Як влаштований торговий контур зараз: моноліт чи роздільні сервіси, де живуть заявки, баланси та історія угод.
- Модель ордерів і типи заявок, які потрібно підтримати: лімітні, ринкові, стоп-, умовні, маржинальні — від цього залежить ядро зіставлення й розрахунок ризиків.
- Цільовий профіль навантаження: кількість рахунків і торгових пар, пікові сплески в моменти волатильності, вимоги до затримки розміщення й скасування заявки.
- Вимоги до відмовостійкості та допустимий час простою: що критичніше — безперервність торгів чи збереження балансів при аварії.
- Регуляторний контур: які перевірки доведеться проходити, яку звітність та історію операцій зберігати.
- Зовнішні інтеграції: поповнення й виведення коштів, постачальники котирувань, майданчики зовнішньої ліквідності, кастодіальне зберігання ключів.
- Межі відповідальності й доступи: що закриваємо ми, що залишається на ваших інженерах, до яких репозиторіїв і стендів потрібен доступ, чи є обмеження за строками виведення на ринок.
Після розбору вихідних даних повертаємося з планом робіт за етапами, оцінкою строків і порядком старту — що робимо першим, що можна вести паралельно. Опишіть задачу в поточному вигляді, навіть якщо частину даних поки не зібрано: прогалини закриємо уточнювальними питаннями.







