【问题标题】:Sending C# Workers over different Virtual Machines通过不同的虚拟机发送 C# Worker
【发布时间】:2011-05-12 19:18:25
【问题描述】:

我的问题很简单,但答案可能不是。

我有成千上万的工作人员执行相同的任务,我希望他们在许多远程虚拟机(云或网络)上以并行方式执行

这是一个想法:

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);
       }
    }
}


当然,这是伪代码,你明白了:通过网络将线程/工作者分配给不同的计算机/VM(不仅是多核)

我有哪些基本/最简单的选择? 我愿意接受任何轻便有效的解决方案(我不想进行复杂的调度/应用程序工作流程再造等……请保持原样)

注意:这不是一个无辜的问题。我知道所有关于网格/云计算、HPC、亚马逊网络服务、Azure 等的大惊小怪......我花了很多时间阅读和尝试一些东西,我认为有很多(金钱)业务出去。有时回到基础并提出简单的问题是很好的,看看我们是否真的需要一个过于复杂/复杂/侵入性/昂贵的解决方案来解决基本问题(我们不是拥有庞大网络的财富 500 强,而只是一家小型研究公司具有特定/原子计算需求)

【问题讨论】:

  • 我不确定我是否同意您对云的负面看法...过于复杂/复杂/侵入性/昂贵
  • @Forgotten Semicolon :我看到了那个,想知道一年后是否有更多机会对这样一个基本问题获得更全面的答案......
  • @Aaron :我已经尝试过 Amazon EC2 和 Azure(动手操作)。到目前为止,我发现无法使用 Windows 集群 EC2 实例来执行计算过程(HPC 实例仅适用于 Linux),而对于 Azure,我们遇到了存储问题,因为我们必须执行高速 I/O 操作,更不用说应用程序(重新)部署很痛苦,因为它不像 VM 那样无缝。无论如何,我并不反对云,我只是想找出是否有一种基本的、简单的、循序渐进的方法来在云或其他 VM 上执行集群/网格

标签: c# .net multithreading networking


【解决方案1】:

最简单的方法是将“DoWork”建模为 WCF 服务上的方法。 使用 NetTCP 绑定和load balance across multiple machines。如果机器是无状态克隆,这是合适的,并且所有状态都在数据库上维护。在这种情况下,您不应该关心哪台机器为您的请求提供服务,并且您不应该在应用程序级别使用 IP 地址。

这不提供通信保证,不提供可靠性或故障转移。例如,如果服务机器在请求期间“死亡”,则不会在另一台机器上重新启动请求。这可能正好满足您的需求。

如果您想要保证交付(即即发即弃)和事务持久性,请考虑将 MSMQ 传输用于您的 WCF 服务。在这种情况下,服务机器以事务方式出列,并且仅在已执行数据库更新时才提交事务。

【讨论】:

  • 谢谢你的洞察力。我会试一试(我不知道具体如何,但我会阅读文档并尝试使用 API)。就可靠性和故障转移而言,这不是问题,我有一个并行交叉检查系统,如果某些服务失败,我会让它在下一个进程池中重新运行。
  • 我欢迎分步指南或任何有用的可用资源来帮助我开始。谢谢你的回答。
【解决方案2】:

NGrid 一个开源网格计算怎么样。如果您想自己完成所有工作,则需要大量编码才能将容错融入您的自定义解决方案。最困难的是将故障保持在本地而不影响整个系统。

【讨论】:

  • Ngrid 已停止维护 3 年,我更愿意在深入挖掘之前获得用户反馈。至于容错,这不是我的应用程序处理的问题。如果某个工作人员失败了,我会进行交叉检查以了解它并再次运行它。
  • sourceforge.net/projects/ngrid:最后更新:2009-08-05。不要看起来过分活跃:(
【解决方案3】:

您的……嗯……问题中有很多未回答的问题。从概念上讲,这是一项非常简单的任务,但是一旦您开始了解一些细节,它就会变得越来越具有挑战性。

正如您在问题中所述,我了解您想要触发并忘记分布式处理器的任务。这意味着每个任务都是原子的,不需要返回。一种方法是在分布式节点上创建一个侦听服务器,然后您的主节点将发送包含要执行的序列化工作对象的消息。然后,分布式节点将启动一个新线程(或工作进程)来执行处理。

然后根据涉及的更多功能,问题开始扩大。

【讨论】:

【解决方案4】:

首先要了解的是,您当然可以相当轻松地将数据发送到其他计算机(即 WCF)……但是,您不能轻松地发送代码/逻辑。因此,您可以通过以下两种方式之一解决该问题:

  • 有一个“安装程序”,您可以手动将工作人员分配到将参与练习的每台计算机,然后通过 WCF、MSMQ 或任何其他数量的远程通信向他们发送要处理的数据片段技巧
  • 让主进程能够序列化 .net 程序集,将其传输到每个从属/工作进程,并让该工作进程将程序集加载到应用程序域中,然后继续向它们发送要处理的位。李>

无论哪种方式,你都必须首先解决通信问题(你是通过 WCF 之类的东西推送,还是让从属从队列中拉出)等等。

【讨论】:

    【解决方案5】:

    .NET 没有简单的内置方法来做到这一点。您可能希望使您的工作人员可序列化并通过消息队列将它们发送到节点(可能使用System.Messaging 和 MSMQ)。

    【讨论】:

    • 是的,没有简单的内置方法可以做到这一点,那是我的猜测......关于节点的东西,如果你能给我更多关于前端的细节/资源,让它变得更混凝土会很棒。
    • 我不同意; WCF 让它变得非常简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多