MK-Gii Ответов: 1

Выполнение нескольких исполняемых файлов на сервере


Привет,

Я разработал приложение, которое обрабатывает строки. Единственное, что он делает - берет строку из базы данных, обрабатывает ее и отправляет результаты обратно. Таким образом, он обрабатывает 1 Задание (1 строку) примерно за 200 мс, если мы считаем процессорное время, а я считаю процессорное время вот так:
1. получите процессорное время до начала работы
Process.GetCurrentProcess().TotalProcessorTime.TotalMilliseconds

2. я получаю то же самое процессорное время после завершения задания и вычитаю значения.

Теперь-все в порядке, если я начну 100 из этих исполняемых файлов на одном сервере. Общее потребление ЦП сервера (48 ядер машины) составляет около 10%, а среднее время обработки одного задания (в среднем через все 100 процессов) составляет около 200-300 мс.

Странности начинают происходить, когда я запускаю 200 из этих исполняемых файлов (в 2 раза больше, так что можно было бы ожидать, что общая загрузка процессора сервера составит около 20%). Но... Загрузка процессора на сервере начинает расти до 100%, и среднее время обработки одного задания составляет ~2000-4000 МС (в 10-20 раз больше).
Есть идеи, что здесь происходит? может быть, в коде есть какой-то изъян? Или это что-то с управлением серверными процессами.

Сервер является стандартом Windows Server 2008 R2. Но, похоже, это происходит и на srv 2012.
Приложение написано с .net 4.5 (но я построил его с 4.6.1, чтобы проверить тоже - все еще prolem с 200 процессами)

Заранее спасибо за любые подсказки или предложения.

br,
ИГН

Что я уже пробовал:

проверил код c# приложения, похоже, нет ничего, что могло бы привести к утечке процессора. тестировался на win srv 2008 и 2012 годов.
молиться Богу... но не ответил...

Jon McKee

Быстрый вопрос: Какова загрузка процессора, когда вы начинаете 50 по сравнению со 100 по сравнению с 200? Наличие этого низкого уровня 50 может быть полезно для определения того, является ли это проблемой масштабирования кода.

MK-Gii

ussage процессора на уровне 50 довольно низок. удары от 5 до 10 с пиками. в целом эта обработка является низкоинтенсивной, но по некоторым причинам, когда я запускаю несколько процессов, она значительно увеличивается.
Точка разрыва - это что - то около 120-125. После этого процессор начинает достигать пика от ~10-15% до 100, и через некоторое время половина времени остается на уровне 100% использования процессора.

1 Ответов

Рейтинг:
8

Jon McKee

У меня нет вашего кода или вашего сервера, но вот некоторые вещи, которые нужно проверить, основываясь на вашем посте и ответе на мой комментарий:

1)у вас работает довольно много (предположительно активных) процессов. Процесс-это дорогая вещь по сравнению с AppDomain или нить. При переключении между потоками ядро также должно переключать адресные пространства, если новый поток принадлежит другому процессу (весьма вероятно, с 200 активными процессами). В Диспетчере задач проверьте "View > Show Kernel Times" и посмотрите, сколько из этого процессора % используется для ядра. Рассмотрите возможность использования AppDomains, чтобы увидеть, решена ли ваша проблема. Если нет, рассмотрите потоковый подход (пул). Обычно я использую правило "процессы & lt; AppDomains & lt; threads". Выберите самый высокий из списка, который соответствует вашим требованиям, потому что чем ниже вы идете, тем больше накладных расходов.

2) сокращение количества процессов также позволит вам объединять SQL-операторы и выполнять их пакетно. Вероятно, это не ваша проблема, если только вы не запускаете 200 процессов и БД на одной машине, но тем не менее это хороший бонус.

3) отладьте и определите использование памяти, убедитесь, что различные процессы не борются за ресурсы (например, доступ к БД), и просто дайте вашему коду один раз для хорошей меры. От 5-10% при 50 до 10% при 100 с порогом 120-125, пока вы не прыгнете до 100%, звучит так, как будто вы имеете дело с перегрузкой какой-то части самой системы, но вы никогда не знаете.

4) струны могут быть уродливыми вещами, с которыми нужно обращаться в массовом порядке. Это может быть просто то, что ваша программа обрабатывает их неэффективно и жует память или заставляет GC работать часто. Этот[^]- это хороший базовый учебник о том, как обрабатываются строки в C#.


MK-Gii

Эй.
Я уже давно пробовал подход к потоку, но ничего не получалось. У меня были следующие настройки: одно приложение с пулом потоков, установленным на 100 потоков, и одно приложение с 1 потоком. Запуск 200 новых процессов, каждый из которых имеет один поток, был намного быстрее, чем запуск одного из 100 потоков. Ussage процессора был ниже для threaded, но скорость обработки данных была примерно в 10 раз медленнее, чем у 200 процессов (1 поток на приложение)

Jon McKee

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

MK-Gii

Кстати - я пытался решить эту проблему, но, похоже, не могу понять, почему, черт возьми, это время так велико (80%).
Я уже делал это:
1. стартер 100 приложений - все хорошо. ussage процессора около 5%.
2. начали еще 20-все хорошо. загрузка процессора составляет около 5-6%. нервный
3. запустил еще 10-через 10 секунд время ядра подскочило до 80% и держалось там.

Я использовал Системный монитор, чтобы посмотреть ЦОД, время, закрывает и переключение контекста. Ни одна из этих цифр не изменилась. Контекстные переключатели находятся примерно на уровне 20.000/с, как это было раньше, когда работало 100 приложений.
Есть мысли, Где искать больше?

Jon McKee

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

Тем не менее, вот что я думаю: ваши процессы редко блокируются. Это предположение я делаю, основываясь на том, что прочитал. У вас есть как минимум 120 + процессов, которые все цепляются за процессорное время. Процессоры лучше предназначены для блокировки задач. Запуск > 2x доступных ядер в постоянно активных процессах гарантирует переключение контекста при каждой возможности (вероятно, тайм-аут временного среза, поскольку я предполагаю, что ваши процессы имеют одинаковый приоритет). Это съест процессорное время с задачами ядра, так как ему нужно одновременно переключать контекст потока и контекст процесса.

Опять же, у меня нет вашей настройки, но с моей точки зрения программа нуждается в редизайне, ориентированном на минимизацию процессов, использующих Домены приложений и потоки, и, возможно, (бонусные баллы) минимизацию необходимости в них с помощью шаблона async-await (КРАН) там, где это применимо.

Правка: конечно, все это может быть спорным. Это может быть проблема где-то еще, например, с SQL-сервером. Это может быть много чего. Я бы все равно сосредоточился на решении проблемы масштабирования с точки зрения дизайна. Даже если вы исправите эту конкретную проблему сейчас, что произойдет, если вам нужно масштабироваться до 300 или 400? Ура :большой палец вверх:

MK-Gii

Просто проверил это = вы правы. Ядро занимает более 80% мощности процессора....