Low-latency оптимизации на всех уровнях торговой системы

В предыдущей статье я говорил об оптимизации вообще, а теперь приведу несколько советов по low-latency оптимизациях в Java-приложениях на всех уровнях торговой системы:

  • оптимизации на уровне приложения
  • настройка JVM
  • операционная система
  • аппаратный уровень: процессор, сетевой интерфейс, коммутация

Чтобы наглядно дать представление о том, через сколько «слоев» сообщение от торгового приложения должно пройти, чтобы достигнуть торгового движка биржи, взгляните на данную диаграмму.

Каждый уровень добавляет свою долю в latency и может значительно увеличивать latency, если не настроить уровень определенным образом.

На уровне самого Java-приложения

Текст этого раздела оказался настолько большим, что был вынесен в отдельную статью Принципы написания торговых low-latency приложений на Java. В ней затрагиваются темы:

  • оптимизация работы сборщика мусора
  • логирование
  • многопоточность
  • lock-free алгоритмы и структуры данных и проч.

На уровне JVM

Настройки JVM с помощью стартовых опций я описываю в отдельной статье.

  • настройки heap
  • настройки сборщика мусора
  • настройки JIT-компилятора
  • прочие настройки

На уровне операционной системы

Выбор ОС

Наиболее популярной операционной системой является Linux. Из всех дистрибутивов Linux наиболее популярным являются Red Hat Enterprise Linux (RHEL) и его открытый вариант CentOS. Версия CentOS тоже играет роль, но нет пока никаких доказательств, что свежая версия всегда лучше предыдущей. Скорее бывает даже наоборот: новая версия дистрибутива приносит с собой какие-то новые настройки, которые могут снижать производительность системы, и если вы не догадываетесь о существовании этих настроек, после обновления ОС ваша торговая система будет работать медленнее.

Выбор версии

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

Используйте самые свежие драйвера для сетевой карты.

Выбор драйверов

Если используется Solarflare сетевая карта, воспользуйтесь драйверами и функцией Open Onload, которая позволяет обходить TCP/IP стек операционной системы и ее системные вызовы при передаче данных, и позволяет сетевой карте писать данные прямо в user-space вашего приложения, а вашему приложению — напрямую общаться с стевой картой, минуя ядро операционной системы. Этот механизм называется TCP-offload или kernel bypass. Очень эффективно снижает зажержки на копирование данных из буфера в буфер между user-space и kernel-space, переключение контекста и системные вызовы.

Отключите у операционной системы все некритические и ненужные сервисы.

Отключите у операционной системы заплатки от Spectre и Meltdown. Заплатки предназначены для защиты систем, где работают несколько пользователей. Вы своей торговой системой владеете безраздельно. Защитите ее от доступа извне другими способами, а в самой системе снимите все барьеры. Заплатки от Spectre и Meltdown легко могут съесть 20-30% производительности вашего приложения так как препятствуют процессору использовать многие техники, ускорявшие исполнение кода.

Изоляция и привязка процессов: Современные сервера имеют несколько многоядерных процессоров — чаще два. Идеально — запускать приложение только на одном процессоре (affinity), отдавая второй CPU под задачи и сервисы операционной системы. Привязка процесса осуществляется с помощью утилит cgroups и taskset. Предоставление данного CPU только данному процессу (isolation) выполняется с помощью утилит cgroups и isocpu. Более подробно об этом написано в отдельной статье о многозадачной операционной системе. Демонстрация работы утилиты taskset представлена в отдельной статье блога.

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

  • с помощью cgroups
  • с помощью утилиты numactl
  • с помощью параметра JVM -XX:UseNUMA, сообщающего JVM, что процесс работает на NUMA-машине

На аппаратном уровне

BIOS

Отключить в BIOS энергосберегающий режим. Все ядра процессора должны работать в идеале в Turbo режиме. Изнашивается от такой работы процессор быстрее, но ради прибыли ничего не жалко.

Процессор

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

Чаще всего выбирают процессоры Intel семейства Xeon, так как они стандартно ставятся в серверные решения от ведущих поставщиков производительных решений: большое количество ядер, поддержка памяти с коррекцией ошибок, поддержка сопряжения большого количества процессоров, высокие тактовые частоты, минимум лишнего, что на сервере и не нужно. Недавно AMD-процессоры тоже стали предлагать — получается дешевле, но как-то Intel пока еще держит планку.

Начинайте свой выбор минимум с Sandy Bridge и выше. Существует поверие, что каждое новое поколение процессоров Intel прибавляет 15%-17% производительности. Мои измерения с помощью JMH одного и того же кода на разных машинах вроде бы подтверждают это утверждение. Здесь трудно что-то советовать, так как все зависит от бюджета вашего проекта.  Уверяю вас даже из Sandy Bridge 7-летней давности можно выжать рекордные latency, если хорошо постараться. Помните 3 ГГц — это (очень приблизительно) 3 миллиарда инструкций в секунду! На каждом ядре многоядерного процессора! Это очень много, даже в 2019 году. Какие такие сложные вычисления в вашем приложении могут потребовать 3 миллиардов инструкций, чтобы оно выполняло его 1 секунду?

Какую бы архитектуру процессора вы не выбрали, очень советую основательно разузнать по документации все её характеристики, размеры кэша всех уровней, особенности реализации. Это пригодится при написании кода по принципу mechanical sympathy: часто оказывается что код, который работает быстро на, скажем, стареньком Sandy Bridge, начинает тормозить на более свежем Haswell.

Сетевой интерфейс

В современных серверах PCI-слоты, куда ставятся сетевые карты, распределены так, что часть из них находятся «ближе» к CPU0, а другие — к CPU1. Сетевая карта должна располагаться в слоте, который ближе к процессору, на котором будет крутиться приложение.

PCI-слоты могут поддерживать разное количество lane. При установке сетевой карты надо убедиться не только в том, что вы ставите карту в слот, который ближе к нужному вам процессору, но и в слот, количество lane, которого совпадает с lane вашей сетевой карты.

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

Некоторые Solarflare имеют также FPGA модули, которые позволяют на аппаратном уровне фильтровать пакеты. Но это уже высший пилотаж программирования на уровне VHDL. Главный конкурент Solarflare — компания Mellanox, которая, увы, пока не дотягивает, и еще Exablaze.

Сетевой кабель

В настоящее время наиболее популярным решением является волоконно-оптический кабель от вашей сетевой карты до вашего коммутатора, который располагается в той же стойке, где находится ваш компьютер. Скорость передачи может быть любой, но наиболее часто выбирают скорость 10 Gbit/sec. Нередки случаи, когда выбирают скорость 40 Gb/sec. Но здесь есть один нюанс, о котором речь пойдет ниже.

Сетевой коммутатор

Это последний слой, рубеж, на который распространяется ваша юрисдикция. Сетевой кабель от него до сетевого коммутатора биржи уже выбирает сама биржа. И это сетевое соединение может оказаться медленнее соединения с вашей стороны. То есть вы можете потратить огромные силы и средства на доставку сообщения с немыслимой скоростью от торгового приложения до вашего state-of-the-art сетевого коммутатора по 100 Gb/sec волоконно-оптическому кабелю, а дальше сообщение пойдет на биржу, например, по обычному медному кабелю, нивелируя все ваши усилия.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s