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