Лучший способ для разработки роли Azure Worker для обработки данных из ~ 10 очередей - PullRequest
3 голосов
/ 03 ноября 2010

У меня есть одна рабочая роль, которая выбрасывает данные примерно в 10 очередей, которые необходимо обработать.Существует много данных - около 10-100 сообщений в секунду, которые ставятся в очередь в различных очередях.

Очереди содержат разные данные и обрабатывают их отдельно.В частности, существует одна очень активная очередь.

Как у меня сейчас настроено, у меня есть отдельная рабочая роль, которая порождает 10 разных потоков, каждый поток выполняет метод, имеющий время (true) {получить сообщение из очереди и обработать его}.Всякий раз, когда данные в очереди резервируются, мы просто запускаем больше этих процессов, чтобы помочь ускорить обработку данных из очереди.Кроме того, поскольку одна очередь более активна, я запускаю несколько потоков, указывающих на один и тот же метод для обработки данных из этой очереди.

Однако я вижу высокую загрузку ЦП при развертывании.Почти на или около 100% постоянно.

Мне интересно, это из-за голодания нити?Или потому что доступ к очереди является RESTful и потоки блокируют друг друга, устанавливая соединение и замедляя процесс?Или это потому, что я использую:

while(true)
{
   var message = get message from queue;
   if(message != null)
   {
       //process message
   }
}

И это выполняется слишком быстро?

Каждая обработка сообщения также сохраняет его в хранилище таблиц Azure или в БД - так что это может быть процесс сохранения этих данных, которые поглощают ЦП.

По сути, было очень сложно отладить высокую загрузку процессора.Итак, мой вопрос: есть ли общие изменения архитектуры, которые я могу сделать, которые помогут облегчить + предотвратить любую возможную проблему, которая может быть?(например, вместо использования while (true) с использованием другого типа опроса - хотя я думаю, что в конце этого примера то же самое).

Может быть, просто порождение новых потоков с использованием new Thread () - не лучший способ.

Ответы [ 5 ]

10 голосов
/ 03 ноября 2010

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

Я также часто использовал такой код:

while(true) { var msg = q1.GetMessage(); if (msg != null) { ... } msg = q2.GetMessage(); if (msg != null) { ... } }

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

3 голосов
/ 03 ноября 2010

Была такая же проблема с процессором.Это может быть вызвано неэффективной локальной реализацией очередей Azure.

В конце я добавил экспоненциальную политику сна (для реализации - ознакомьтесь с проектом Lokad.CQRS for Azure ), где очереди часто опрашиваются, но если в них нет ни одного сообщения.Во-первых, мы постепенно начинаем увеличивать интервал сна, пока он не достигнет некоторой верхней границы.Если сообщение обнаружено - мы немедленно сбрасываем интервал.

Таким образом, в целом система не тратит впустую транзакции хранения (и локальный процессор ЦП), но остается чрезвычайно отзывчивой, если несколько сообщений приходят подряд.

2 голосов
/ 04 ноября 2010

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

1 голос
/ 15 июня 2012

Есть отличная статья MSDN, которая охватывает все это

MSDN - Рекомендации по максимизации масштабируемости и экономической эффективности решений для обмена сообщениями на основе очередей в Windows Azure

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

1 голос
/ 03 ноября 2010

Я думаю, что ваша проблема связана с реализацией цикла.Опрос должен быть замедлен чем-то вроде сна ().Иначе ничто не помешает циклу потреблять 100% CPU Core (что на самом деле является нормальным поведением).

...