Допустимо ли использовать ThreadPool.GetAvailableThreads для регулирования объема работы, выполняемой службой? - PullRequest
2 голосов
/ 03 марта 2011

У меня есть служба, которая очень быстро опрашивает очередь, чтобы проверить, не нужно ли выполнить больше «работы». В очереди всегда больше работы, чем может выдержать один работник. Я хочу убедиться, что один работник не захватывает слишком много работы, когда служба уже работает на максимальной мощности.

Допустим, мой работник получает 10 сообщений из очереди каждые N (мс) и использует параллельную библиотеку для параллельной обработки каждого сообщения в разных потоках. Сама работа очень тяжелая. Многие запросы SQL Server и даже хранилище таблиц Azure (запросы http) выполняются за одну единицу работы.

Является ли использование TheadPool.GetAvailableThreads () правильным способом регулирования количества работы, которую может получить служба?

Я вижу, что у меня есть доступ к доступным WorkerThreads и CompletionPortThreads . Для тяжелого процесса ввода-вывода более уместно посмотреть, сколько доступно CompletionPortThreads? Я считаю, что 1000 - это число, доступное для процесса независимо от количества процессоров.

Обновление - Возможно, важно знать, что очередь, с которой я работаю, является очередью Azure. Таким образом, каждый запрос на проверку сообщений выполняется как асинхронный http-запрос, который возвращается со следующими 10 сообщениями. (и стоит денег)

Ответы [ 3 ]

1 голос
/ 03 марта 2011

Я работал практически с той же проблемой в той же среде.В итоге я дал каждому WorkerRole внутреннюю рабочую очередь, реализованную как BlockingCollection <>.Есть один поток, который отслеживает эту очередь - когда количество элементов уменьшается, он запрашивает больше элементов из очереди Azure.Он всегда запрашивает максимальное количество предметов, 32, чтобы сократить расходы.Он также имеет автоматический возврат в случае, если очередь пуста.

Тогда у меня есть набор рабочих потоков, которые я запустил сам.Они сидят в цикле, вытаскивая предметы из внутренней рабочей очереди.Количество рабочих потоков - это мой основной способ оптимизировать загрузку, поэтому я настроил его в качестве опции в файле .cscfg.В настоящее время я использую 35 потоков на одного работника, но это число будет зависеть от вашей ситуации.

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

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

1 голос
/ 03 марта 2011

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

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

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

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

0 голосов
/ 12 марта 2011

Я решил сохранить внутренний счетчик того, сколько сообщений в настоящее время обрабатывается. Я использовал Interlocked.Increment / Decrement для управления счетчиком в поточно-ориентированном режиме.

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

...