Отправка C # работников через разные виртуальные машины - PullRequest
4 голосов
/ 12 мая 2011

Мой вопрос очень прост, но ответ может и не быть.

У меня есть тысячи рабочих, выполняющих одну и ту же задачу, и я хотел бы, чтобы они выполнялись параллельно на многих удаленных виртуальных машинах (облачных или сетевых)

Вот идея:

class ThreadManager
{
    public void main()
    {
      for (int i = 0; i<300; i++)
      {
        myWorker wk;
        if (i < 100)
            wk = new myWorker(IP_Computer_1);
        else if (i < 200)
            wk = new myWorker(IP_Computer_2);
        else 
            wk = new myWorker(IP_Computer_3);

        wk.RunWorkerAsync();
      }
    }

    internal class myWorker :: BackgroundWorker
    {     
       public string IP_Computer;
       {...}//constructor

       protected override void OnDoWork(DoWorkEventArgs e)
       {              
          WriteToDatabaseTable("BAZINGA !  Greetings from computer " + Dns.GetHostName());
          //SQL server DB is hosted on a publicly accessible domain
          base.OnDoWork(e);
       }
    }
}


Конечно, это псевдокод, у вас есть идея: Назначение потоков / рабочих для разных компьютеров / ВМ по сети (не только многоядерных)

Какие основные / самые простые варианты у меня есть? Я открыт для ЛЮБОГО легкого и эффективного решения (я не хочу вдаваться в сложное планирование / реинжиниринг рабочих процессов приложений и т. Д. ... давайте оставим это как можно проще)

NB: Это НЕ невинный вопрос. Я в курсе всего, что связано с грид / облачными вычислениями, HPC, веб-сервисами Amazon, Azure и т. Д. Я потратил много времени, читая и пробуя что-то, и мое мнение таково, что есть много (денег) бизнеса выходя там. Иногда полезно вернуться к основам и задать простые вопросы, чтобы увидеть, действительно ли нам нужно слишком сложное / сложное / инвазивное / дорогое решение для решения основных проблем (мы не Fortune 500 с гигантской сетью, а просто небольшая исследовательская компания с конкретными / атомными вычислительными потребностями)

Ответы [ 5 ]

5 голосов
/ 12 мая 2011

Самый простой способ сделать это - смоделировать ваш «DoWork» как метод службы WCF.Используйте привязки NetTCP и баланс нагрузки на нескольких машинах .Это подходит, если машины являются клонами без сохранения состояния, и все состояние поддерживается в базе данных.В этом случае вам не нужно заботиться о том, какая машина обслуживает ваш запрос, и вам не нужно беспокоиться о IP-адресах на уровне приложений.

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

Если вы хотите гарантированную доставку (также называемую «забыть») и длительность транзакций, рассмотрите возможность использования транспорта MSMQ для вашей службы WCF.В этом случае служебный компьютер транзакционно отключается, и транзакция фиксируется, только если было выполнено обновление базы данных.

1 голос
/ 12 мая 2011

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

  • У вас есть «процедура установки», при которой вы вручную берете рабочих и распределяете их на каждый компьютер, который будет участвовать в упражнении, а затем отправляете имфрагменты данных для обработки с помощью WCF, MSMQ или любого другого числа методов удаленной связи
  • Иметь возможность главного процесса сериализовать сборку .net, передавать его каждому подчиненному / рабочему процессу и иметь этоработник загружает сборку в домен приложения, а затем отправляет им биты для работы.

В любом случае вам придется сначала решить проблему связи (вы проталкиваете что-то вроде WCF)или у вас рабы вытаскивают из очереди) и т. д.

1 голос
/ 12 мая 2011

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

1 голос
/ 12 мая 2011

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

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

Затем проблема начинает увеличиваться в зависимости от того, насколько больше функциональности задействовано.

0 голосов
/ 12 мая 2011

.NET не имеет простого встроенного способа сделать это.Возможно, вы захотите сделать сериализованными ваши рабочие и отправлять их на узлы через очередь сообщений (возможно, используя System.Messaging и MSMQ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...