前言
网格计算,是分布式计算的一种,它研究如何把一个需要非常巨大的计算能力,才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终结果。
集群计算、网格计算、云计算的联系和区别还是很明显的,网上一搜就有这里就不说了。
下面记录使用 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。