分布式计算被誉为高端的东东,我想也是每个程序员都想涉足的领域了。
前一段时间项目中遇到了大数据计算的问题,一般计算时间都要2~3小时,甚至一整天的。我想能不能利用多台机器分布式计算,减少计算时间呢?当前分布式计算框架主要有hadoop, google的map/reduce,或一些其它的框架。但这些东东实在太庞大了,也需要我们修改已有的程序代码。
于是想到了zeromq这个家伙,引用官方的说法: “ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。ZMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接字之上的一 层封装。ZMQ让编写高性能网络应用程序极为简单和有趣。”。
事实证明,zeromq用起来果然不错。
我的做法是:
1、使用zeromq作为通信底层。使用c++对象作为网络传输的基本单位,并使用c++对象反射机制实现对象的解析。
2、每一个任务,即是一个对象。任务的分解(map)与归约(reduce)的任务,则分配给了使用者本身,因为只有TA知道任务的具体算法与数据。一个任务包含了数据、算法、结果(待计算)。
3、任务分解之后,只需要简单调用DoMultiTask(taskList, waitTime)即可。剩下的工作就是等待计算完成,然后归约。
4、类库接收到任务后,将其发送到主服务器,主服务器使用负载均衡算法/最近最少使用算法,将任务发放给已经注册的工作机(worker)。工作机处理完成后返还给主机,主机返还给客户,将结果写入任务(task)的结果变量中。
5、所有计算完成返回,有客户端归约。
其中,分布式框架做的事情就是工作机的注册与管理、服务器(路由)的管理,客户端任务的发送与结果接收,类型反射等。
这样做的优点是,不需要修改已有程序代码,只需增加任务类即可。
当人们使用同一个软件工作,TA愿意选择作为分布式计算客户端,则会向服务器注册这个机器然后被使用,程序就会运行一个线程等待任务。
ps:未来有一个问题需要解决:现在假定的是客户端与工作机的类库相同,即对象能够成功反射。如果一个任务(对象)传送到工作机,可是工作机没有这个对象的反射信息,最多只能反射数据,不能动态生成任务的算法。总不能传一段c++代码,让客户机解释执行吧?我想到的解决方法有:如果反射失败,那么要求客户端将类库信息(dll)发送到工作机,工作机加载类库,然后进行类型反射。
源代码:https://github.com/dario-DI/DistributedCompute