![](https://habrastorage.org/webt/ug/vx/tm/ugvxtmtcasedx_hsmqskdxvc4qo.png)
Цикл статей освещает попытку создания реактивной системы силами одного человека с минимальным бюджетом и в кратчайшие сроки.
Цели эксперимента:
- Более глубокое понимание предметной области и улучшение технической экспертизы
- Выявление сильных и слабых сторон использования функциональных языков и проектов с открытым исходным кодом при разработке торговых систем
В этой статье представлена мотивационная часть проекта и декомпозиция задачи.
Я планировал начать эксперимент еще весной 2019 года, однако обстоятельства сдвинули сроки. Поэтому я приношу извинения своим немногочисленным подписчикам, которые ждали статей по этой теме.
Как я дошел до такой жизни?
Когда я осознал, что начал уставать от рутины рабочих проектов, захотелось сделать что-то необычное. Я рассматривал различные темы и направления, процесс реализации которых для меня представлял вызов. Были сформулированы основные требования к проекту:
- Интересная мне область знаний;
- Распределенный и высокодоступный характер приложения;
- Высокая информационная емкость и большие объемы хранимых данных характерные data-intensive приложениям;
- Максимальное применение проектов с открытым исходным кодом.
Поскольку уже был определенный опыт в разработке объектных хранилищ данных, родилась идея развить тему и написать новую реализацию s3-совместимого хранилища с использованием избыточного кодирования и быстрых хэш функций. Но хотелось чего-то более интересного. С точки зрения разработчика, финансовые системы любопытны своей работой в режиме близком к реальному времени, большим количеством обновлений и объемами хранимых данных. Так я решил сделать свою реализацию биржевой системы.
Про биржи
В широком смысле биржа (от лат. bursa — кошелек) — это рынок, где продавцы и покупатели совершают сделки. В зависимости от того, что является торгуемым активом (инструментом) определяется специфика биржи:
- товарные, в том числе и биржа труда
- фондовые
- валютные
- фьючерсные
Исторически биржи действительно были местом, где в назначенный час собирались покупатели, продавцы и брокеры (посредники), через которых совершались сделки.
К главным функциям биржи можно отнести:
- Организация процесса биржевого торга:
- Определение правил торговли в соответствии с действующим законодательством
- Установление стандартов на товары
- Материальное и кадровое обеспечение
- Информационная деятельность. Предоставление информации о ценах инструментов, рынках и компаниях;
- Разработка типовых контрактов;
- Урегулирование споров (арбитраж);
- Предоставление определенных гарантий исполнения сделок.
Современные биржи — организованные торговые площадки, функционирующие по конкретным правилам и концентрирующие спрос и предложение. Экономика биржи тоже предельно понятна, чем больше сделок на бирже, тем выше вознаграждении биржи за оказанные услуги.
Итак, общие черты решения понятны, теперь необходимо ограничить объем работ, чтобы реализация идеи могла уложиться в разумные сроки.
MVP
Из ограниченности ресурсов вытекает ограниченность функционала прототипа. Но жизненно необходимые и фундаментальные вещи необходимо реализовать полностью.
Декомпозиция задачи и выбор архитектуры
С технической стороны, биржа — система массового обслуживания, в которой участники генерируют поток обращений — ордеров, а система по заранее известным правилам совершает над ними действия.
Обслуживание ордеров должно происходить с наименьшими временными затратами. Биржа должна быть отказоустойчивой и высокодоступной.
Разделим проект на служебную и публичную часть. Служебная часть позволит управлять компонентами платформы и торговым процессом биржи. К публичной части отнесем интерфейсы взаимодействия с клиентами: Web API, Trading API, подсистема уведомлений. Обе части будут базироваться на платформе распределенных приложений, отвечающей за вопросы масштабируемости и надежности системы в целом.
Поскольку мы ограничены бюджетом, будем использовать только проверенные открытые решения для организации хранения данных. Для горячих данных системы применим Tarantool, а для холодных PostgreSQL.
Изобразим планируемый состав системы (картинка кликабельна):
Складывается ощущение, что и архитектура и проект ничем не отличается от обычных систем. Где же тут вызов? Для ответа рассмотрим процесс создания ордеров и закрытия сделок для валютной биржи.
Создание ордера
- Проверить авторизацию
- Убедиться что у пользователя в текущий момент хватает средств на создание ордера.
- Создать ордер
- Уведомить пользователя об успешном создании или ошибке
Закрытие сделки
- Найти ордеру пару
- Проверить достаточность средств на балансах сторон для закрытия сделки
- Произвести фиксацию сделки: перевод между аккаунтами + перевод комиссии биржи на комиссионный аккаунт биржи.
- Сохранить историю выполненных ордеров.
- Обновить информационные данные: сырые торговые данные и агрегированные данные для графиков.
- Уведомить все заинтересованные стороны о сделке.
Сложности начинаются, когда мы от монолита работающего на одной машине переходим к распределенной отказоустойчивой системе развернутой на кластере. Я закладываю минимальную производительность системы на уровне 5-7к закрытых сделок в секунду на каждый рынок. Это накладывает дополнительные ограничения на архитектуру и работу с данными.
Следуя принципу KISS, каждое приложение должно выполнять только те функции, которые необходимы для обработки реализуемой в нем сущности: рынок, аккаунт, авторизация и так далее.
VTrade построен на принципах горизонтального масштабирования. Каждое приложение может быть запущено во множественном числе. Это позволяет добиться отказоустойчивости и требуемого уровня производительности.
Технологический стек
Чтобы не множить энтропию, ограничим применяемые языки и технологии.
Для сервера этот набор будет включать:
- Erlang. На мой взгляд идеальный язык для построения инфраструктурных вещей.
- Rust. Отлично подходит для системных вещей и вопросов оптимизации.
- PostgreSQL. В качестве основной базы для длительного хранения данных
- Tarantool. В качестве хранилища горячих данных (только на время MVP)
- Clickhouse. Для анализа логов и возможностей глубокой аналитики.
- Linux. Система должна поддерживать современные дистрибутивы.
Клиентское ПО реализовано с помощью фреймворка Vue с применением Vuex.
Так как проект изначально предполагает большое количество компонентов, для обеспечения должного уровня качества итогового решения будем писать большое количество property-based тестов и интеграционных тестов.
Про планы
В ближайшее время я планирую разобрать основы теории и углубиться в практику по следующим направлениям:
- Ордеры. Типы, особенности обработки. Аспекты хранения торговой информации.
- Книга ордеров. Визуальное представление рынка.
- История торгов. Принты, графики, персональная история.
Как там говорят… Если интересно, лайк, подписка )
Комментарии (4)
stone_evil
19.12.2019 10:49+1Если каждое приложение может быть запущено во множественном числе, будет ли применение оркестратора сервисов типа k8s? Каким образом планируется service discovery, балансировка сервисов, и т.д.? Где api gateway для публичных api, что планируется использовать в качестве system bus? Смотря на картинку архитектуры возникает много вопросов.
mr_elzor Автор
19.12.2019 11:06Спасибо за комментарий. Организация кластера действительно важный вопрос.
Контейнеризация активно используется на этапе разработки для создания виртуальных сред приближенных к боевым. В продакшене ее использование не планирую. Штатных средств Erlang/OTP хватает для построения отказоустойчивого и масштабируемого кластера. Ответы на вопросы связанные с SD, балансировкой, системной шиной и другими важными моментами при проектировании распределенных систем освещены в моих прошлых публикациях: habr.com/ru/post/446028, habr.com/ru/post/446108, habr.com/ru/post/446344.
В последующих статьях архитектура Vtrade будет рассмотрена более детально.
Northborn
Вместо тарантула я бы предложил рассмотреть Mnesia (или ETS для начала), которые являются частью (платформы) Erlang. Так вы получите прозрачное взаимодействие с возможностью хранения термов эрланга без дополнительных затрат на сериализацию/десериализацию.
mr_elzor Автор
ETS не подойдут из-за отсутствия персистентности. У Mnesia слишком узкая область применения из-за ее особенностей, таких как высокий IO, медленный рестарт и ограничения на размеры таблиц. Тарантул выбран для MVP, оверхэд на взаимодействие пока допустим. Затем планирую переход на rocksdb.