2012-03-02 4 views
4

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

Одна из существующих теорий заключается в том, что задействовано слишком много потоков, и мы должны попытаться уменьшить количество одновременных выполнения потоков. Есть только один основной пул потоков, с 3000 потоками, и с ним работает WorkManager (это Java EE - Glassfish). В любой момент времени существует около 620 отдельных сетевых операций ввода-вывода, которые необходимо проводить параллельно (использование java.NIO также не является вариантом). Более того, существует около 100 операций, которые не связаны с IO и выполняются параллельно.

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

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

Так что - мы можем исключить переключение контекста или слишком много нитей в качестве проблемы?

Общие детали:

  1. Java 1.5 (да, это старая), работает на CentOS 5, 64-бит, Linux ядра 2.6.18-128.el5
  2. Существует только один единственный процесс Java на машине, ничего больше.
  3. Два процессора под управлением VMware.
  4. 8GB ОЗУ
  5. У нас нет возможности запуска профилировщика на машине.
  6. У нас нет возможности обновить Java или ОС.

UPDATE Как сообщил ниже, мы провели захваты средней нагрузки (с использованием безотказной работы) и CPU (с помощью vmstat 1 120) на нашем тестовом сервере с различными нагрузками. Мы ждали 15 минут между каждым изменением нагрузки и ее измерениями, чтобы обеспечить, чтобы система стабилизировалась вокруг новой нагрузки и числа средних нагрузок обновляются:

50% загруженность производственного сервера: http://pastebin.com/GE2kGLkk

34 % загруженность производственного сервера: http://pastebin.com/V2PWq8CG

25% нагрузки производственного сервера: появляется http://pastebin.com/0pxxK0Fu

использования центрального процессора, чтобы быть уменьшено нагрузка уменьшает, но не на очень резкий уровень (изменения от 50% до 25 % на самом деле не составляет 50% сокращение использования ЦП). Средняя загрузка кажется несопоставимой с объемом рабочей нагрузки.

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

ОБНОВЛЕНИЕ 2 Прикрепление снимок нитей из трех частей (Pastebin ограничений)

Часть 1: http://pastebin.com/DvNzkB5z

Часть 2: http://pastebin.com/72sC00rc

Часть 3: http://pastebin.com/YTG9hgF5

+0

Ну, а как уменьшить количество потоков в пуле потоков и посмотреть, помогает ли это? – Voo

+0

Высокое использование ЦП может быть хорошим: это означает, что использование ресурса ЦП является оптимальным. Ваши потоки что-то вычислили, не дожидаясь ввода-вывода или блокировки. Если у вас нет жесткой петли, потребляющей ваш процессор без необходимости, вы должны быть довольны высоким уровнем параллелизма, который вам удалось достичь. – dasblinkenlight

+1

@dasblinkenlight Это правда, если нам удастся доказать, что нет ненужных отходов (например, переключение контекста).Если нам удастся это сделать, мы можем сказать системной команде добавить больше процессоров и оправдать то, что это такое. Но сначала мы должны сделать домашнее задание. – Yon

ответ

2

Кажется мне, проблема 100 CPU связаны нити больше, чем все остальное. 3000 - это в основном красная селедка, так как простаивающие нити не потребляют много чего. Потоки ввода/вывода, вероятно, будут спать «большинство» времени, так как ввод-вывод измеряется по геологическому временному масштабу с точки зрения компьютерных операций.

Вы не упомянули, что делают потоки 100 процессоров, или как долго они длится, но если вы хотите замедлить работу компьютера, выделение 100 потоков «запустить до тех пор, пока временной срез не будет останавливаться», это, безусловно, сделает это , Поскольку у вас есть 100 «всегда готовых к запуску», машина переключит контекст так быстро, как позволяет планировщик. Будет почти нулевое время простоя. Контекстное переключение будет иметь последствия, потому что вы делаете это так часто. Поскольку потоки ЦП (вероятнее всего) потребляют большую часть процессорного времени, ваши «связанные потоки» ввода-вывода ждут в очереди выполнения дольше, чем они ждут ввода-вывода. Таким образом, ожидают еще больше процессов (процессы ввода-вывода просто выходят из строя чаще, поскольку они быстро ударяют по барьеру ввода-вывода, который простаивает процесс для следующего).

Нет сомнений, что есть кое-какие возможности для повышения эффективности, но 100 потоков ЦП - это 100 потоков ЦП. Не так много вы можете там сделать.

+0

Благодарим вас за понимание. Посмотрите на стек потока, опубликованный во втором обновлении на вопрос, что вы думаете? – Yon

+0

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

2

Итак - можем ли мы исключить переключение контекста или слишком много нитей, как проблема?

Я думаю, что вы обеспокоены изнашиванием, являются оправданными. Пул потоков с 3000 потоками (700+ одновременных операций) на экземпляре VMware 2 CPU конечно кажется проблемой, которая может вызывать перегрузку и проблемы с переключением контекста. Ограничение количества потоков может дать вам повышение производительности, хотя определение правильного числа будет сложным и, вероятно, будет использовать множество проб и ошибок.

Нам нужно некоторое доказательство проблемы.

Я не уверен, что лучший способ ответить, но вот некоторые идеи:

  • смотреть средняя нагрузка VM OS и виртуальной машины Java. Если вы видите высокие значения нагрузки (20+), то это индикатор того, что в очередях выполнения слишком много вещей.
  • Нельзя ли смоделировать нагрузку в тестовой среде, чтобы вы могли играть с номерами пулов потоков? Если вы запускаете смоделированную нагрузку в тестовой среде с размером пула X, а затем запускаете с X/2, вы должны иметь возможность определять оптимальные значения.
  • Вы можете сравнить большие времена загрузки с меньшими затратами времени на загрузку? Можете ли вы нарисовать количество ответов на латентность в течение этих времен, чтобы увидеть, можете ли вы увидеть переломный момент с точки зрения перерыва?
  • Если вы можете имитировать нагрузку, тогда убедитесь, что вы не просто проверяете методологию «напиток из пожарного шланга». Вам нужна смоделированная нагрузка, которую вы можете набирать вверх и вниз. Начните с 10% и замедляйте увеличение симулированной нагрузки при просмотре пропускной способности и латентности. Вы должны уметь видеть точки опрокидывания, наблюдая за плотностью пропускной способности или иным образом отклоняющимся.
+0

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

+1

@Yon Мне кажется, что вы делаете заказы здесь с точки зрения потоков к физическим ядрам, поэтому я не думаю, что 1 или 2 дополнительных процессора, настроенных при загрузке, будут иметь значение. Вы пытались запустить систему в системе 8 или 16 CORE где-нибудь? – Gray

+0

Как мы докажем ваше утверждение и оправдаем работу? – Yon

1

Обычно переключение контекста в потоках очень дешево, но когда речь идет о многих потоках ... вы просто не можете знать. Вы говорите, что обновление до Java 1.6 EE не может быть и речи, но как насчет некоторых обновлений оборудования? Это, вероятно, обеспечит быстрое исправление и не должно быть так дорого ...

+0

Системная команда требует от нас доказательств, объясняющих, почему любые изменения в ресурсах оправданы. – Yon

0

например. запустить профайлер на аналогичной машине.

  • попробовать новую версию Java 6 или 7. (Это не может изменить ситуацию, и в этом случае не беспокоить модернизирует производство)
  • попробовать Centos 6.x
  • стараются не используя VMware.
  • Попробуйте уменьшить количество потоков. У вас всего 8 ядер.

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

+0

У нас есть тестовая среда, работающая примерно на половину нагрузки. Изменение версий Java не повлияло на нее и не уменьшило количество потоков. – Yon

+0

Итак, вы можете сделать вывод, что обновление версии Java не поможет, и количество потоков, вероятно, не проблема. –

+0

Один из вопросов, который у нас есть: есть ли возможность, когда более загруженные серверы пробуждают больше потоков, и это переключение контекста вызывает проблему? Важно помнить, что даже с большими пулами большая часть потоков ждет очереди. – Yon

4

Я думаю, что ваши ограничения необоснованны. В основном вы говорите:

1.I can't change anything 
2.I can't measure anything 

Не могли бы вы рассказать о моей проблеме?

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

Помните правило 80/20 настройки производительности. 80% зависит от настройки вашего приложения. У вас может быть слишком много нагрузки для одного экземпляра виртуальной машины, и настало время рассмотреть решения для масштабирования по горизонтали или по вертикали, предоставив больше ресурсов машине. Это может быть любая из трех миллиардов настроек JVM, не связанных с особенностями исполнения вашего приложения.

Я предполагаю, что пул из 3000 потоков был создан из знаменитых больше потоков = больше параллелизма = больше теории производительности. Реальный ответ - изменение настройки не стоит ничего, если вы не измеряете пропускную способность и время отклика до/после изменения и не сравниваете результаты.

+0

Обоснование нашей неспособности делать то, что сервер находится за несколькими защитными мерами на другой стороне планеты. Нам нужно лететь туда, и даже тогда у него нет доступа в Интернет, поэтому все довольно громоздко. Мы действительно не хотим этого делать. Предоставление большего объема ресурсов требует убеждения местной команды, что означает, что нам нужны доказательства. – Yon

+0

Пул потоков пришел из этого: количество одновременных задач ввода-вывода может расти без нашего контроля над ним, есть кто-то еще (назовите его «Оператор»), который может вызвать это увеличение с небольшим пониманием системы.Таким образом, мы устанавливаем 3000 как число, которое должно быть достаточным для любой работы, которую этот Оператор может бросить в систему. Проблема с пулами потоков в Glassfish, по-видимому, не может быть изменена во время выполнения. – Yon

+2

Ваше оправдание совершенно недействительно. Размер пула потоков - это не пособие, которое вы даете своему ребенку. Почему бы просто не установить его до 4 миллиардов? Это показатель для вашего приложения в отношении его физической операционной среды и ограничений там. Поиск правильного числа - это процесс проб и ошибок. К малому, и работа будет стоять в очереди, и ядра будут сидеть без дела, слишком много затрат на переключение между потоками превышают преимущества одновременного выполнения. Вам нужно использовать силу науки, чтобы найти нужный номер – nsfyn55

2

Если вы не можете профилировать, я бы рекомендовал взять дамп потока или два и посмотреть, что делают ваши потоки. Ваше приложение не должно останавливаться, чтобы сделать это:

  1. http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/threads.html
  2. http://java.net/projects/tda/
  3. http://java.sys-con.com/node/1611555
+0

Хорошая точка, моментальный снимок, добавленный к вопросу. – Yon

Смежные вопросы