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







