12 февр. 2025 г.·8 мин

Низколатентный сервер для финансовых приложений: замеры

Низколатентный сервер для финансовых приложений: как поставить стенд, измерить задержку и джиттер, и какие настройки BIOS и железа дают максимум эффекта.

Низколатентный сервер для финансовых приложений: замеры

Что именно измеряем: латентность и джиттер простыми словами

Задержка (латентность) - это время от момента, когда событие произошло, до момента, когда система на него отреагировала. В финансовых задачах это часто выглядит так: пакет пришел по сети, приложение обработало его, и ответ ушел обратно. Здесь важна не только средняя задержка, но и то, как часто система ведет себя хуже обычного.

Поэтому почти всегда смотрят несколько чисел. Среднее удобно для общей картины, но оно прячет редкие, зато болезненные всплески. Гораздо полезнее 99-й перцентиль (P99) - задержка, которую система не превышает в 99% случаев. Отдельно фиксируют худший случай (max), потому что именно он часто объясняет внезапные проскальзывания и пропуски по срокам.

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

Микросекунды обычно теряются не в одном месте, а по цепочке: в планировании CPU, ожидании памяти, обработке сетевой карты, драйверах и фоновых задачах ОС. Иногда вклад дает диск, если в горячем пути есть синхронные записи или агрессивное логирование.

Перед любыми настройками зафиксируйте базовые метрики. Минимальный набор:

  • среднее, P95, P99 и max для задержки
  • джиттер (например, разница между P99 и медианой)
  • загрузка CPU и частота (нет ли просадок)
  • сетевые счетчики: потери, ретрансляции, ошибки
  • версии BIOS/UEFI, ОС и драйверов как паспорт стенда

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

Сформулируйте тест так, чтобы он был похож на прод

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

Сначала определите, что именно вы тестируете: шлюз заявок (например, FIX), риск-контроль на входе, обработку market data или внутреннюю маршрутизацию событий. У каждого пути своя горячая часть и свои узкие места. Один и тот же сервер может показывать отличный результат на пинге, но проваливаться на реальном потоке сообщений.

Нагрузку задавайте так, как она выглядит в бою: размер сообщений, частота, всплески и параллельность. Важно зафиксировать и форму трафика: ровный поток и короткие пики ведут себя по-разному. Если в проде заявки идут пачками на новостях, моделируйте именно это.

Перед первым прогоном ответьте на несколько вопросов:

  • какой путь измеряем: клиент - сервер - ответ или только внутри сервера
  • где границы замера: сеть отдельно, приложение отдельно или все вместе
  • какие метрики считаем проходными: p50, p99, p99.9, максимум за окно
  • какая длительность теста и нужен ли прогрев перед замером
  • какие пики критичны (например, не больше X мкс чаще чем раз в минуту)

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

Как собрать стенд для измерений и не запутаться

Чтобы измерения задержки были полезны, стенд должен быть простым и повторяемым. Цель одна: убрать лишние переменные, чтобы вы видели разницу от железа и настроек, а не от случайных факторов.

Минимальный состав стенда обычно такой: генератор трафика (или отдельный хост, который шлет запросы), тестовый сервер, коммутатор и точный таймер. Таймером может быть аппаратная метка времени на NIC или внешний измеритель. Даже при программных замерах важно фиксировать, где именно стоит метка: на отправке, на приеме или внутри приложения.

Хорошая практика - выделить отдельную сеть только под тест. Один коммутатор, короткие одинаковые кабели, без лишних VLAN и без параллельного трафика. На генераторе и на сервере отключите все, что создает фон: автообновления, лишние агенты мониторинга, бэкапы, индексацию, антивирусные проверки. Иначе вы начнете оптимизировать не сервер, а шум вокруг него.

Повторяемость держится на дисциплине версий. Запишите и заморозьте: BIOS/UEFI, прошивку NIC, микрокод CPU, версию драйвера, версию ОС и конфигурацию ядра. Если меняете что-то одно, остальное должно оставаться прежним, иначе выводы будут спорными.

Чтобы не утонуть в итерациях, держите простое правило: один набор настроек - один прогон - один лог. В логе сохраняйте не только p50/p99 и джиттер, но и паспорт прогона: дата, температура в серверной или стойке, частоты CPU под нагрузкой, версии прошивок и параметры BIOS.

Пример стенда для торгового шлюза: отдельный генератор на втором сервере, тестируемый узел на стойковом сервере (например, из класса S200), между ними один коммутатор. Так проще понять, что реально улучшило задержку: смена NIC, настройки BIOS для минимальной латентности или банальная уборка фоновых процессов.

Инструменты измерения: от приложения до системы

Начинайте с измерения, которое ближе всего к пользователю, а затем спускайтесь ниже. Так проще понять, где именно теряются микросекунды: в коде, в сети или внутри ОС.

Самый простой вариант - измерять round-trip (RTT) на уровне приложения: отметили время отправки, получили ответ, посчитали разницу. Это быстро и повторяемо, и показывает то, что действительно видит торговая логика. Минус в том, что RTT складывает все задержки вместе, и отделить сеть от обработки становится сложнее.

Если важна именно сеть, стремитесь к one-way замерам (в одну сторону). Но это имеет смысл только при точной синхронизации времени между двумя машинами, например PTP с подходящим оборудованием. Иначе вы получите красивую цифру, которая отражает дрейф часов, а не латентность.

На уровне системы полезно смотреть не только сколько, но и почему. Обычно помогают три наблюдения: задержки планировщика (как быстро поток получает CPU), прерывания и их распределение по ядрам (IRQ и softirq), а также сетевой стек (очереди, дропы, коалесинг, распределение по NUMA).

Практичный набор инструментов для стенда обычно такой: метрики и тайминги в приложении (p50/p99/p99.9), системные счетчики и трассировка (perf/ftrace), а для сети - capture и счетчики интерфейса (ethtool, nstat, ss). Смысл не в количестве утилит, а в том, чтобы один слой подтверждал выводы другого.

Чтобы замеры можно было сравнивать, в отчете фиксируйте паспорт стенда. Минимум:

  • версия ОС и параметры загрузки ядра
  • модель и версия драйвера NIC, прошивка
  • частоты CPU (база и турбо), включенные C-states и P-states
  • топология NUMA: на каком сокете NIC и где выполняется процесс

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

Пошаговый план измерений: базовая линия и итерации

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

Сначала приведите стенд в стабильное состояние: одинаковые версии ОС и драйверов, одинаковый набор запущенных сервисов, один и тот же тест и входные данные. Базовую линию снимайте на настройках по умолчанию (BIOS и ОС без тонкой правки), чтобы было с чем сравнивать.

Дальше работайте итерациями. Удобный порядок:

  • снимите базовую линию: 5-10 прогонов одного теста одинаковой длительности
  • выберите один параметр (профиль питания, режим Turbo, настройка NUMA) и измените только его
  • повторите те же 5-10 прогонов и сравните распределение задержки
  • если эффект есть, закрепите изменение и переходите к следующему
  • если эффекта нет или вырос разброс, откатите и пометьте как нецелевое

Смотрите не только среднее. Для финансовых приложений часто решают хвосты, поэтому фиксируйте хотя бы p50, p99, max, джиттер между прогонами и ошибки (если тест их показывает).

И обязательно проверяйте разные режимы нагрузки. На холостом ходу чаще всплывают проблемы энергосбережения и просыпания. На средней нагрузке видно планирование и конкуренцию за ресурсы. На пике проявляются очереди, прерывания и перегрузка. Один красивый прогон почти всегда обманывает; стабильность важнее рекорда.

Железо, которое сильнее всего влияет на задержку

Расчет для торгового контура
Получите расчет по стойковому серверу GSE S200 под ваш сценарий нагрузки.
Запросить расчет

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

CPU: стабильная частота и ровные ядра

Процессор часто дает самый заметный вклад. Высокий турбо может помочь в среднем, но в стендовых замерах больнее бьет просадка частоты из-за энергосбережения, лимитов по питанию или температуры. Чем стабильнее частота под постоянной нагрузкой, тем короче хвосты на p99 и p99.9.

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

Память: каналы и равномерность важнее модных цифр

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

PCIe и сеть для торговых систем критичны. Нужны достаточные PCIe-линии для NIC, правильный слот и предсказуемые прерывания. Если сетевой адаптер делит линии с другими устройствами или попадает в перегруженный корневой комплекс, вы увидите редкие, но неприятные пики.

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

Перед замерами полезно пройтись по простому мини-чеку: убедиться в стабильности частоты CPU под типовой нагрузкой, проверить равномерность заполнения каналов памяти, посмотреть, где стоит NIC и нет ли конкурентов по линиям, а также разделить горячий путь и фоновые записи на диск.

На стенде удобно сравнивать одинаковые конфигурации, меняя по одному фактору и фиксируя не только среднее, но и p99/p99.9.

Настройки BIOS/UEFI, которые обычно дают самый заметный эффект

BIOS/UEFI часто дает больше выигрыша по стабильности задержек, чем точечные твики в ОС. В низколатентных контурах важнее предсказуемость: меньше редких всплесков и меньше джиттера.

Энергосбережение: главный источник джиттера

Энергосберегающие режимы хороши для офисных нагрузок, но плохи для коротких и частых событий, как обработка рыночных данных. C-states (глубокий сон) и агрессивные P-states (скачки частоты) добавляют микрозадержки, которые потом видны как хвосты в распределении.

Практичный подход: включить профиль максимальной производительности в BIOS/UEFI, ограничить или отключить глубокие C-states, оставить управление частотой в более предсказуемом режиме. Turbo иногда снижает среднюю задержку, но может ухудшить стабильность, если процессор часто меняет частоту из-за лимитов питания и температуры.

Потоки, память и ввод-вывод

SMT/Hyper-Threading иногда помогает при большом числе параллельных задач, но в низколатентных контурах способен добавлять непредсказуемость из-за конкуренции за ресурсы одного ядра. Обычно разумно сравнить два режима на стенде: SMT включен и SMT выключен, и смотреть не только среднее, но и 99.9 перцентиль.

NUMA особенно важна на двухсокетных системах. Если поток обработки пакетов работает на одном сокете, а память и PCIe-устройство оказались на другом, задержка растет и становится рваной. Проверьте топологию и старайтесь, чтобы сеть, CPU и память были в одном NUMA-домене.

PCIe-энергосбережение (ASPM и похожие режимы) для сетевых адаптеров и критичных устройств обычно лучше отключать. Иначе линк может уходить в экономичный режим и добавлять микросекунды именно после коротких простоев.

Настройки, которые обычно проверяют первыми (по одной за раз, с повторными прогонами):

  • C-states: ограничить или отключить глубокие состояния
  • P-states и профиль питания: режим максимальной производительности
  • SMT/Hyper-Threading: сравнить включено и выключено
  • NUMA: режим, соответствующий реальной топологии, без случайных переносов
  • PCIe ASPM: отключить для низколатентного ввода-вывода

На стенде торгового шлюза вы нередко увидите, что после отключения глубоких C-states средняя задержка почти не меняется, но редкие пики (которые ломают SLO) становятся заметно ниже. Именно такие изменения дают реальную пользу в продакшене.

ОС и драйверы: что проверить до тонкой оптимизации

Сервер под ваши метрики
Подберем конфигурацию под ваши p99 и джиттер, с учетом NUMA, NIC и BIOS.
Подобрать сервер

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

Закрепление процессов и изоляция ядер

Начните с того, где именно выполняется ваш путь запроса. Критические процессы (шлюз, обработчик рыночных данных, риск-проверки) лучше закрепить за конкретными CPU-ядрами, а шумные системные задачи увести на другие.

Если этого не сделать, планировщик будет мигрировать потоки между ядрами. Это дает промахи кэша и рост джиттера. Отдельно проверьте, что IRQ сетевой карты не конкурируют с главным потоком на том же ядре.

NIC, прерывания и фон

Сетевая карта часто становится источником сюрпризов: одно ядро перегружено прерываниями, другое простаивает, а задержка прыгает.

Перед тонкой настройкой полезно сделать несколько проверок:

  • разнести IRQ и очереди NIC по ядрам так, чтобы сетевые ядра не совпадали с ядрами критического процесса
  • отключить или ограничить фоновые службы, которые периодически просыпаются (обновления, индексация, лишние агенты мониторинга)
  • убрать избыточное логирование на горячем пути (особенно синхронные записи и подробный debug)
  • проверить драйвер NIC: версию, режимы offload и принцип менять по одному параметру за раз

Частоты, governor и троттлинг

Профиль производительности должен быть предсказуемым. Убедитесь, что частоты не плавают, нет перегрева и троттлинга.

Типовой сценарий ошибки: на стенде все хорошо, но через 15 минут под нагрузкой температура растет, частота падает, и p99 задержки ухудшается. Поэтому важны не только пиковые цифры, но и стабильность на длительном прогоне.

Частые ошибки, которые портят замеры и выводы

Главная причина магических улучшений в низкой латентности - плохая дисциплина измерений. Цифры выглядят убедительно, но на деле вы сравниваете разные условия или ловите случайность.

Самая частая ловушка - смешивать результаты разных тестов. Один прогон меряет round-trip по сети, другой - только обработку внутри приложения, третий - время на диске. Если меняется хотя бы один кусок цепочки, сравнение теряет смысл.

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

Часто портит картину одновременное изменение нескольких параметров. Поменяли профиль питания, выключили C-states и обновили драйвер сетевой карты - эффект есть, но причина неизвестна. Это превращает настройку в гадание.

И почти всегда недооценивают хвосты. Среднее и p50 могут улучшиться, но p99.9 вырастет из-за редких затыков. А в финансовых приложениях именно хвосты становятся заметными как проскальзывание и тайм-ауты.

Наконец, перегрев и троттлинг. Первые 5 минут все красиво, потом частота падает, растет джиттер, и вы получаете ложный оптимизм. Это особенно опасно на плотных серверных конфигурациях.

Короткий чек, который стоит держать рядом:

  • сравнивайте только одинаковый сценарий и одинаковую метрику (один и тот же путь запроса)
  • фиксируйте состояние системы: холодный старт отдельно, прогретый режим отдельно
  • меняйте за итерацию один параметр и записывайте, что именно меняли
  • смотрите p95, p99 и p99.9, а не только среднее
  • контролируйте температуру, частоты и признаки троттлинга на всем прогоне

Пример: вы отключили энергосбережение в BIOS и увидели минус 8% по среднему. Если при этом p99.9 стал хуже, а через 20 минут начался троттлинг, в проде итог будет обратным: редкие, но болезненные задержки.

Короткий чеклист перед тем, как верить цифрам

Замеры латентности легко сломать мелочами. Один прогон может выглядеть отлично, а на следующем из-за обновленного драйвера или другой частоты CPU цифры уже не сравнимы. Перед тем как делать выводы и тем более выбирать железо, пройдитесь по контролю качества.

Сначала зафиксируйте окружение: версии BIOS/UEFI, прошивок (включая сетевую карту), ОС, драйверов и важных пакетов. Если что-то обновили, это должен быть отдельный прогон с новой меткой.

Дальше снимайте не только среднее, а хвосты: p50, p95, p99, p99.9 и максимум. Рядом полезно записать загрузку CPU, число контекстных переключений и статистику по прерываниям (IRQ), чтобы понимать источник редкого шипа.

Проверьте частоты CPU под нагрузкой: важно, чтобы частота не прыгала неожиданно и не было троттлинга по температуре или питанию. Иначе вы сравниваете не настройки, а разные режимы работы процессора.

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

И наконец, сохраняйте состояние: профиль BIOS (или экспорт настроек), параметры запуска теста, pinning/affinity, результаты каждого прогона в одном формате. Тогда можно откатиться и честно сравнить до и после.

Простой пример: вы поменяли настройку BIOS и получили минус 3 мкс по p50, но p99.9 стал хуже. Без хвостов, частот и IRQ легко решить, что стало быстрее, хотя для торгового шлюза важнее стабильность.

Пример реального сценария: стенд для торгового шлюза

Интеграция низколатентной платформы
GSE выполнит системную интеграцию и соберет контур под ваши требования по задержке.
Заказать интеграцию

Представьте торговый шлюз, который принимает заявки из одного сетевого сегмента (внутренняя сеть) и отправляет их в другой (биржевой или провайдерский сегмент). Цель формулируем заранее и просто: p99.9 задержки обработки заявки не выше заданного порога, а джиттер должен быть предсказуемым, без редких длинных хвостов.

Стенд собираем так, чтобы путь пакета был похож на боевой: две NIC (или два порта), отдельная машина-генератор нагрузки и отдельная машина-приемник. Сам шлюз запускаем на сервере, который по классу соответствует планируемому продакшену, но без лишних сервисов.

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

Второй прогон - правки BIOS/UEFI, которые чаще всего дают заметный эффект: отключение агрессивного энергосбережения, фиксация предсказуемых частот, корректный профиль производительности. После каждого изменения повторяем тот же тест, той же длительности, в той же схеме.

Третий прогон - работа с NUMA и прерываниями NIC. Закрепляем процесс шлюза и его сетевые прерывания ближе к своему NUMA-узлу и ядрам, сравниваем именно хвосты (p99.9 и максимум), а не только среднее.

Чтобы выводы было легко проверить, сведите итог в одну таблицу (заполните своими цифрами):

ПрогонИзменениеp99.9МаксимумДжиттер (описание хвоста)Примечание
1Дефолт
2BIOS: питание и частоты
3NUMA + IRQ NIC

Следующие шаги: как перейти от стенда к стабильному продакшену

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

Соберите требования заранее: какие перцентили важны (p99 и p99.9), какая сеть и топология будут в бою, какой профиль нагрузки ожидается (пики, бурсты, равномерный поток), какой запас по мощности допустим. После этого составьте план испытаний, где каждый шаг оставляет след: что поменяли, зачем и какой эффект получили.

Перед выкаткой сделайте паспорт конфигурации и придерживайтесь его в поставке и эксплуатации:

  • целевые метрики и пороги по перцентилям, плюс допустимый джиттер
  • фиксируемые параметры: профиль BIOS/UEFI, версии прошивок, драйверов, ОС
  • схема сети: скорость, MTU, количество хопов, настройки коммутатора
  • регламент изменений: кто может менять настройки и как это проверяется
  • план наблюдаемости: что мониторим постоянно и как ищем регресс

Отдельно имеет смысл попросить поставщика помочь с BIOS-профилем и воспроизводимыми стендовыми замерами. Это экономит недели: у вендора часто уже есть проверенные комбинации настроек под низкую латентность.

Если важны локальный производитель, прозрачная поставка и интеграция под ваш контур, можно рассмотреть серверы GSE S200 и услуги системной интеграции GSE.kz (gse.kz). В таких проектах особенно ценна возможность согласовать единый профиль настроек и закрепить его в поставке, установке и дальнейшей поддержке.

Низколатентный сервер для финансовых приложений: замеры | GSE