Почему TCP accept () так плохо работает под Xen?

89

Скорость, с которой мой сервер может принимать () новые входящие TCP-соединения, действительно плоха при Xen. Тот же тест на железном железе показывает увеличение скорости в 3-5 раз.

  1. Почему это так плохо под Xen?
  2. Можете ли вы настроить Xen для повышения производительности новых TCP-соединений?
  3. Существуют ли другие платформы виртуализации, более подходящие для этого варианта использования?

Фон

В последнее время я исследовал некоторые узкие места в производительности собственного Java-сервера под управлением Xen. Сервер говорит по HTTP и отвечает на простые вызовы TCP connect / request / response / connect.

Но даже при отправке трафика трафика на сервер он не может принимать более ~ 7000 TCP-соединений в секунду (на 8-ядерном экземпляре EC2 c1.xlarge с Xen). Во время теста сервер также демонстрирует странное поведение, когда одно ядро ​​(не обязательно cpu 0) сильно загружается> 80%, в то время как другие ядра остаются почти бездействующими. Это заставляет меня думать, что проблема связана с ядром / лежащей в основе виртуализацией.

При тестировании того же сценария на чистой виртуальной платформе без виртуализации я получаю результаты теста, показывающие скорость TCP accept () выше 35 000 в секунду. Это на Core i5 4-ядерном компьютере под управлением Ubuntu со всеми ядрами, почти полностью насыщенными. Мне такая фигура кажется правильной.

На экземпляре Xen я снова попытался включить / настроить почти все настройки, имеющиеся в sysctl.conf. Включая включение управления пакетами приема и потокового управления и закрепление потоков / процессов на процессорах, но без видимых преимуществ.

Я знаю, что при виртуализации следует ожидать снижения производительности. Но до такой степени? Более медленный сервер с «голым железом» превосходит вирт. 8-ядерный в 5 раз?

  1. Это действительно ожидаемое поведение Xen?
  2. Можете ли вы настроить Xen для повышения производительности новых TCP-соединений?
  3. Существуют ли другие платформы виртуализации, более подходящие для этого варианта использования?

Воспроизведение этого поведения

При дальнейшем изучении этого и выявлении проблемы я обнаружил, что инструмент тестирования производительности netperf может имитировать аналогичный сценарий, который я испытываю. Используя тест netperf TCP_CRR, я собрал различные отчеты с разных серверов (как виртуальных, так и не виртуальных). Если вы хотите поделиться с некоторыми результатами или посмотреть мои текущие отчеты, пожалуйста, см. Https://gist.github.com/985475

Откуда я знаю, что эта проблема не из-за плохо написанного программного обеспечения?

  1. Сервер был протестирован на «железном» оборудовании и практически насыщает все доступные ему ядра.
  2. При использовании TCP-соединений keep-alive проблема исчезает.

Почему это важно?

В ESN (мой работодатель) я являюсь руководителем проекта Beaconpush , сервера Comet / Web Socket, написанного на Java. Несмотря на то, что он очень производительный и может насытить практически любую полосу пропускания, предоставленную ему при оптимальных условиях, он все равно ограничен тем, насколько быстро могут быть сделаны новые соединения TCP. То есть, если у вас большой отток пользователей, когда пользователи приходят и уходят очень часто, многие TCP-соединения придется устанавливать / отключать. Мы пытаемся смягчить это, поддерживая связи как можно дольше. Но, в конце концов, производительность accept () - это то, что удерживает наши ядра от вращения, и нам это не нравится.


Обновление 1

Кто-то разместил этот вопрос в Hacker News , там также есть несколько вопросов / ответов. Но я постараюсь держать этот вопрос в актуальном состоянии с информацией, которую я найду по мере продвижения.

Оборудование / платформы, на которых я тестировал:

  • EC2 с экземплярами типов c1.xlarge (8 ядер, 7 ГБ ОЗУ) и cc1.4xlarge (2x Intel Xeon X5570, 23 ГБ ОЗУ). Использовались AMI ami-08f40561 и ami-1cad5275 соответственно. Кто-то также отметил, что «Группы безопасности» (т.е. брандмауэр EC2) также могут повлиять. Но для этого тестового сценария я попытался только на локальном хосте устранить такие внешние факторы, как этот. Еще один слух, который я слышал, заключается в том, что экземпляры EC2 не могут выдавать более 100 тыс. PPS.
  • Два частных виртуализированных сервера под управлением Xen. Один имел нулевую нагрузку до теста, но не имел значения.
  • Частный выделенный Xen-сервер в Rackspace. Примерно таких же результатов нет.

Я в процессе повторного запуска этих тестов и заполнения отчетов по адресу https://gist.github.com/985475 Если вы хотите помочь, укажите свои номера. Это просто!

(План действий был перенесен в отдельный сводный ответ)

cgbystrom
источник
3
Отличная работа, позволяющая точно определить проблему, но я считаю, что вам будет гораздо лучше работать в списке рассылки, посвященном Xen, на форуме поддержки или даже на сайте с отчетами об ошибках xensource . Я полагаю, что это может быть некоторой ошибкой планировщика - если вы возьмете число из 7000 соединений * 4 ядра / 0,80 загрузки процессора, вы получите ровно 35 000 - число, которое вы получите, когда 4 ядра будут полностью насыщены.
The Wabbit
Ах, и еще одна вещь: попробуйте другую (возможно, более свежую) версию ядра для вашего гостя, если можете.
the-wabbit
@ syneticon-dj Спасибо. Я попробовал это на cc1.4xlarge в EC2 с ядром 2.6.38. Я видел увеличение примерно на 10%, если я не ошибаюсь. Но это более вероятно из-за более мощного оборудования этого типа экземпляра.
cgbystrom
6
спасибо за то, что держали это в курсе ответов HN, это отличный вопрос. Я предлагаю перенести план действий в консолидированный ответ, возможно - так как это все возможные ответы на проблему.
Джефф Этвуд
@jeff Переместить план действий, проверить.
cgbystrom

Ответы:

27

Прямо сейчас: производительность небольших пакетов отстает под Xen

(вместо этого перешел от самого вопроса к отдельному ответу)

По словам пользователя HN (разработчика KVM?), Это связано с небольшой производительностью пакетов в Xen, а также в KVM. Это известная проблема с виртуализацией, и, по его словам, ESW от VMWare справляется с этим гораздо лучше. Он также отметил, что KVM приносит некоторые новые функции, разработанные для облегчения этого ( оригинальный пост ).

Эта информация немного обескураживает, если она верна. В любом случае, я попробую описанные ниже шаги, пока какой-нибудь гуру Ксен не придет с окончательным ответом :)

Iain Kay из списка рассылки xen-users составил этот график: график netperf обратите внимание на столбцы TCP_CRR, сравните «2.6.18-239.9.1.el5» против «2.6.39 (с Xen 4.1.0)».

Текущий план действий на основе ответов / ответов здесь и от HN :

  1. Отправьте эту проблему в список рассылки, относящийся к Xen, и в bugzilla xensource в соответствии с предложением syneticon-dj. В список пользователей xen было отправлено сообщение , ожидающее ответа.

  2. Создайте простой патологический тестовый пример на уровне приложения и опубликуйте его.
    Тестовый сервер с инструкциями был создан и опубликован на GitHub . При этом вы сможете увидеть более реальный вариант использования по сравнению с netperf.

  3. Попробуйте 32-битный гостевой экземпляр PV Xen, так как 64-битный может вызвать дополнительные издержки в Xen. Кто-то упомянул это на HN. Не имеет значения.

  4. Попробуйте включить net.ipv4.tcp_syncookies в sysctl.conf, как предложено abofh на HN. Это, очевидно, может улучшить производительность, поскольку в ядре произойдет рукопожатие. Мне не повезло с этим.

  5. Увеличьте отставание с 1024 до чего-то гораздо более высокого, также предложенного abofh на HN. Это также могло бы помочь, так как гость мог потенциально принимать () больше соединений во время своего среза выполнения, заданного dom0 (хост).

  6. Дважды проверьте, что conntrack отключен на всех машинах, так как он может вдвое уменьшить скорость приема (предложено deubeulyou). Да, это было отключено во всех тестах.

  7. Проверьте «переполнение очереди прослушивания и переполнение сегментов синхронизации в netstat -s» (предложено mike_esspe в HN).

  8. Разделите обработку прерываний между несколькими ядрами (RPS / RFS, которые я пытался включить ранее, должны делать это, но может стоить попробовать еще раз). Предложено Адамтом в HN.

  9. Отключите разгрузку сегментации TCP и ускорение разброса / сбора, как это было предложено Мэттом Бэйли. (Невозможно на EC2 или аналогичных хостах VPS)

cgbystrom
источник
2
+1 Обязательно опубликуйте результаты выступления, когда узнаете!
Крисэйкок
Кто-то ткнул меня в Twitter по этому вопросу. К сожалению, похоже, что эта проблема сохраняется. Я не проводил много исследований с прошлого года. Ксен МОЖЕТ улучшиться за это время, я не знаю. Разработчик KVM также упомянул, что они решают подобные проблемы. Может быть стоит преследовать. Кроме того, еще одна рекомендация, которую я слышал, это попробовать OpenVZ вместо Xen / KVM, так как он добавляет меньше или не использует многоуровневую / перехват системных вызовов.
cgbystrom
21

Неожиданно я обнаружил, что отключение аппаратного ускорения NIC значительно повышает производительность сети на контроллере Xen (также верно для LXC):

Scatter-сбор, ускорение:

/usr/sbin/ethtool -K br0 sg off

Разгрузка сегментации TCP:

/usr/sbin/ethtool -K br0 tso off

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

Мэтт Бэйли
источник
Я второй это. У меня был сервер Windows 2003, работающий на Xen, который испытал некоторые ужасные проблемы с потерей пакетов в условиях высокой пропускной способности. Проблема исчезла, когда я отключил разгрузку сегмента TCP
rupello
Благодарю. Я обновил «план действий» в исходном вопросе с вашими предложениями.
cgbystrom
см. также cloudnull.io/2012/07/xenserver-network-tuning
Лари Хотари
3

Может быть, вы могли бы немного уточнить - вы запускали тесты под Xen на своем собственном сервере или только на экземпляре EC2?

Accept - это просто еще один системный вызов, и новые соединения отличаются только тем, что первые несколько пакетов будут иметь определенные флаги - гипервизор, такой как Xen, определенно не должен видеть никакой разницы. Другие части вашей установки могут: например, в EC2, я не удивлюсь, если Группы безопасности будут как-то с этим связаны; Также сообщается, что conntrack вдвое снижает скорость приема новых соединений (PDF) .

Наконец, кажется, что есть комбинации CPU / Kernel, которые вызывают странное использование CPU / зависания на EC2 (и, возможно, Xen в целом), о чем недавно опубликовал Librato .

deubeulyou
источник
Я обновил вопрос и уточнил, на каком оборудовании я это пробовал. abofh также предложил увеличить количество нерассмотренных дел до 1024, чтобы ускорить число возможных accept () во время выполнения для гостя. Что касается Conntrack, я должен обязательно перепроверить, что такие вещи отключены, спасибо. Я читал эту статью о Liberato, но учитывая количество разного оборудования, на котором я это пробовал, этого не должно быть.
cgbystrom
0

Убедитесь, что вы отключили iptables и другие хуки в мостовом коде в dom0. Очевидно, это относится только к настройке моста Xen.

echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge.bridge-nf-call-arptables

Это зависит от размера сервера, но от более мелких (4-ядерный процессор) выделите одно ядро ​​процессора для Xen dom0 и закрепите его. Параметры загрузки гипервизора:

dom0_max_vcpus=1 dom0_vcpus_pin dom0_mem=<at least 512M>

Вы пытались передать физическое Ethernet-устройство PCI в domU? Должен быть хороший прирост производительности.

kupson
источник