Назад | Перейти на главную страницу

Веб-сервер кэширования больших файлов nginx 10/20/40 Гбит / с [достигнуто 20 Гбит / с]

В этом вопросе я хотел бы найти наилучшую возможную конфигурацию / оборудование для доставки 40 Гбит / с с одного сервера.

Ситуация

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

В настоящее время на внутренних серверах хранения хранится около 100 ТБ файлов.

Механизм кеширования реализован независимо, и этот вопрос не о самом кешировании, поскольку он работает очень хорошо - в настоящее время обеспечивает 14 Гбит / с, передает на внутренние серверы только 2 Гбит / с. Так что использование кеша хорошее.

Цель

Получите пропускную способность 40 Гбит / с или даже больше на одной машине.

Оборудование 1

Аппаратное обеспечение: Supermicro SC825, X11SSL-F, Xeon E3-1230v5 (4C/8T@3,4 ГГц), 16 ГБ оперативной памяти DDR4, 2x Supermicro 10G STGN-i1S (LACP L3 + 4)

SSD: 1x 512 ГБ Samsung, 2x 500 ГБ Samsung, 2x480 ГБ Intel 535, 1x 240 ГБ Intel S3500

Система:

Nginx:

Как видно на графиках, мы смогли увеличить скорость до 12,5 Гбит / с. К сожалению, сервер не отвечал.

Мое внимание привлекли 2 вещи. Первый - это большое количество IRQ. В этом случае у меня, к сожалению, нет графиков из / proc / interrupts. Во-вторых, высокая нагрузка на систему, я думаю, была вызвана тем, что kswapd0 не мог работать только с 16 ГБ ОЗУ.

Оборудование 2

Аппаратное обеспечение: Supermicro SC119TQ, X10DRW-i, 2x Xeon E5-2609v4 (8C/8T@1,70GHz), 128 ГБ ОЗУ DDR4, 2x Supermicro 10G STGN-i1S

SSD, Конфигурация системы такая же, как и у оборудования 1. Nginx включен (сравнение aio / sendfile).

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

Sendfile против потоков aio

Я попытался отключить sendfile и вместо этого использовать потоки aio.

против

Затем в 15:00 я снова переключился на sendfile и перезагрузил nginx (так что для завершения существующих подключений потребовалось время). Приятно, что загрузка диска (измеряется iostat) снизилась. По трафику ничего не изменилось (к сожалению, zabbix решил не собирать данные с bond0).

sendfile вкл / выкл

Просто пробовал включить / выключить отправку. Ничего не изменилось, кроме переноса прерываний.

irqbalancer как сервер / cron / отключен

Как упоминал @lsd, я попытался настроить irqbalancer для выполнения через cron:

*/5 * * * *   root    /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null

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

Я не смог найти, что было не так на графиках, и, поскольку это снова произошло на следующий день, я вошел на сервер и увидел, что одно ядро ​​было на 100% (использование системы).

Пробовал запустить irqbalance как сервис, результат все тот же.

Затем я решил использовать сценарий set_irq_affinity, и он сразу устранил проблему, и сервер снова выдвинул 17 Гбит / с.

Оборудование 3

Мы сделали обновление до нового оборудования: 2U 24 (+2) корпуса дисков (6xSFF), 2x Xeon E5-2620v4, 64GB DDR4 RAM (4x16GB модулей), 13x SSD, 2x Supermicro (с чипом Intel) сетевые карты. Новые процессоры значительно улучшили производительность.

Остается текущая настройка - sendfile и т.д. Единственное отличие состоит в том, что мы позволяем только одному процессору обрабатывать обе сетевые карты (через скрипт set_irq_affinity).

Достигнут предел 20 Гбит / с.

Следующая цель? 30 Гбит / с.


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

Есть идеи, как бороться с большим количеством SoftIRQ на процессоре?

Это не вопрос планирования емкости - у меня уже есть оборудование и трафик. Я всегда могу разделить трафик на несколько серверов (что мне и так придется делать в будущем) и решить проблему деньгами. Однако это вопрос об оптимизации системы и настройке производительности в реальном сценарии.

Отказ от ответственности: Тот же совет применим ко всем сервисам, использующим скорость более 10 Гбит / с. Включены, но не ограничиваются балансировщиками нагрузки, кэширующими серверами, веб-серверами (HAProxy, Varnish, nginx, tomcat, ...)

То, что ты хочешь сделать неправильно, не делай этого

Вместо этого используйте CDN

CDN предназначены для доставки кэшируемого статического контента. Используйте подходящий инструмент для работы (akamai, MaxCDN, cloudflare, cloudfront, ...)

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

Вместо этого масштабируйте по горизонтали

Я ожидаю, что один сервер будет обрабатывать 1–5 Гбит / с без особых настроек (примечание: обслуживает только статические файлы). 8-10 Гбит / с обычно доступны при расширенной настройке.

Тем не менее есть много жестких ограничений на то, что может выдержать одна коробка. Вы должны предпочесть масштабирование по горизонтали.

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

Есть несколько вариантов глобальной балансировки нагрузки: большинство CDN может это сделать, DNS roundrobin, балансировщики нагрузки ELB / Google ...

Давайте проигнорируем хорошие практики и сделаем это в любом случае

Понимание структуры трафика

            WITHOUT REVERSE PROXY

[request ]  user ===(rx)==> backend application
[response]  user <==(tx)===     [processing...]

Следует учитывать две вещи: полосу пропускания и направление (излучение или прием).

Маленькие файлы - это 50/50 tx / rx, потому что заголовки HTTP и служебные данные TCP больше, чем содержимое файла.

Большие файлы - это 90/10 tx / rx, потому что размер запроса незначителен по сравнению с размером ответа.

            WITH REVERSE PROXY

[request ]  user ===(rx)==> nginx ===(tx)==> backend application
[response]  user <==(tx)=== nginx <==(rx)===     [processing...]

Обратный прокси-сервер передает все сообщения в обоих направлениях. Нагрузка всегда 50/50, а общий трафик удваивается.

С включенным кешированием ситуация усложняется. Запросы могут быть перенаправлены на жесткий диск, данные которого могут быть кэшированы в памяти.

Заметка: Я проигнорирую аспект кеширования в этом посте. Мы сосредоточимся на получении в сети 10-40 Гбит / с. Зная, поступают ли данные из кеша, и оптимизация этого кеша - это еще одна тема, в любом случае она передается по сети.

Ограничения Monocore

Балансировка нагрузки - одноядерная (особенно балансировка TCP). Добавление ядер не делает его быстрее, но может замедлить его.

То же самое для балансировки HTTP с простыми режимами (например, на основе IP, URL, файлов cookie. Обратный прокси-сервер считывает заголовки на лету, он не анализирует и не обрабатывает HTTP-запросы в строгом смысле).

В режиме HTTPS расшифровка / шифрование SSL более интенсивна, чем все остальное, необходимое для проксирования. SSL-трафик может и должен быть разделен на несколько ядер.

SSL

При том, что вы все делаете через SSL. Вы захотите оптимизировать эту часть.

Шифрование и дешифрование 40 Гбит / с на лету - настоящее достижение.

Возьмем процессор последнего поколения с инструкциями AES-NI (используются для операций SSL).

Настройте алгоритм, используемый сертификатами. Есть много алгоритмов. Вам нужен тот, который наиболее эффективен на вашем ЦП (проведите сравнительный анализ), ПОКА поддерживавшийся клиентами И был достаточно безопасным (без необходимости избыточного шифрования).

IRQ и закрепление ядра

Сетевая карта генерирует прерывания (IRQ), когда есть новые данные для чтения, а ЦП не может немедленно обработать очередь. Это операция, выполняемая в ядре и / или драйверах устройств, и она строго одноядерная.

Это может быть крупнейший потребитель ЦП с миллиардами пакетов, отправляемых во всех направлениях.

Назначьте сетевой карте уникальный номер IRQ и закрепите его за конкретным ядром (см. Настройки Linux или BIOS).

Закрепите обратный прокси-сервер на других ядрах. Мы не хотим, чтобы эти две вещи мешали.

Адаптер Ethernet

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

Забудьте о встроенном адаптере на материнских платах (не важно, серверная или потребительская материнская плата), они просто отстой.

Разгрузка TCP

TCP - это очень интенсивный протокол с точки зрения обработки (контрольные суммы, ACK, повторная передача, повторная сборка пакетов, ...). Ядро выполняет большую часть работы, но некоторые операции могут быть перенесены на сетевую карту, если она ее поддерживает.

Мы не хотим просто относительно быстрая карта, мы хотим одну со всеми наворотами.

Забудьте об Intel, Mellanox, Dell, HP и т. Д. Они всего этого не поддерживают.

На столе есть только один вариант: Солнечная вспышка - Секретное оружие фирм HFT и CDN.

Мир разделен на два типа людей: "Те, кто знает SolarFlare" и "те, кто не". (первый набор строго эквивалентен"люди, которые работают в сети со скоростью 10 Гбит / с и заботятся обо всем"). Но я отвлекся, давайте сосредоточимся: D

Настройка TCP ядра

Есть варианты в sysctl.conf для сетевых буферов ядра. Что эти настройки делают или не делают. Честно говоря, не знаю.

net.core.wmem_max
net.core.rmem_max
net.core.wmem_default
net.core.rmem_default

net.ipv4.tcp_mem
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem

Игра с этими настройками - явный признак чрезмерной оптимизации (т. Е. В целом бесполезной или контрпродуктивной).

В исключительных случаях это может иметь смысл с учетом экстремальных требований.

(Примечание: 40 Гбит / с на одном устройстве - это чрезмерная оптимизация. Разумный путь - горизонтальное масштабирование.)

Некоторые физические ограничения

Пропускная способность памяти

Некоторые цифры о пропускной способности памяти (в основном в ГБ / с): http://www.tweaktown.com/articles/6619/crucial-ddr4-memory-performance-overview-early-look-vs-ddr2-ddr3/index.html

Допустим, диапазон составляет 150-300 Гбит / с для пропускной способности памяти (максимальный предел в идеальных условиях).

В какой-то момент все пакеты должны быть в памяти. Простое получение данных на скорости линии 40 Гбит / с - большая нагрузка на систему.

Останется ли энергия для обработки данных? Что ж, давайте не будем слишком завышать наши ожидания. Просто говорю ^^

Шина PCI-Express

PCIe 2.0 - 4 Гбит / с на полосу. PCIe 3.0 - 8 Гбит / с на линию (не все это доступно для карты PCI).

Сетевая карта 40 Гбит / с с одним портом Ethernet обещает больше, чем шина PCIe, если длина разъема меньше 16x по спецификации v3.0.

Другой

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

Программное обеспечение не может работать лучше, чем оборудование, на котором оно работает.

Магистральная сеть

Все эти пакеты в конечном итоге должны куда-то попасть, пересекая коммутаторы и маршрутизаторы. Коммутаторы и маршрутизатор 10 Гбит / с [почти] стали обычным товаром. 40 Гбит / с определенно нет.

Кроме того, пропускная способность должна быть сквозной, поэтому какие ссылки у вас есть для пользователя?

В прошлый раз, когда я проверил со своим парнем из центра обработки данных для небольшого стороннего проекта с 10 миллионами пользователей, он совершенно ясно дал понять, что в лучшем случае будет только 2x 10-гигабитных ссылок на Интернет.

Жесткие диски

iostat -xtc 3

Метрики делятся на чтение и запись. Проверьте очередь (<1 - хорошо), задержку (<1 мс - хорошо) и скорость передачи (чем выше, тем лучше).

Если диск работает медленно, решение состоит в том, чтобы поместить в raid 10 больше И больше SSD (обратите внимание, что пропускная способность SSD увеличивается линейно с размером SSD).

Выбор процессора

IRQ и другие узкие места работают только на одном ядре, поэтому стремитесь к ЦП с максимальной производительностью одного ядра (т. Е. С максимальной частотой).

Для шифрования / дешифрования SSL требуются инструкции AES-NI, поэтому старайтесь использовать только последнюю версию ЦП.

SSL выигрывает от нескольких ядер, поэтому стремитесь к большему количеству ядер.

Короче говоря: идеальный процессор - это новейший процессор с самой высокой доступной частотой и большим количеством ядер. Просто выберите самое дорогое и наверное все: D

Отправить файл()

Sendfile включен

Просто величайший прогресс современных ядер для высокопроизводительных веб-серверов.

Заключительное примечание

1 SolarFlare NIC 40 Gbps (pin IRQ and core)
2 SolarFlare NIC 40 Gbps (pin IRQ and core)
3 nginx master process
4 nginx worker
5 nginx worker
6 nginx worker
7 nginx worker
8 nginx worker
...

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

Одна сетевая карта, ведущая во внешний мир. Одна сетевая карта, ведущая во внутреннюю сеть. Разделение обязанностей - это всегда хорошо (хотя двойной сетевой адаптер 40 Гбит / с может быть излишним).

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

Я пока не могу комментировать из-за репутации, поэтому вместо этого мне нужно добавить ответ ...

В первом примере вы сказали:

Мое внимание привлекли 2 вещи. Первый - это большое количество IRQ. В этом случае у меня, к сожалению, нет графиков из / proc / interrupts. Во-вторых, высокая нагрузка на систему, я думаю, была вызвана тем, что kswapd0 не мог работать только с 16 ГБ ОЗУ.

Совершенно согласен, что это важные моменты.

  1. Попробуйте использовать агент collectd, который может собирать IRQ и сохранять их с помощью RRD.

  2. У вас есть диаграмма использования памяти?

    Хотя на первый взгляд это похоже на проблему с процессором, высокий% softtirq может просто указать пальцем на память, если происходит много жестких или программных ошибок страницы. Я думаю, что раздача заключается во внезапном увеличении IRQ за счет системного ЦП примерно в 19:00.

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

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