开发者学堂课程【分布式计算入门:统一计算框架】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/375/detail/4703
统一计算框架
内容介绍
一、内存计算
二、内存计算问题
三、算子类型
四、难点
一、内存计算
关于内存计算,在广义上没有什么不适内存计算,大家所有计算都会用到内存的方式,狭义的定义是最大限度利用内存容量,最大限度可复用内存数据,内存数据可编程,框架内置容错的机制,存在 Replication 和 partition 的机制,这样才构成了狭隘上的内存计算范畴。
Batch : 可大可小
串并行 DAG:Batch 内串行,Batch 间并行
MRM
所以从内存计算引出到计算,认为计算分为三大要素,第一数据结构,第二功能,三控制逻辑,而 MapReduce 的出现是弱化了数据结构,抽象的功能让你只能去继承 MapReduce 编写程序,大大简化了控制逻辑,只能把控制逻辑编写成 Dag,不能自由组合,在某种程度上,他束缚了整个的编程能力。
思考一下,是不是还是以数据结构为核心(这里指分布式数据结构),数据结构的运算定义了从 a 到 b , b 到 a 的数据对象,他们之间的血缘关系, spark 的出现往传统方向靠近,spark 的问题是 Immutable 有什么好处,缺陷。所以需要提供更多的原语,而不是 mapreduce,需要对用户开放控制逻辑,用户可以在它的程序下面写出任意程序代码,和 sql 有点不同的是,如果用户把所有要做的事表示成 sql ,系统可以知道他要做什么事情,他可以在范围之内做出优化的动作,而且成控制逻辑功能逻辑的方法,很多时候需要用分布式执行,返回到控制层,分布式系统是不知道更高的信息,但是他取的是灵活性。
二、内存计算问题
基本的问题包括用户复杂的控制逻辑,Dag 运行效率,Distributed cache 的扩展问题,迭代计算,实际业务中的 case 问题,任务间如何共享数据,还有如何定义分布式数据结构。进而要考虑一个 adhoc 系统,他需要一线架构索引,基线,流式增量的合并,不同的文件所以加载后摆放到本地,然后再进行在线 service ,如何在各种复杂系统中做迁移,在离线,流式,迭代,在线计算做迁移。
所以换一个维度看计算,尝试从是否需要分批 Shuffle 方式是推还是拉,后世节点是预先拉起还是 Shuffle 拉起,通过这三个维度的组合可以发现,如果―A0B1C0,可以认为它是传统离线模式,―A0B0C1是 service mode ,―A0B0C1是流计算,这些只是模块不同的组合。尝试去 build 以这几种模块去设计系统,如图,
Application,可以嵌入在任何的用户环境,定义的各种分布式操作以及算子原语,用户可以使用它编写各种单机程序,以及分布式运行。Session,是指不同 job 复用数据的边界,DAGSession 可以复制不同的数据在内存中,DAGSession,不同的逻辑执行计划来复用相同的物理执行计划,BlockSession 支持 job 间复用用数据的全局管理,VertexManage 可以接受更细节的控制逻辑,localAM 保持与 am 数据结构一致的本地 am。
三、算子类型
算子层抽象出了五个基础算子类型:map,reduce,merge,shuffle,union
这五类算子是正交的,但是她的全集能组合出任何复杂算子,这张图是五个算子,在计算结构中的扭转,
四、难点
RC 的引入引发了一系列的问题,比如看到了资源一致,所以要进行本地调度,灵活的表示层会付出,泛型的代价,非原生的消耗成本是成倍数的增长,包括需要在这一层上面抽象出 schema 的 Table ,大量复用对象池和内存池,因为存在着本地的所以和摆放信息,所以引入了优化器,而不是全部依赖 globa l优化器,在分布式变量引入了 LocalDataSet ,所以用户可以和本地进行交叉式运算。分布式变量引入版本 Version,Partition/replica引入了不同的分布式变量亲缘以及计算的关系,用Tag来组合,Version 的引入使得分布式变量变得可读可写。在 ac 端支持 sql 的时候,执行计划可以简单的,分布式的 .match 来询问这个 DataSet 支持在 a 字段下支持等于的挑选操作。有所以和没有所以,逻辑执行计划经过优化后会变成不同的物理执行计划。
那么引入 CPU 框架,对不同的 join 会生出十几种优化策略,大量使用下推逻辑,希望一个处理逻辑到处运行,上下文运行的 context 不同,可以在离线, stream ,迭代,准实时,实时,在线,图分析复用。对于一个在线的场景,可以建立 dag,提前拉起 pattern 固定,大量执行下沉,利用 Codegen 做本地优化,以及内存优化,长尾控制,本地调度,在线的截断策略。
而分布式变量支持可读改,串并行 DAG 组合,支持 push/pull 模式,Shuffle service 单独抽离,进而会进一步思考 BD 是否进一步与 DB 融合,用户不希望数据拖动出来,所以需要更好的 schema 控制,建立更丰富的 index ,本地调度以及 CBO,目标客户,考虑将 DAG 和 MPP 延合成汇合架构,除了价格的设计,也要从微观的代码方面做到极致的优化。
下面介绍一下在向量化和 Codgen 做出的优化,简单来看,如下的这些代码是行存储,行运算的话,即便是在内存中也存在大量的跳跃,
GetBigint(*record, 0, &c0);
GetDouble(* record, 1, &c1);
GetBigint(*record, 2, &c2);
GetDouble(*record,3, &c3);
GetBigint(*record, 4, &c4);
GetDouble(* record, 5, &c5);
double r0 =c0+ c1;
for (uint32_ _ti= 0;i < input.mView- >GetCount(); ++i){
if(c0== NULL |Ic1 == NULL)
r1 = NULL;
else *(r1++) = *(c0++)+ *(c1++);
}
如果利用列的存储,单指令多数据集 CPU 的优化变成列的计算,那么在内存里一次可以读出多行的这一列,当然存储是混合存储,提高性能。