• Alchemi的实现机制初探


    前边的文字介绍了基于.net的计算网格(Computing Grid)的实现Alchemi,并对其使用做了简单的介绍。个人一直对其不同于其他Grid框架的基于Thread的实现很感兴趣,通过细粒度的Thread,应用Alchemi可以比较容易的实现分布算法。今天比较闲暇,因此对其源码做了简单的浏览,结合其文档,大概得出以下认识。

    Alchemi的基本编程模式如下:

    第一,从GThread继承自己的GThread类,实现具体的计算代码;
    第二,使用GApplication实现主程序:
    (1)通过GApplication.Threads.Add添加线程;
    (2)通过GApplication.Connection初始化连接和Grid平台;
    (3)GApplication.Start启动计算;
    (4)必须订阅事件以获知线程结束和计算结束。

    一个Alchemi必须包含以下部分:User, Manager, Executor。User通过继承GTread类创建自己的执行代码,通过GApplication的实例连接到Manager来执行代码。在初始化时,需要指定Thread运行需要的任何数据、Dll等信息,Alchemi负责把这些数据或第三方代码部署到Excutor所在的计算机,在运行结束后删除之。对于一般的.net程序,则简单的使用
    App.Manifest.Add(new ModuleDependency(typeof(PrimeNumberChecker).Module));
    类似的语句将本程序集添加即可。

    Manager提供透明的计算服务,一个Manager可以有数个User来使用,同时,Manager将任务分配给自己的Executor来完成任务。这些任务在Manager上存储于SQL Server或者MSDE。Manager同时验证User是否合法用户。

    Excutor提供计算服务,在计算之前,任务通过先进先服务的原则依次获得计算。

    Alchemi通过.net的Remoting机制来实现。上边提到的User, Manager, Executor分别在GManager,  GExecutor, GApplication中实现,其继承自GNode,其中实现了基本的通信机制。一个Grid程序的执行过程如下:

    首先,用户创建继承自GTread的类,创建GApplication的实例,所有执行代码需要的数据被加载到DependencyCollection中,FileDependencyCollection是一个继承自ReadOnlyCollectionBase的一个集合类。而继承自GTread的类的实例线程则加载到ThreadCollection中。ThreadCollection是继承自CollectionBase的一个自定义Collection,作为保存GTread实例的容器。



    接着,GApplication序列化执行Thread需要的代码和数据,并将其发送到Manager所在计算机,并持久化到硬盘,线程状态等信息则保存到SQL Server数据库中。以下是GApplication的Start的代码:

    public void Start()
    {
          ...
         
          Init();
          lock(_Threads)
          {
                foreach (GThread thread in _Threads)
                {
                      if (thread.Id == -1)
                      {
                            SetThreadOnManager(thread);
                      }
                }
          }
         
          ...
    }

    其中首先通过Init初始化系统,然后遍历Threads集合,通过SetThreadOnManager方法将其发送到Manager,代码如下,关键在于Manager.Owner_SetThread方法,其中最后一个参数将需要的数据、代码等序列化。

    private void SetThreadOnManager(GThread thread)
    {
          thread.SetId(++_LastThreadId);
          thread.SetApplication(this);

          Manager.Owner_SetThread(
                Credentials,
                new ThreadIdentifier(_Id, thread.Id, thread.Priority),
                Utils.SerializeToByteArray(thread));
    }

    在Manager的Owner_SetThread方法中,Thread被添加到MApplicationCollection集合中。

    将线程发送给Manager后,GApplication实例通过订阅GThreadFinish等事件返回执行结果。Manager通过MApplicationCollection和MExecutorCollection集合保存其用户和Thread信息。通过Owner_CreateApplication和Owner_SetApplicationManifest来完成用户需求的任务的创建,在Owner_SetThread方法中完成Thread的创建。对于有空闲的dedicated的Executor,可以直接连接并执行之,对于没有的情况下,则保存在集合中,由Executor反过来调用来执行Thread。



    在Excutor中,执行Thread的方法在ExecuteThreadInAppDomain中,其中首先创建应用程序域,然后通过以下语句执行之:

    首先从Manager获取Thread:
    byte[] rawThread = Manager.Executor_GetThread(Credentials, _CurTi);
    GridAppDomain gad = (GridAppDomain) _GridAppDomains[_CurTi.ApplicationId];
         
    然后执行之,并设置完成状态:
    byte[] finishedThread = gad.Executor.ExecuteThread(rawThread);
    Manager.Executor_SetFinishedThread(Credentials, _CurTi, finishedThread, null);

    其中的gad.Executor定义在AppDomainExecutor中,ExecuteThread方法如下:

    GThread gridThread = (GThread) Utils.DeserializeFromByteArray(thread);
    gridThread.SetWorkingDirectory(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
    gridThread.Start();
    return Utils.SerializeToByteArray(gridThread);

    首先从数据中重建GThread类,然后设置目录,运行,最后序列化回为数组流。其中的序列化使用的是.net的BinaryFormatter。

    对于non-dedicated的Thread,通过StartNonDedicatedExecuting(i),设置一个i参数来完成间隔一定时间从Manager获取Thread来调用。

    这样,我们对Alchemi的运行机制做了一个简单的剖析,文中肯定存在不少问题和错误,欢迎指正和讨论。了解一个系统的内部实现,一方面可以很好的应用之,另一方面也可以学习其设计思想,应用在我们的项目中。对于Alchemi,个人觉得其核心思想很简单,就是通过一定机制,将执行代码和数据序列化,然后临时部署到远程计算机,然后启动之,达到分布式计算的目的。与一般的远程调用机制比较,一般的远程调用是调用远程计算机上存在的程序,而Alchemi是将代码先部署到远程计算机,然后在执行之。

  • 相关阅读:
    如何把.ipynb文件转化为.py文件?
    本地浏览器连接服务器端jupyter notebook服务
    本地浏览器下远程连接jupter notebook服务器
    ubuntu下如何设置环境变量
    ubuntu环境变量的设置
    ssh免密登录设置方法
    主机之间ssh免密码登录
    ubuntu与windows互传文件的3种方法
    ubuntu16.04安装Sogou输入法详细步骤
    Ubuntu下安装Sogou输入法
  • 原文地址:https://www.cnblogs.com/maweifeng/p/233059.html
Copyright © 2020-2023  润新知