c++/c#/java, 架构设计, 自然语言处理、机器学习
昼闲人寂,听数声鸟语悠扬,不觉耳根尽彻; 夜静天高,看一片云光舒卷,顿令眼界俱空。

以前其它的项目组遇到了大数据计算的问题,一般计算时间都要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)发送到工作机,工作机加载类库,然后进行类型反射。

直接发送客户端的类库到工作机,显然没有考虑到跨平台的问题。

有想法的朋友,可以一起探讨下这个问题的解决方法。

 

下面是源代码地址,敬请指正。

https://github.com/dario-DI/DistributedCompute

posted on 2014-09-25 12:01  dario.  阅读(4353)  评论(5编辑  收藏  举报