FastDCS是一个使用C++开发的轻量级的分布式计算系统,使用它可以解决海量数据的实时计算和需要分布式服务方面的问题。

1.1 背景简介

FastDCS最初是为了解决 瑞读网 的文件格式转换工作而开发的,瑞读网是一家提供数字阅读的服务提供商,每天约有10万份Office文档和上千份期刊杂志排版文件需要转换成PDF、JPG、FLASH、HTML、Txt和ePub等文件格式,瑞读网将FastDCS部署在4台服务器上,从2008年至2012年累计提供转换服务7千万次,生成各式文件数40亿,总量300TB的数据;

2013年FastDCS进行了代码重构,大幅度提升了系统的性能和可靠性,并将代码和相关设计文档全部开源。

1.2 系统特性

  • FastDCS是一个轻量级的分布式计算系统,开发者使用它可以快速的完成开发和部署工作,如同系统的名称Fast Distributed Computing System。
  • FastDCS适合用于需要长期运行的计算处理业务,如瑞读网提供了长达4年的在线文档转换服务,它和MapReduce模式的批处理系统有很大的区别。

1.3 系统说明

从系统组成划分的角度来看,FastDCS包括了管理节点(Master)和工作节点(Worker)

  • 管理节点Master对整个计算集群的服务状态、任务分发、计算调度等服务进行管理。
  • 工作节点Worker作为计算单元接受Master服务器的管理,完成整个计算集群的计算任务。

1.3.1 系统处理流程说明

FastDCS系统整体架构FastDCS系统整体架构

如图1-3-1,系统处理流程有如下几个部分组成:

  1. 数据流将需要计算的数据保存在外部的存储系统中,如数据库或分布式存储系统中;
  2. Primary master节点从外部存储系统中不断获取新的计算任务,保存在Primary master节点中;
  3. Secondary master节点主动从Primary master节点获取一部分计算任务副本;
  4. Worker节点主动从Secondary master节点获取计算任务进行计算处理;
  5. Worker节点将计算结果提交给Secondeary master节点,所有的Secondary master节点将计算结果汇总到Primary master节点;
  6. Primary master节点将计算结果保存到外部的存储系统。

1.3.2 计算任务处理流程说明

计算任务处理流程

计算任务处理流程

如图1-3-2,计算任务处理流程有如下几个部分组成:

  1. Primary master节点保存了整个服务集群的所有计算任务;
  2. 一台Master节点加入Master服务集群后,通过Lease机制从Primary master节点租赁一部分计算任务,将副本数据保存在本节点(副本有效期10秒);
  3. 每个Worker节点分别从所属的Secondary master节点获取一份计算任务进行计算;
  4. 当Secondary master节点退出或异常时,它下属的Worker节点直接从Primary master节点获取计算任务;
  5. Worker节点完成计算任务后,将计算结果提交给所属的Secondary master节点,由Secondary master节点将计算结果汇总提交给Primary master节点保存到外部的存储系统;

1.4 架构剖析

1.4.1 系统可靠性

FastDCS通过同时运行多个管理节点Master来避免服务集群的单点故障问题,多个Master节点之间通过环形算法选举出Primary master节点对服务集群进行主控,其它的Secondary master节点承担一部分辅助管理,确保了服务集群的可靠性的同时也避免了单点过载的问题。

Master选举算法

Master选举算法

如图1-4-1,FastDCS系统中所有Master节点按照前后顺序组成一个环新形结构,每个Master节点都保存了这个环形结构的排序表,因此每个Master节点都知道自己的所有后继Master节点。

Master选举算法说明

假设当Master(1)节点发现到Primary master不再工作时,它将启动一个召集选举的过程:

  1. Master(1)构造一个包含自己进程编号的 ELECTION 给后继进程,如果直接后继进程没有响应,Master(1)就将消息发送给下一个Master节点,直到找到一个正常运行的Master节点;
  2. Master(2)接收到 ELECTION 消息的进程将自己的编号增加到 ELECTION 消息中,然后按照同样的方式将消息发送给后继Master节点。这样,消息在环上的传递将构造一个包含所有正常运行的Master的编号表;
  3. 当 ELECTION 消息最后回到召集选举的Master节点时,消息中最大编号的Master节点即成为选举的胜利者。召集选举的进程将消息类型改为 COORDINATOR,然后将消息沿着环重新发送一次,将选举结果通知所有的Master节点;
  4. 当 COORDINATOR 消息重新回到召集选举的Master节点时,算法终止;

同样,在环选举算法中,也可能同时存在多个召集选举的过程。当在这个时刻环结构不变时,只是消息数量多一些,最后的结果也是一致的。

1.4.2 系统可用性

primary-secondary协议

primary-secondary协议

如图1-4-2,FastDCS采用primary-secondary(也称 primary-backup)的中心化副本控制协议。 在FastDCS系统中,数据被分为由Primary master节点管理着的元数据和由Secondary master节点管理着的数据副本。

Primary master节点负责维护数据的更新、并发控制、协调副本的一致性

  1. 数据更新都由Primary节点协调完成;
  2. primary master节点从外部存储系统获取新数据;
  3. Primary master节点进行并发控制即确定并发更新操作的先后顺序;
  4. Primary master节点将更新操作发送给secondary 节点;
  5. Primary master根据secondary master节点的完成情况决定更新是否成功并将结果返回外部存储系统;

Secondary master节点管理一部分数据副本

  1. Primary master节点将数据分为数据段,以数据段为副本的基本单位;
  2. 将数据副本分散到集群中个,每个Secondary master节点上都有一部分元数据的副本;
  3. Secondary master节点使用数据副本完成服务集群的一部分管理工作,来分担系统的整体压力;

1.4.3 数据一致性

Lease机制

Lease机制

如图1-4-3,FastDCS采用Lease机制能够确保在服务器或网络异常等情况下,仍然保持分散在服务集群中的数据具有很强的一致性。

  • Primary master节点在向各个Secondary master节点发送数据的同时向节点颁发一个lease;
  • Primary master节点在lease有效期内,保证不对已经颁发的数据进行修改;
  • Primary master节点在lease有效期失效后,才会对颁发的数据进行重新下发或修改;
  • 只有Primary master节点才能修改元数据,所以在任何时间Primary master节点中的数据都是最新的;

1.4.4 数据结构说明

FastDCS中的数据结构定义文件在/src/server/tracker_protocol.proto文件中。

其中只有FdcsTask、KeyValuesPair和KeyValuePair三个数据结构需要开发者了解掌握,其他的数据结构用于FastDCS系统内部的处理,与开发者无关。

数据结构FdcsTask用于计算任务的调度和保存计算结果,为了让FdcsTask能够以一种通用的结构满足各种应用场景中数据传输的需要, FastDCS使用了可以包含多个KV键值对的变量来满足需求,同时使用Google Protocol Buffers对系统内部的数据结构进行定义以及序列化操作。

1.4.4.1 FdcsTask:计算任务数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
message FdcsTask {
// 任务ID
required string task_id = 1 [default = ""];
// 任务租约有效时间
optional int64 lease_time = 2 [default = 0];
// 多个KeyValuesPair数据结构
repeated KeyValuesPair key_values_pairs = 3;
}
// 为方便理解FdcsTask数据结构
// 下面列出了在Demo程序'单词排序应用实例'中的一个计算任务FdcsTask变量内部的数据内容如下:
FdcsTask = {
task_id = id1,
key_values_pairs = [
{key='A', value=[{key=单词1, value=count1},{key=单词11, value=count11}, ...]}
{key='B', value=[{key=单词1, value=count1},{key=单词11, value=count11}, ...]}
{key='C', value=[{key=单词1, value=count1},{key=单词11, value=count11}, ...]}
...
]
}

FastDCS中的计算任务数据结构FdcsTask有只有3个变量组成,分别是任务ID、任务租约有效时间、一对多KV键值对三个部分组成:

  • task_id(任务ID):用于在整个工作任务中进行唯一标示某一项计算任务;
  • lease_time(任务租约有效时间):FastDCS系统内部控制数据有效性的变量,开发者可以忽略该变量;
  • key_values_pairs(一对多KV键值):每个计算任务通过该变量能够保存多个一对多的K-V键值对数据,可以用来保存自定义的多个变量;

1.4.4.2 KeyValuesPair:一对多KV键值对数据结构

1
2
3
4
5
6
7
8
message KeyValuesPair {
optional bytes key = 1;
// value中以字节的方式保存了多个KeyValuePair数据结构
repeated bytes value = 2;
}
// 为方便理解KeyValuesPair数据结构
// 下面列出了在Demo程序'单词排序应用实例'中的一个计算任务KeyValuesPair变量内部的数据内容如下:
key_values_pairs = {key='A', value=[{key=单词1, value=count1},{key=单词11, value=count11}, ...]}
  • KeyValuesPair其中的Key用来保存自定义变量的名称,value用来保存该自定义变量的数据;
  • value中的数据可以使用多个一对一KV键值对KeyValuePair数据结构进行填充。

1.4.4.3 KeyValuePair:一对一KV键值对

1
2
3
4
5
6
7
message KeyValuePair {
optional bytes key = 1;
optional bytes value = 2;
}
// 为方便理解KeyValuesPair数据结构
// 下面列出了在Demo程序'单词排序应用实例'中的一个计算任务KeyValuePair变量内部的数据内容如下:
{key=单词1, value=count1}
  • KeyValuePair其中的Key用来保存自定义变量的名称,value用来保存该自定义变量的数据;
  • value中的数据可以使用具体的数据进行填充;
  • 注意:KeyValuesPair 和 KeyValuePair数据结构名称只差一个表示是复数的字母s;