谢谢大家来看这篇文章,我想花点时间分享一下我对分布式计算的理解。
分布式服务有很多,比如hbase, hadoop, spark等,我所要讲述的重点不是这些服务的原理,而是用更浅显的话讲述更深刻的设计。
如何把多个的机器组合起来完成一件简单的计算任务,所以这方面的架构设计更多的关注服务器间的关系。
下面我们来设计一个框架,以进行简单的分布式计算。
我们假设计算目标有三类:
1.分布计算能力,简单多节点计算, 计算1万以内的质数。
2.map-reduce,以wordcount为例。
3.资源查询,分布式查询数据库

模块设计

在架构上, 可以将服务中的服务器分三个模块:

深度学习分布式计算 分布式计算实现_云计算

模块

含义

config

配置服务

service

对外接口服务

server

工作服务(worker)

我想让service接受请求,server进行计算, 流程会是怎样的呢。

流程设计

一条简单的请求过来,可能经过的处理过程:

深度学习分布式计算 分布式计算实现_分布式计算_02

实际的处理比这个要复杂,比如请求过期处理等。

抽象设计

在框架内通个上,service与server都会向config注册,通信以及获取节点情况等,因此会有很多
相似的逻辑实现,所以很自然地,我把节点的关系重新定义为 config-node

深度学习分布式计算 分布式计算实现_云计算_03

为了简单处理,抽象了一个node,service与server共同继承node, 由node负责与config通信。

功能设计

config在框架里起到分配资源与注册服务的功能。

深度学习分布式计算 分布式计算实现_云计算_04

node功能

深度学习分布式计算 分布式计算实现_mapreduce_05

整体功能

深度学习分布式计算 分布式计算实现_深度学习分布式计算_06

下面我将对系统设计的协议进行设计。

协议设计

为了简单方便,我将模块间的通信采用protobuf。
(实际上在通用对外服务是不能用protobuf的,请大家思考为什么。)

config:

message ConfigRequest{
    optional ConfigAuthReq auth= 1;
    optional ConfigGetNodesReq get_nodes= 2;
}
message ConfigResponse{
    optional ConfigAuthRsp auth = 1;
    optional ConfigGetNodesRsp  get_nodes= 2;
    optional ConfigNotifyNodes  notify_nodes= 3;
}

server

message ServerRequest{
    required ServerDiag               diags = 1;
    required ServerDiagNodeType       diag_type = 2;

    optional ServerAuthReq            auth = 3;

    optional PrimeQueryReq            prime = 4;
    optional ServerWordCountReq       wc = 5;
    optional ServerQueryReq           query = 6;
    optional ServerBGReq              bg = 7;

}

message ServerResponse{
    optional ServerAuthRsp               auth = 1;
    optional PrimeQueryRsp               prime = 2;
    optional ServerWordCountRsp          wc = 3;
    optional ServerQueryRsp              query = 4;
    optional ServerBGResponse            bg = 5;
}

下面来定义我们的代码结构

代码架构

下面的代码架构主要争对config-node而设计。
config请求处理:

class Config{
  public:
     void OnRequest(const TcpConnPtr& con, ConfigRequest& request);
}

相应的node接口

class Node{
  protected:
      virtual void onConfigResponse(const TcpConnPtr& con,ConfigResponse& response);

  protected:
      void sendToConfig(const TcpConnPtr& con,ConfigResponse& response);
};

service与server继承node后实现onConfigResponse即可。

深度学习分布式计算 分布式计算实现_服务器_07

对外接口设计

为了接口方便,对外接口均设为http接口,并支持网页。

prime:

[get] http://dist.alibaba-inc.com/calc/prime

参数

含义

start

起始值

end

结束值

例:http://dist.alibaba-inc.com/calc/prime?start=1&end=10000

wordcount

[post] http://dist.alibaba-inc.com/calc/wordcount

参数

含义

data

待计算的文件

tokenize

分隔符

分布式查询
[post] http://dist.alibaba-inc.com/calc/query

参数

含义

app

应用名

db


collection

连接

data

查询条件

service与server程序架构

深度学习分布式计算 分布式计算实现_mapreduce_08

流程监控设计

为了方便了解每次请求的全链路情况,我在原架构中添加了日志与监控模块

深度学习分布式计算 分布式计算实现_服务器_09

功能显示设计

prime

深度学习分布式计算 分布式计算实现_mapreduce_10

wordcount

深度学习分布式计算 分布式计算实现_云计算_11

query

深度学习分布式计算 分布式计算实现_分布式计算_12

chart

深度学习分布式计算 分布式计算实现_mapreduce_13

业务流程图

prime

深度学习分布式计算 分布式计算实现_深度学习分布式计算_14

wordcount

深度学习分布式计算 分布式计算实现_云计算_15

对于map reduce运算,实际处理过程是这样的

深度学习分布式计算 分布式计算实现_分布式计算_16

query

深度学习分布式计算 分布式计算实现_深度学习分布式计算_17

这里的query在设计上是简化处理了的,生产上可能需要注意结果缓存,主从同步等。

从上面的设计上,我们可以发现,分布式处理的基础需要有一个config(配置服务器),及内部通信协议。
另外,节点的备份机制也很重要, 比如 config崩溃或者server崩溃的结果要做到不受影响。

崩溃恢复机制

config

对于config的功能,由于其核心功能是当前节点分布,是动态数据,因此数据安全可以采用的方法有很多,比如redis,mysql, mongo等。

深度学习分布式计算 分布式计算实现_mapreduce_18

其自身的功能崩溃恢复可以采用一种简单有效的方法。每个config节点都存有所有config的信息并且同步到各个node(service/server)。
每当新起一个config或者关掉一个,信息更新一次,node与config失联后再主动选择一个连接。

深度学习分布式计算 分布式计算实现_深度学习分布式计算_19

node

config提供node相互关注的能力, 即node A可以关注node B, 当node B断开后,config会通知像A一样所有关注它的node。

深度学习分布式计算 分布式计算实现_分布式计算_20