Расчёт ресурсов и производительность
Типичные показатели использования CPU: в режиме TCP или HTTP с закрытием соединений на HAProxy приходится 15% времени обработки, а на ядро — 85%; в режиме постоянных соединений HTTP на HAProxy приходится около 30%, а на ядро — 70%. Это означает, что операционная система и её настройка сильно влияют на общую производительность.
Сценарии использования сильно различаются: одни пользователи ориентируются на пропускную способность, другие — на интенсивность запросов, число одновременных соединений или производительность SSL. В этом разделе приведены некоторые сведения, помогающие оценить необходимые ресурсы.
Важно помнить, что любая операция требует затрат: накладные расходы каждой операции прибавляются к остальным. В одних обстоятельствах они могут быть пренебрежимо малы, а в других — преобладать.
При обработке запросов в рамках соединения можно утверждать следующее:
Пересылка данных требует меньше ресурсов, чем разбор заголовков запроса или ответа.
Разбор заголовков запроса или ответа требует меньше ресурсов, чем установка и последующее закрытие соединения с сервером.
Установка и закрытие соединения требуют меньше ресурсов, чем возобновление TLS.
Возобновление TLS требует меньше ресурсов, чем полное рукопожатие TLS с вычислением ключа.
Бездействующее соединение потребляет меньше CPU, чем соединение, в буферах которого есть данные.
Контекст TLS требует ещё больше памяти, чем соединение с данными.
На практике обработка байтов полезной нагрузки обходится дешевле обработки байтов заголовков, поэтому высокой пропускной способности сети проще добиться с большими объектами (мало запросов на единицу объёма), чем с маленькими (много запросов на единицу объёма). Этим объясняется, почему максимальную пропускную способность всегда измеряют на больших объектах, а интенсивность запросов или соединений — на маленьких.
Некоторые операции хорошо масштабируются при использовании нескольких процессов на разных CPU, другие — хуже. Пропускная способность сети масштабируется лишь до определённого предела, поскольку для больших объектов узким местом редко бывает CPU: обычно ограничение задают сеть и шины данных, по которым передаются данные к сетевым интерфейсам. Интенсивность соединений плохо масштабируется на несколько процессоров из-за ряда системных блокировок при работе с таблицей локальных портов. Интенсивность запросов по постоянным соединениям масштабируется очень хорошо: такие запросы не требуют большого объёма памяти или пропускной способности сети и не обращаются к структурам с блокировками. Вычисление ключей TLS также отлично масштабируется, поскольку полностью ограничено ресурсами CPU. Возобновление TLS масштабируется умеренно хорошо, но примерно на 4 процессах достигает предела: накладные расходы доступа к общей таблице нивелируют небольшой выигрыш от дополнительных вычислительных ресурсов.
От хорошо настроенной системы можно ожидать показателей производительности в приведённых ниже пределах. Их важно воспринимать как порядок величин и учитывать возможные значительные отклонения в обе стороны в зависимости от процессора, настройки IRQ, типа памяти и сетевого интерфейса, настройки операционной системы и прочих факторов.
Следующие результаты получены на Core i7 с частотой 3.7 GHz и двухпортовыми сетевыми адаптерами 10 Gbps под управлением ядра Linux 3.10, HAProxy 1.6 и OpenSSL 1.0.2. HAProxy работал одним процессом на одном выделенном ядре CPU, а ещё два ядра были выделены для сетевых прерываний:
Максимальная пропускная способность сети без шифрования — 20 Gbps для объектов размером 256 kB и больше, 10 Gbps для объектов размером 41kB и больше.
4.6 Gbps трафика TLS с шифром AES256-GCM на больших объектах.
83000 соединений TCP в секунду от клиента до сервера.
82000 соединений HTTP в секунду от клиента до сервера.
97000 запросов HTTP в секунду в режиме server-close (постоянное соединение с клиентом, закрытие соединения с сервером).
243000 запросов HTTP в секунду в режиме постоянных соединений на всём пути.
300000 отфильтрованных соединений TCP в секунду (защита от DDoS).
160000 запросов HTTPS в секунду в режиме постоянных соединений поверх постоянных соединений TLS.
13100 запросов HTTPS в секунду с возобновляемыми соединениями TLS.
1300 соединений HTTPS в секунду с повторным согласованием соединений TLS с использованием RSA2048.
20000 одновременных полностью загруженных соединений на GB оперативной памяти, включая память системных буферов. Тщательная настройка позволяет улучшить этот показатель, но такого результата легко достичь.
Около 8000 одновременных соединений TLS (только со стороны клиента) на GB оперативной памяти, включая память системных буферов.
Около 5000 одновременных сквозных соединений TLS (с обеих сторон) на GB оперативной памяти, включая память системных буферов.
В более новом тесте многопоточный HAProxy 2.4 на 64-ядерном процессоре ARM Graviton2 в AWS достиг 2 миллионов запросов HTTPS в секунду при времени ответа менее миллисекунды и объёме трафика 100 Gbps:
Полезный практический ориентир: интенсивность запросов уменьшается в 10 раз при переходе от постоянных соединений TLS к возобновлению TLS и от возобновления TLS к повторному согласованию TLS, тогда как при переходе от постоянных соединений HTTP к закрытию соединений HTTP она уменьшается лишь в 3 раза. Ещё один ориентир: высокочастотное ядро с инструкциями AES может обрабатывать около 20 Gbps AES-GCM на ядро.
Также полезно учитывать, что на том же сервере HAProxy способен полностью загрузить:
около 5-10 серверов статических файлов или кеширующих прокси;
около 100 антивирусных прокси;
около 100-1000 серверов приложений в зависимости от используемой технологии.