
算法研究:集群部署-众人能移万座山
一人难挑千斤担,众人能移万座山。很多场景下,一个人很难完成的任务,交给一个团队可以很容易的完成。程序算法也是同样的道理。
单台计算机一秒钟的计算量,人工可能要算几个月。虽然计算机比人的计算量已经大的非常多了,但是面对爆炸增长的大数据单台计算机也力不从心,也需要发挥集体的力量。
1. 计算机的组织方式
计算机如何协作完成大量的计算任务的哪?
1.1 计算机特征分析
计算机如何协作首先取决于计算机本身的特征:计算机由控制器、运算器、存储器、输入设备、输出设备五部分组成。
- 控制器:控制器是计算机五大部分的领导者,控制器负责协调其余四个部分的任务,指令的下发都是由控制器完成。
- 运算器:运算器是运算的执行者,是硬件化的运算程序。每个CPU都有硬件编程的运算器。
- 存储器:存储器是存储数据的地方,存储器包括CPU的寄存器、内存、外存、网络(网络也可以抽象为存储器,也可以认为是输入输出设备)。并且各存储器的访问速度是依次下降的。虽然外存从普通的机械硬盘可以升级成固态硬盘,但是整个存储器的访问速度的递减规律并未改变。
- 输入输出设备:输入输出设备包括键盘、显示器等。
1.2 协作模式分析
我们接着考察下计算机的协作模式:
1.2.1 单枪匹马-单内核模式
从计算机的五大组成部分的描述可知,单内核的计算机也是控制器、运算器、存储器、输入输出设备五大角色、五大组件协作的结果。
这五大组件是计算机不可分割的部分,此处将他们作为一个整体看待,故称呼此模式为单枪匹马模式。
1.2.2 上阵父子兵-多内核模式
一般多内核的计算机是有多个独享的控制器和运算器,共享存储器和输入输出设备。
与单内核模式相比,多个控制器和运算器可以同一时间同时执行指令,实际运行的速度可以逼近单内核模式的N倍。
1.2.3 规范化组织-集群模式
该模式是多个多内核或单内核设备的集群,设备之间通过互联网相联系。
在存储设备中,与寄存器、内存、外存相比,网络连接数据传输的速度是较慢的,因此与多内核模式相比,该模式的主要卡点就是网络的速度。
网络是共享的通道,如果网络中的设备比较多,每个设备访问同样的数据花费的时间会更长。
道理也很简单,虽然现实世界,修了很多高速公路,但是节假日高速上还是会堵车,所以使用集群一定要注意尽可能减少数据传输的量。
2. 任务分割
上文的三种协作模式,都需要做业务的分割,在数据量很大的情况下,不分割是无法完成任务的。由于多内核模式和集群模式主要用来处理数据量大的场景,所以这两种模式中任务分割使用的更多。
2.1 分割什么
计算机程序运行主要就是数据和程序两部分,所以分割就是分割这两部分。
2.1.1 分割数据
计算机对数据的常规操作是增加、删除、修改、查询。
业务数据都是按时间逐个添加的,但是数据查询时,并不总是按照输入时的顺序查询。
为了提高数据的查询效率,数据保存时会先排序,保存有序的数据,可以提高查询的效率。
由于数据的输入是不可预判的,数据可能输入1个、2个、100个、1000个,所以数据的排序只能按照数据存储的约束分割。
比如操作系统会划分固定大小的页,数据写满本页会自动排序并保存。最终保存的数据各个页都是有序的。
所以数据的分割应该是在保存时,就已经完成分割,而不是需要使用时再分割。
如果使用单内核模式或多内核模式,分割的数据可以直接保存在本地磁盘中。如果使用集群模式,分割的数据应该直接保存到指定成员设备的磁盘中。
2.1.2 分割程序
程序承载着数据处理的逻辑,业务的变化往往是最先被人感知到。所以对程序的分割都是由架构师完成。
比如模块、包、类、对象、方法都是不同颗粒度的程序分割单位。
即使现在的机器学习也并没有一个可以匹配任意场景的算法,还是要靠架构师匹配合适的算法。目前程序分割的任务主要靠人脑来构建。
2.2 分割依据
任务分割的重点落在“分”上。哪些可以分哪些不可以分呢?
2.2.1 原子操作不可分
原子操作是元操作,meta操作,是任务执行的最小单位,原子操作无需再分,也无法再分。比如写入日志,要么成功要么失败,不存在第三种情况,无法被部分阻断。
2.2.2 普通组合可分
原子操作不可分,数据是各种原子数据的组合,普通组合理论上可分。
如果多个原子数据按照普通顺序组合是可以任意分的。
比如日志系统,日志是按照写入时间顺序组织的普通组合,各个原数据之间并无强约束,此种数据最容易拆分。只要将同一个日志分到一组,可以按照任意数量拆分。这种方式代码实现最简单,Hadoop和各种NoSQL数据库主要处理的该种场景。
2.2.3 特殊组合不可分
特殊组合指的是事务,事务也是多个原操作的组合,不同于普通组合,事务是强约束,同一个事务要么同时成功要么同时失败。
比如:购物付款,客户的收货和商家的收费需要同时完成,不能出现客户收到货了,商家没有付款导致纠纷。
对于这种强约束,不能将同一事务的任务拆分到不同的系统上执行,没有通用的简单方案做拆分。
比如各种SQL数据库,对事务支持良好,但是将系统拓展到不同系统上部署时,约束很多,分布式部署复杂,只能由人工处理任务划分。比如可以人工决策将日志部分,部署到Hadoop平台。
2.3 分割时间
对于数据分割,应该在数据保存时就分割并保存到对应的系统上。大数据场景中数据量非常大,动辄几T几十T,数据一定要在保存时分布到设备集群中,这样数据处理时就可以直接让就近的计算机执行数据分析程序。
在给定算法的场景下,优化程序速度,只有两种办法:
- 将任务分配给更多的内核
- 让计算多走路,让数据少走路。(这个很有趣,现实世界中的口号是要让数据多走路,让人少走路。集群计算则是让计算都走路,让数据少走路。)
对于程序的分割,肯定是每次程序迭代时,按照模块化分割,面向对象设计就是当前最流行分割理念的实践。
2.4 分割角色
任务要拆解,就必须指定拆解的角色。这个拆解的人在线下管理中就是TeamLeader就是项目经理。
在算法程序中,这个人自然是架构师。
TeamLeader或者架构师是对整个任务流程最熟悉的人,任务拆分是一个技术活,需要做到“高内聚、低耦合”。
最理想的拆分方案是,不同人的工作不能相互依赖,至少不能全程相互依赖,如果A的每一步都需要等待B,这就是外部耦合性过高,A无法独立完成工作。
在数据运算中,需要多个CPU内核,甚至计算机集群一同参与运算,计算机之间肯定也是需要一个项目经理的角色。计算机的项目经理不仅参与数据的分割还参与任务的分配。
3. 任务分配
我们知道计算机程序运行主要就是数据和计算
数据:数据是程序处理的原材料和输出。
运算:运算是计算机程序的执行。Leader设备分配任务后,成员设备需要按照项目Leader的指令执行运算。
3.1 成员设备服从Leader设备的指令
任务分配的前提肯定是N个设备组成集群,人工或自动选举出Leader和成员,项目成员能接收Leader的指令并坚决执行。
作为集群,Leader和成员两个角色和对应的功能由单独的程序构建,并在任务启动前由项目人员部署到系统中。
3.2 Leader指令的数据来源
Leader指令如需处理数据,需要指定数据来源:
- 方式一:数据随指令一同送达
- 方式二:数据在其他设备上,数据地址随指令一同送达
- 方式三:数据在当前设备上,数据地址随指令一同送达
对于数据处理,一般而言正是因为数据量大才有分配的必要,显然如果数据量很大,数据随指令一同送达,会占用很多网络带宽,数据传输时间远长于指令获取时间。
方式二,随指令到达的是在其他设备上的设备地址,成员设备需要主动访问其他设备获取数据,显然该动作耗时也很长。
由于上述两种方式都需要访问其他设备获取数据,特别是数据量特别大的场景下,该方式效率极低。且获取数据的设备与处理数据的设备间隔的路由器交换机越多,路径可用带宽越小,数据传输越慢。
第三种方式效率最高,项目Leader设备仅传输指令即可。那么数据是何时保存在本地的呢?此种场景是数据保存时,就已经负载保存到本机,此时只需要处理指定的数据即可。
3.3 Leader指令的程序来源
Leader指令的程序来源与数据来源一样有三种方式:
- 方式一:程序随指令一同送达
- 方式二:程序在其他设备上,程序地址随指令一同送达
- 方式三:程序在当前设备上,程序地址随指令一同送达。
同数据来源,最高效的程序来源也是方式三。如果程序需要升级,可以由单独的程序升级指令提前将程序部署在本地。
3.4 程序指令的动态调整
任务分配并不是仅在任务首次触发阶段分配一次,特别对于数据量很大的时候,任务分配都是一点点分配的。
各个设备由于内存、算力、网络、其他任务等原因导致,同样的任务有的设备运算的快,有的设备运算的慢。
Leader设备需要保持与各设备的心跳通讯,监督各设备的任务完成进度和速度,将任务尽可能多的分配给算力充足的设备。
4. 结果上报
Leader设备指导各项目设备安排任务后,各设备需要及时汇报设备运行状态,执行阶段。
汇总的设备信息可以使Leader了解各设备完成的进度并能提供协助:
比如:同样的工作量A设备10分钟未完成,B设备5分钟就完成了,Leader设备可以将更多的设备分配给A设备。又因为某个原因导致,B设备的速度变长,要及时将数据分配给C设备。
只有各成员设备主动汇报当前处理进度,Leader设备才能管控整个集群运算的进度。如果成员设备不上报,Leader设备面对的就是各种黑盒子,就无法保证项目运算的效果。
各设备项目完成后,要上报给Leader设备哪些信息?
4.1 成功失败
比如保存、删除、修改操作,成员设备需要上报成功或失败,如果失败了,Leader设备可以安排重复写入或者安排给其他设备。
4.2 查询结果
比如查询最大值、最小值、或者符合条件的某个值,需要返回对应的数值。
4.3 概要信息
如果是排序信息,可以返回索引信息,比如:数值区间、数值数量。
5. 任务汇总
任务拆分不是目的,只是手段,Leader设备将任务拆分分配给成员设备执行,成员设备将结果反馈给Leader设备后,Leader设备需要汇总并给外部请求者返回结果。
原则上Leader设备作为领导者,可以不完成具体的业务,比如:不需要管理业务数据、不需要执行业务操作。
Leader设备的主要任务是管理好各设备节点,维护数据的目录。
Leader设备上不需要直接存储数据,但是当外部数据请求数据时,Leader设备只需要知道应该找哪个成员设备,将请求重定向给成员设备。或者给成员设备下发指令,然后将结果汇总返回给请求者。