网格计算:ignite

前言

网格计算,是分布式计算的一种,它研究如何把一个需要非常巨大的计算能力,才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终结果。

集群计算、网格计算、云计算的联系和区别还是很明显的,网上一搜就有这里就不说了。

下面记录使用 Apache 的 ignite 引擎开启一个网格计算。官方参考文档:https://apacheignite.readme.io/docs/getting-started

一、Getting Started

1,下载、安装 JDK8 或者更高版本

2,配置环境 JDK 的变量

windows 10 配置方法:

系统变量中新建:

a),变量名:JAVA_HOME    变量值:C:\Program Files\Java\jdk-12.0.2(jdk 安装路径)

b),变量名:Path (已有就在里面新建记录)   变量值:%JAVA_HOME%\bin;

在 CMD 中执行 "JAVA" ,有相关说明出来就说明配置成功了。

3,在 vs 项目中,使用 NuGet 安装 ignite:

4,下面是官方给的一个分布式计算样例:

样例很简答,就是把几个计算字符穿长度的任务,按照空格,拆分成了 N 个子任务,交给网格内的计算机群进行计算,最后汇总计算结果。

MasterNode

using Apache.Ignite.Core;
using Apache.Ignite.Core.Compute;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace Ignite_test__MasterNode_
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ignite = Ignition.Start())
            {
                int i = 1;
                var funcs = "a b c d e f g h i j k l m n o p q r s t u v w x y z".Split(' ').Select(word => new ComputeFunc { Word = word, TaskNumber = i++ });

                Stopwatch sw = new Stopwatch();
                sw.Start();
                ICollection<int>res = ignite.GetCompute().Call(funcs);

                var sum = res.Sum();

                Console.WriteLine(">>> Total number of characters in the phrase is '{0}'.", sum);
                sw.Stop();
                Console.WriteLine("总耗时{0}ms", sw.Elapsed.TotalMilliseconds);
                Console.ReadKey();
            }

        }
    }
    class ComputeFunc : IComputeFunc<int>
    {
        public string Word { get; set; }
        public int TaskNumber { get; set; }
        public int Invoke()
        {
            Console.WriteLine("任务{0}开始\n", TaskNumber);
            int i = 0;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (i < 200000)
            {
                i++;
                Thread.Sleep(0);
            }
            Console.WriteLine("任务{0}结束,耗时{1}ms\n", TaskNumber, sw.Elapsed.TotalMilliseconds);
            return Word.Length;
        }
    }
}

会发现编译时出错: if not exist “…Ignite test\Ignite test\bin\Debug\libs””已退出,代码为 9009

对此官方文档上并没有说明,不过根据错误信息,应该是缺少了某些库文件。试了多次终于找到了解决办法:

a) 修改目标解决方案平台为 x64(安装的 jdk 是 x64 的)

b) NuGet 上下载的库文件,复制到 x64 -> Debug 目录里

5,重新生成解决方案,还是会有一个错误,不过可以忽略,直接运行即可:

可以看到,ignite 显示现在又一个服务端,CPU 数量是 8 个,因为我的笔记本是 4 核 8 线程的。现在,只有 MasterNode,ignite 除了本机找不到其他可以使用的计算机,所以所有的计算任务,都是本机独立完成的,最终耗时:

6,下面,我们在另外一台电脑上,运行 AssistNode,实现 “分布式计算”:

AssistNode

using Apache.Ignite.Core;
using Apache.Ignite.Core.Compute;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace Ignite_test__MasterNode_
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ignite = Ignition.Start())
            {
                //AssistNode 只需要等待任务就好了
                Console.ReadKey();
            }

        }
    }
    class ComputeFunc : IComputeFunc<int>
    {
        public string Word { get; set; }
        public int TaskNumber { get; set; }
        public int Invoke()
        {
            Console.WriteLine("任务{0}开始\n", TaskNumber);
            int i = 0;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (i < 200000)
            {
                i++;
                Thread.Sleep(0);
            }
            Console.WriteLine("任务{0}结束,耗时{1}ms\n", TaskNumber, sw.Elapsed.TotalMilliseconds);
            return Word.Length;
        }
    }
}

先开启 AssistNode,再开启 MasterNode,MasterNode 就能检索到 AssistNode,并且把一部分任务分配给 AssistNode 计算:

可以看到,两台电脑一起计算,CPU的数量加了起来,实现了分布式计算。但是为什么比单机计算耗时还长呢,因为计算过于简单,大部分的时间都花在数据传输了。

 

更新

2019年9月20日

1,编译项目的过程中报错 “ if not exist “…Ignite test\Ignite test\bin\Debug\libs””已退出,代码为 9009 ” 的问题原因找到了:

visual studio 在项目编译完成后,会执行一个命令行:

这个命令行的作用就是把 Apache ignite 的库文件,从 …\Ignite test\packages\Apache.Ignite.2.7.5\libs 复制到 …\Ignite test\Ignite test\bin\x64\Debug\libs 里。

这个命令行使用了一个可执行文件:xcopy.exe,这个 exe 存在于 c:\windows\system32 目录下,但是没有被 cmd 识别,所以命令行执行失败了,所以 visual studio 就弹出了相应的错误。

要想 cmd 识别找到这个 exe,要手动添加一个环境变量:

系统变量 path 中新增条目 C:\Windows\System32

新增这个环境变量重启后生效,再次编译就没有这个错误啦。

之前没有这个环境变量,忽略 error,程序还能正常运行,是因为我手动把库文件拷贝到了 debug 目录里。

也可以删掉这个后期生成事件命令行,手动拷贝也 ok。

发表评论