Высокочастотная торговля в JVM с помощью Scala/Akka
Представьте себе гипотетическую систему HFT на Java, требующую (очень) низкой латентности, с небольшим количеством короткоживущих мелких объектов из-за неизменности (Scala?), тысяч подключений в секунду и непристойного числа сообщения, проходящие вокруг в управляемой событиями архитектуре (akka и amqp?).
Для экспертов, что бы (гипотетически) было лучшей настройкой для JVM 7? Какой код сделает его счастливым? Готовы ли Scala и Akka к таким системам?
Примечание. Были некоторые аналогичные вопросы, такие как один, но я еще не нашел одно покрытие Scala (у которого есть свой собственный индивидуальный след в JVM).
Ответы
Ответ 1
На моем ноутбуке средняя латентность сообщений ping между актерами Akka 2.3.7 ~ 300ns и намного меньше ожидаемой задержки для GC приостанавливается на JVM.
Код (включая опции JVM) и результаты тестов для Akka и других участников на Intel Core i7-2640M здесь.
P.S. Вы можете найти множество принципов и советов для низкозатратных вычислений на сайте Дмитрия Вюкова и в Martin Thompson blog.
Ответ 2
В Java можно добиться очень хорошей производительности. Однако этот вопрос должен быть более конкретным, чтобы дать надежный ответ. Ваши основные источники латентности будут поступать из следующего неисчерпывающего списка:
-
Сколько мусора вы создаете и работа GC для сбора и
продвигать его. Неизменяемые конструкции по моему опыту не подходят
с низкой задержкой. Настройка GC должна быть большой фокус.
-
Разбавьте JVM, чтобы классы загружались и JIT имел время
выполнять свою работу.
-
Создайте свои алгоритмы как O (1) или, по крайней мере, O (log2 n), и
которые утверждают это.
-
Ваш дизайн должен быть заблокирован и следовать " Single Writer
Принцип".
-
Необходимо предпринять значительные усилия для понимания всего
стек и показывая механическую симпатию в его использовании.
-
Создайте свои алгоритмы и структуры данных, чтобы они были дружественными к кэшу.
Кэш, пропустивший эти дни, является самой большой ценой. Это близко
связанный с сродством к процессу, который, если он не настроен правильно, может привести к
и значительное загрязнение кеша. В некоторых случаях это будет означать симпатию к ОС и даже некоторый код JNI.
-
Убедитесь, что у вас достаточно ядер, чтобы любой поток, который
run имеет ядро, доступное без необходимости ждать.
Недавно я опубликовал блог о примерном примере такого упражнения.
Ответ 3
Вы можете обнаружить, что использование кольцевого буфера для передачи сообщений превзойдет то, что можно сделать с помощью Akka. Реализация основного кольцевого буфера, которую люди используют в JVM для финансовых приложений, называется функцией Disruptor, которая тщательно настроена на эффективность (мощность двух размеров), для JVM (без GC, без блокировок) и для современных процессоров (без ложного обмена кэш-строки).
Вот презентация с точки зрения Scala http://scala-phase.org/talks/jamie-allen-sdisruptor/index.html#1, и на последнем слайде есть ссылки на исходный материал LMAX.