Как завершить конкретный экземпляр рабочей роли Azure

Фон

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

Если у меня слишком много заданий, я могу указать Azure развернуть дополнительный экземпляр роли и использовать его для новых заданий. И наоборот, если моя нагрузка падает (например, ночью), я могу объединить невыполненные задания на нескольких машинах и сказать Azure, чтобы мне давали меньше экземпляров.

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

Идея 1: я решаю, какой экземпляр остановить, и вернуться из его Run(). Затем я говорю Azure уменьшить количество моих экземпляров на один и надеюсь, что он решит, что сломанный экземпляр является хорошим кандидатом. Кто-нибудь пробовал что-нибудь подобное?

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

Идея 3: живите с этим.

Есть идеи получше?


person Oliver Bock    schedule 17.03.2011    source источник


Ответы (2)


В ответ на ваши идеи

Идея 1: я не пробовал делать именно то, что вы описываете, но по моему опыту ваш первый экземпляр имеет имя, оканчивающееся на _0, следующий _1, и я уверен, что вы можете угадать имя отдых. Когда вы уменьшаете количество экземпляров, он удаляет экземпляр с наибольшим числовым суффиксом. Я был бы удивлен, если бы он учитывал состояние любого конкретного экземпляра.

Идея 2: Как я думаю, вы намекаете, что это создаст проблемы с управлением. У вас может быть только 5 разных рабочих для каждой размещенной службы, поэтому вам понадобится служба для каждой группы из 5 ролей, до которых вы хотите масштабироваться. Кроме того, при развертывании обновлений вам придется загружать в X раз больше сервисов, где X — это максимальное количество поддерживаемых экземпляров.

Идея 3. Технически проще всего. В ожидании некоторых разъяснений, это, вероятно, то, что я буду делать сейчас. Чтобы уменьшить недостатки этого варианта, возможно, стоит изучить способы более быстрой загрузки данных. Обычно существует уровень Златовласки (не слишком много и не слишком мало) параллелизма, который помогает в этом.

person knightpfhor    schedule 18.03.2011
comment
re Идея 1: Это очень полезная информация. Возможность предсказать, что пойдет, почти так же хороша, как и возможность указать. - person Oliver Bock; 18.03.2011
comment
Идея 3: я надеюсь в конечном итоге улучшить время загрузки, но это сложная, уже существующая программа, поэтому я не могу полагаться на нее при первом развертывании. - person Oliver Bock; 18.03.2011
comment
Вы не можете рассчитывать на идею № 1 — нет абсолютно никакой гарантии, какой экземпляр будет остановлен при масштабировании, скажем, с 3 экземпляров до 2. Что касается идеи № 3 — если ваши задания запускаются сообщением очереди, и если ваша обработка очереди вывод является идемпотентным, вам не нужно беспокоиться о закрытии экземпляра - элементы очереди в процессе выполнения просто снова станут видимыми в очереди (после заданного вами значения тайм-аута), и другой экземпляр повторно обработает их. - person David Makogon; 20.03.2011

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

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

person David Makogon    schedule 17.03.2011
comment
Я должен был объяснить, что каждое задание (упрощение — это фактически загрузка большого файла данных и запрос его для пользователей) занимает несколько минут для запуска и использует около 50 МБ ОЗУ, но очень быстро отвечает на многочисленные запросы, связанные с заданием. Поэтому я хочу запускать каждое задание в одном экземпляре роли, но втиснуть в каждый экземпляр как можно больше заданий. У меня есть одна очередь сообщений для каждого задания, поэтому при перезапуске задания ничего не будет потеряно, но это дает пользователю нежелательную задержку. Заранее зная, какие задания следует перенести на другой хост, я могу свести к минимуму сбои (см. исходный вопрос). - person Oliver Bock; 18.03.2011