Агрегатор данных с крупнейших криптобирж

Криптобиржи (ВК).jpg

Американская финтех-компания обратилась в Sibedge с просьбой разработать высоконагруженную систему, способную в реальном времени собирать информацию о торгах и котировках с крупнейших мировых криптобирж.

Зачем собирать данные с криптобирж

Собранные данные делают крипторынок прозрачнее, способствуют формированию честных цен, используются для отчётности перед регулирующими органами. Кроме того, собранную информацию можно продавать брокерам, среди которых она пользуется высоким спросом.

В некоторых странах покупка и продажа криптовалюты облагается налогом, поэтому участникам рынка приходится отчитываться перед регуляторами. В США — это агентство по борьбе с финансовыми преступлениями, комиссия по ценным бумагам и биржам, комиссия по торговле товарными фьючерсами и другие.

Требования к системе

Прежде чем обратиться к Sibedge, клиент арендовал стороннее решение. Это было связано с рядом неудобств: данные собирались медленно, поставлялись с большой задержкой, а внести изменения в чужой продукт было крайне сложно. Собственную систему решили разработать для того, чтобы не платить ренту и не зависеть от третьих лиц.

Всё это отразилось на требованиях к системе:

  • Сбор и доставка данных в течение одной минуты.
  • Минимальные усилия для добавления новых криптобирж.
  • Система должна обрабатывать до 600k событий в секунду от одной биржи.
  • Поддержка WebSocket и REST API для получения данных.
  • К системе планируется подключить до 100 криптобирж.

Отдельно подчёркивалась важность отсутствия потери данных при агрегации. Все полученные данные должны приводиться к единому унифицированному формату. Это нужно для простоты обработки и анализа собранной информации, ведь биржи могут использовать разные идентификаторы одной и той же криптовалюты.

Binance — первая биржа, которую предстояло подключить к системе. Учитывая, что в будущем количество бирж планируется увеличить до 100, нужно изначально заложить в архитектуру возможность кратного масштабирования. Система должна работать под огромными нагрузками, ведь каждая криптобиржа проводит сотни тысяч транзакций в секунду.

Архитектура и технологии

Веб-соединения с криптобиржей крайне нестабильны: может сработать ограничение на количество запросов, объём трафика или произойти спонтанный разрыв соединения. Чтобы повысить надёжность системы, подключение происходит через несколько компонентов Gate, которые параллельно извлекают из биржи копии одних и тех же данных. Это позволяет избежать потери ценной информации в случае обрыва одного или сразу нескольких каналов.

CryptoAgregator.jpg

После извлечения данных они передаются компоненту Deduplicator. Его основная задача в том, чтобы отбросить дубликаты сообщений. Например, если данные поступают тремя потоками, Deduplicator пропускает через себя лишь одно из трёх дублирующихся событий. Если один или два компонента Gate выйдут из строя, мы не потеряем важную информацию, так как она будет поступать в Deduplicator по третьему каналу. Собранные данные передаются в Kafka. Дальше с информацией работают аналитики клиента.

Эксперты Sibedge тщательно выбирали подходящие для системы технологии. Нужно было добиться максимальной производительности, учитывая колоссальную нагрузку, с которой предстояло иметь дело. В итоге выбор остановился на Java, Spring Framework, Kafka, Kafka Streams, Apache Avro и Kryo. Именно эти технологии продемонстрировали лучшую производительность и надёжность в процессе стресс-тестов.

Разработка

Эмулятор криптобиржи

Нужно было продемонстрировать клиенту практическую осуществимость создания подобной системы. Текущая нагрузка современных криптобирж не превышает 40 000 событий в секунду. Но перед инженерами Sibedge стояла цель достигнуть обработки 600 000 событий в секунду от каждой биржи. Такой большой запас нужен, чтобы в будущем, когда количество пользователей бирж возрастёт, система продолжала исправно работать.

Для проведения стресс-тестов был написан эмулятор криптобиржи, на котором изучалось поведение системы при необходимых целевых нагрузках. Разработчики получили возможность изменять количество событий в секунду, симулировать обрывы веб-соединений, экспериментировать с количеством потоков считывания данных и многое другое.

Передача и формат данных

Любой обмен данными связан с процессами сериализации (передачей) и десериализации (получением). В ходе сериализации данные преобразуются в битовую последовательность, передаются между компонентами системы, после чего начинается десериализация — биты вновь преобразуются в информацию, с которой удобно работать приложениям и персоналу.

Криптобиржи используют формат данных JSON. Он обладает простой и понятной человеку структурой, легко редактируется и максимально кроссплатформенный. Из множества решений для парсинга JSON разработчикам методом проб и ошибок предстояло выбрать оптимальное.

Оптимизация производительности

Изначально для достижения целей разработчики выбрали Java-библиотеку Jackson: она быстрая и гибкая, с ней просто начать работать. Но на практике оказалось, что пропускной способности системе не хватало. Бутылочным горлышком стали сериализация сообщений при записи в файл и отправке в Kafka, а также десериализация JSON-сообщений от биржи.

На смену Jackson пришла библиотека DSL-JSON. Вместо использования общих методов, она генерирует уникальные методы для каждой конкретной структуры JSON. Её использование позволило добиться дополнительного выигрыша в скорости — до 66% в сериализации и 40% в десериализации. Но в итоге было решено отказаться и от неё.

Дальнейшая оптимизация привела разработчиков к решению передавать данные не в виде текста, а в бинарном формате. Для десериализации бинарный формат не использовался, так как формат приходящих от биржи данных разработчики контролировать не могли. Решили использовать фреймворки Apache Avro (сериализация в Kafka) и Kryo (сериализация в файлы). Сериализация по сравнению с Jackson ускорилась в 3,42 раза.

Параллельно проводились исследования по достижению максимальной производительности при десериализации JSON-сообщений, поступающих от биржи. Именно этот процесс расходовал большую часть вычислительной мощности CPU. Слабое место библиотечных решений — ориентация на максимально общий случай. Их удобно использовать, но максимальная производительность при этом сильно ограничивается.

В итоге разработчики пришли к решению написать собственный парсер, который не использует сторонних библиотек для работы с JSON. Это позволило добиться максимальной производительности при следующих условиях:

  • Отказ от поддержки Unicode в пользу ASCII-символов.
  • Сообщения от бирж должны быть правильно сформированы, чтобы избавиться от расходов на проверку текстовой структуры.
  • Формат сообщений должен быть заранее известен.

Это открыло дополнительные возможности для оптимизации. Парсер позволяет осуществлять быстрый поиск нужных данных по одному символу, быстрое определение имени свойства в JSON по одному-двум символам вместо полного анализа имени, а также предоставляет возможность «предсказать» длину нужного участка сообщения.

Для подключения к системе новых бирж нужно писать парсеры длиной от 100 до 500 строк Java-кода. Они выбрасывают из получаемых сообщений всю лишнюю информацию и передают системе лишь нужные данные, что значительно увеличивает производительность. Этот подход оказался в 1,2 раза быстрее, чем DSL-JSON, и в 3 раза быстрее, чем Jackson.

Результат

Разработчикам удалось достичь пиковой нагрузки в 400 000 событий в секунду от одной биржи. Это всё ещё далеко от целевых 600 000, но гораздо выше текущего показателя Binance в 40 000 событий. Deduplicator изначально обрабатывал 800 000 событий. Этого было недостаточно, учитывая, что данные поступали от нескольких компонентов Gate. Его код был полностью переписан, что позволило достичь пиковой нагрузки в 2 500 000 событий в секунду.

Клиент решил остановиться на достигнутых результатах, посчитав, что такого запаса пропускной способности системы хватит на ближайшие годы. В декабре 2022 года, после того, как была подготовлена необходимая инфраструктура, агрегатор запустили в эксплуатацию и подключили к четырём крупным криптобиржам.

Система продолжает улучшаться и обрастать новыми функциями. Например, инженеры Sibedge разрабатывают кодогенератор, который автоматически создаёт парсеры для новых бирж. В будущем продолжится процесс оптимизации, чтобы повысить стрессоустойчивость решения под постепенно растущими нагрузками. В ближайшее время к системе планируется подключить несколько новых бирж.