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

Объясните эту странную проблему производительности Ruby, связанную с окружением

Мы диагностируем проблемы с производительностью Ruby на наших серверах приложений, которые нам удалось свести к простому тесту.

Мы сравниваем производительность машины в нашем кластере разработки с машиной в нашем производственном центре обработки данных.

Мы использовали этот простой Ruby oneliner:

5000000.times { a = []; a << 1; a.length }

И мы отметили, что он постоянно на 55% медленнее на производственной машине.

Очевидно, что это могло быть и почему мы думаем, что это не так:

  1. Различное программное обеспечение - машины для разработчиков и производственные машины устанавливаются из одной и той же операционной системы ubuntu, сценариев установки ubuntu, репозиториев пакетов, и мы используем марионетку для согласованности конфигураций.
  2. Другое железо - возможно, но см. Ниже.
  3. Различная нагрузка - ни машины разработки, ни производственные машины не сильно загружены, и снова см. Ниже.

Почему мы не думаем, что это нагрузка или оборудование?

Во-первых, у них похожие нагрузки и конфигурации оборудования. Во-вторых, мы написали тестовый скрипт на Python:

n = 10000000
while n > 1:
  n = n - 1
  a = []
  a.append(4)
  len(a)

а это стабильно 10% Быстрее на производстве, чем на разработке, чего мы и ожидали. Если проблема была в загрузке или оборудовании, разве Python не работал бы медленнее и в производственной среде?

Вкратце обе машины виртуализированы с помощью ESXi.

Операционная система - Ubuntu Hardy 64bit. Наш интерпретатор Ruby:

ruby 1.8.6 (2008-08-11 patchlevel 287) [x86_64-linux]

и наш интерпретатор Python

Python 2.5.2 (r252:60911, Jul 31 2008, 17:31:22)

NB. Мы также пробовали это с Ruby Enterprise Edition, и результаты такие же.

Вы пробовали УМЕНЬШИТЬ количество виртуальных ЦП, которые вы передаете рабочей виртуальной машине?

Я знаю, что это звучит контрпродуктивно, но, и вы, возможно, уже знаете об этом, ESX не предоставит виртуальной машине НИКАКОГО процессорного времени, если ВСЕ слоты виртуальных ЦП, выделенные какой-либо виртуальной машине, не являются свободными, т.е. если виртуальной машине назначено 4 виртуальных ЦП. к нему, и они просто не все бесплатны, тогда виртуальная машина вообще не получает времени. Я знаю, что это звучит ментально, но серьезно попробуйте перейти на 2 или 1 виртуальный ЦП и запустить его снова.

Удачи.

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

  • Opteron 2354 имеет 2 МБ кэш-памяти L-3, а 2376 - 6 МБ.
  • 2354 использует ОЗУ PC2-5300 DDR2, а 2376 использует ОЗУ PC2-6400 DDR2.

Я немного устарел с оборудованием, но я предполагаю, что это означает, что доступ к памяти в целом значительно быстрее на машине разработки? Итак, если Ruby каким-то образом был более «требователен к памяти» (и я действительно не понимаю, что я имею в виду!), То это могло бы проявиться как большая разница в производительности?

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

Пара вопросов ...

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

Однако такая же проблема может или должна произойти и с Python. Поскольку и Ruby, и Python реализованы на C, целочисленный размер, вероятно, будет одинаковым (хотя это предположение может быть неверным).

Короче еще ищу!

Вопрос: как вы проводите бенчмаркинг? Используете ли вы тест Ruby для версии Ruby или какой-либо внешний инструмент? Если первое, мне интересно, является ли что-то в библиотеке тестов, что вызывает проблему.

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

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

Эээ ... просто чтобы убедиться, что происходит, когда вы делаете:

 n = 1000000
 while n > 1 do
   n = n - 1
   a = []
   a.push 4
   a.length
 end

Я знаю, что это функционально эквивалентно 1000000.times { a = []; a << 4; a.length }, но функция times может делать что-то необычное за кулисами? Я также согласен с утверждением о многопоточности, но это фактически означает, что блок разработчика всего на 0,083 ГГц быстрее, что вряд ли объясняет падение на 55%. Было бы интересно посмотреть, что делает Ruby 1.9, но если вы пробовали REE, я сомневаюсь, что разница в производительности будет слишком большой. Я предполагаю, что это точно такая же скорость диска, кешей памяти и т. Д.?

Это потому, что Ruby не может воспользоваться дополнительными виртуальными ядрами из-за того, что он использует зеленые потоки, в то время как python с нативными потоками может? (Здесь дикая задница догадывается - я действительно не понимаю, о чем говорю).