在讲分布式之前,我们先从需求入手,有这么一个需求,是要求构建一个任务处理的集群。

需求 要求满足以下特点:

高性能:对数据的分发和处理都必须低延时并且高效。 高可靠性:主要是对集群的健壮性的要求,就是整个集群,在网络抖动和部分机器挂掉的情况下,能保持较高的可用性。 强扩展能力:尽量减少对有状态的数据的依赖,便于横向或者纵向的扩展我们的实例,来满足大规模分布式计算的需求。 根据以上三个需求,我们来设计一个系统。 分析 如果要满足以上三个条件,那么我们就对需求进行拆解,通过功能和架构设计来满足,来尽量适配我们的设计需求。

高性能: 那么如何做到高性能,其实在整个架构中,高性能主要体现在降低IO操作,提高缓存能力。大多数的系统设计都可能跑不过这链各个方向。 降低IO的方式在整个系统设计中主要体现在两个方面:网络IO 和磁盘IO。 在大的集群中必不可少要有大量的网络数据传输,包括节点间的状态通信,数据流的同步等。这些都可能比较占用和依赖IO资源,我们在设计系统高性能的时候,尽量本着减少对网络IO的依赖关系,我们可以往这两方面思考:

减少网络传输次数 减少网络传入大小 网络的IO的基本优化,也就是这两个方面,那么对应磁盘的IO操作我们可以通过缓存来解决,尽量把数据放在内存里缓存起来,尽量减少任务的变更操作,或者借鉴 MapReduce的思想,增加集群的并行处理。那么针对任务处理主要有这么几点优化。

减少磁盘IO,缓存数据。 并行计算,任务分派和多节点处理。 同时,我们也对数据结构上也有要一些考虑,针对不同的使用场景,也需要考虑包括使用高性能的并发数据结构。 高可靠性: 为了满足整个集群的高可用性需求,我们需要考虑整个任务系统的健壮性,那么就会考虑到引入分布式协调组件的方式来提升系统的健壮性,从集群设计上来说,多引入一个组件,也会导致我们的系统复杂度的提升。在系统设计中,我们要尽量遵循“高内聚,低耦合”的设计思想。所以,引入的分布式协调组件,及时不能正常工作,也只是影响集群部分功能,不是强依赖的需求,暂时部分功能缺失,不能影响我们整体的功能,等到组件正常回复后,我们系统能正常运转就好了,这才是我们高可靠的目的所在。

引入分布性协调组建,我们就会引入两个l逻辑概念:控制层面和数据层面; 控制面:主要是和协调组件交互,负责整个集群层面控制逻辑的交互,包括选leader、watch监听状态,注册worker 等。 数据面:主要指定是整个集群中,数据处理和流动,包括数据分发,解析、处理等。 这两个层面是相互独立且相互协调,像汽车的发动机的几个系统相互协作。

那么我们的思路:

考虑到做任务,那么我们就会考虑, 需要有一个节点,来分派任务。<—数据面的情况 那这个节点怎么来的,抢出来的节点。 <— leader 控制面的概念 了解了基本概念后,我们也引入了不同的逻辑概念下的这么几个角色信息: 控制面: Leader:控制面中的角色,通过分布式协调组件选出来的角色信息,一个集群只有一个。 Follower: 是leader的候选者,如果发现leader 不存在,自己会主动抢leader ,直到有一个抢占成功。

数据面: master 的用来拉取、分派任务、维护worker 和任务的动态平衡。worker 用来干活的。 Leader 和master 是不是在一起。可以在一起,也可以不在一起,等到集群大的情况,可能这块的逻辑就分开了。 master 来做的事呢,就是分配好资源给worker 处理。 那么维持整个集群的高可靠性呢? 这个集群的有master 拉取任务,分派给worker 进程处理的这个流程。

master 挂了,这个集群中,是通过 控制面的 follow 抢占锁 来 获取新的leader 。 worker挂了。那么master 会watch worker的工作目录,对资源重新分派,来维持这个集群的可靠性。

那么我们引入了分布式协调组件,主要考虑这么几点:

单点故障,不影响整个集群运行,也就是分布性协调组件本身的高可靠性; 分布式协调组件,无状态性,不能把分布式协调组件当成持久化存储,不能太依赖其数据。 其实,大多数基于Paxos 和Raft共识协调组件例如: zookeeper、 Etcd都满足我们的需求。 整个集群通过这么几个角色信息相互协调,来识别状态,来维护整个集群的有序稳定的运行。

强扩展能力: 考虑强扩展能力,我们会考虑,横向添加资源操作。集群中的任务太多了,worker 除了增加线程外,也已经到瓶颈了。那么我们集群中可以横向加节点来处理 集群中的任务 如果集群足够大,leader 和 master 节点也因为有大量的数据交互,导致系统整体功能变差,我们可以通过对集群拆分的方式,划分为多个集群的方式来处理不同的任务需求。这也是算法里“分治”的思想。

总结,本次我们通过对一个分布式系统的需求梳理,确定我们要实施的系统整体的设计方向和大体上的方案。同时,我们把需求具体化,通过拆解控制面和数据面的功能关系,这样我们的目标清晰和明确不少。后续,我们会根据需求,开始先从流程出手,进行架构设计,然后一步步深入讲解。