flink 1.8
迭代次数Iterations
迭代算法在数据分析的许多领域都有应用,如机器学习或图计算。这些算法能够从大数据集中提取一些有意义的特征信息。为了在大数据集上运行这些算法,需要以大规模并行方式执行迭代。
Flink程序通过定义一个步进函数(step function)并将其嵌入一个特殊的迭代操作算子来实现迭代算法。这个操作算子有两种变体:Iterate和Delta Iterate。这两个操作算子都在当前迭代状态上反复调用step函数,直到达到一定的终止条件。
在这里,我们提供了这两种操作算子变体的背景知识,并概述了它们的用法。编程指南 programming guide解释了如何在Scala和Java中实现这些操作算子。我们还通过Flink的图形处理API Gelly支持以顶点vertext为中心和聚集求和的迭代。
在这里,我们提供两种算子变体的背景并概述它们的用法。该节目指南介绍了如何实现算子在这两个Scala和Java。我们还通过Flink的图计算API Gelly支持以顶点为中心和聚类求和的迭代。
下表提供了这两种操作符的概述:
Iterate |
Delta Iterate |
|
Iteration Input迭代输入 |
Partial Solution 迭代输入 |
Workset and Solution Set Workset 和 Solution Set两个数据集 |
Step Function 步长函数 |
Arbitrary Data Flows 任意的数据流 |
|
State Update 状态更新 |
Next partial solution 下一轮迭代的输入 |
1.Next workset 2.Changes to solution set ● 下一个workset数据集 ● 对solution set数据集更新 |
Iteration Result迭代结果 |
Last partial solution 最后的迭代结果 |
Solution set state after last iteration 最后一次迭代后的solution set数据集状态 |
Termination 终止 |
1.Maximum number of iterations (default) 2.Custom aggregator convergence ● 最大迭代次数(默认) ● 自定义聚合器收敛 |
1.Maximum number of iterations or empty workset (default) 2.Custom aggregator convergence ● 最大迭代次数(默认) ● 自定义聚合器收敛 |
Iterate Operator
Iterate Operator 是一种简单的迭代形式:每一轮迭代,Step function 消费整个数据集(前一个迭代的结果或初始数据集),计算出下一轮迭代的输入(也称为 Next Partial Solution)(例如map,reduce,join,等等。),满足迭代的终止条件后,会输出最终迭代结果。
分析上图的流程:
有多个选项可指定迭代的终止条件:
你也可以考虑伪代码中的迭代操作算子:
IterationState state = getInitialState();
while (!terminationCriterion()) {
state = step(state);
}
setFinalState(state);
有关详细信息和代码示例,请参阅编程指南 Programming Guide。
例如:递增的数字
在以下示例中,迭代地递增一组数字:
1.迭代输入:初始输入从数据源读取的五个记录(整数1到5)。
2.Step function:单个 map 算子,将整数字段从i增加到i+1。将应用于输入的每个记录。
3.Next Partial Solution:Step function 的输出(map 算子的输出),反馈给下一次迭代。
4.迭代结果:经过十次迭代,最初的数字将被增加十,新的数据集为整数11到15。
// 1st 2nd 10th
map(1) -> 2 map(2) -> 3 ... map(10) -> 11
map(2) -> 3 map(3) -> 4 ... map(11) -> 12
map(3) -> 4 map(4) -> 5 ... map(12) -> 13
map(4) -> 5 map(5) -> 6 ... map(13) -> 14
map(5) -> 6 map(6) -> 7 ... map(14) -> 15
注意,1、2和4可以是任意的数据流。
Delta Iterate
Delta Iterate 实现了增量迭代。有选择地修改其解中的元素并演化解决方案,而不是完全重新计算它。
在适用的情况下,这会使算法更高效,因为解中的每个元素不会都出现在每次迭代中。这样可以专注于解中的的 hot part,并保持 cold part 不受影响。
分析上图的流程:
Delta Iterate 的默认达到指定的最大迭代次数或当生成的下一个工作集为空时,迭代将终止。还可以指定自定义聚合器和收敛标准函数。
你也可以考虑伪代码中的迭代操作符:
IterationState workset = getInitialState();
IterationState solution = getInitialSolution();
while (!terminationCriterion()) {
(delta, workset) = step(workset, solution);
solution.update(delta)
}
setFinalState(solution);
有关详细信息和代码示例,请参阅编程指南 programming guide 。
示例:在图表中传播最小值
在下面的例子中,每个顶点都有一个ID和一个着色。每个顶点将把它的顶点ID传播到相邻的顶点。目标是为子图中的每个顶点分配最小ID。如果接收到的ID小于当前顶点的ID,那么它将更改为使用接收到的ID的顶点的颜色。
初始输入被设置为workset and solution set。在上图中,颜色可视化solution set的演化过程。每次迭代时,最小ID的颜色在相应的子图中展开。同时,每次迭代的工作量(交换和比较顶点ID)都会减少。与此相对应的workset 数据集的大小也会减小,其在三次迭代之后七个顶点将变为零,此时迭代终止。得到的最终结论是,下半部分的子图(5-6-7)比上半部分的子图(1-2-3-4)先收敛,delta迭代能够通过workset是否为空来捕获到这一点。
在上半部分的子图(1-2-3-4)中,ID1(橙色)是最小的ID。在第一次迭代中,它将被传播到顶点2,顶点2随后将其颜色更改为橙色。顶点3和4将接收ID2(黄色)作为它们当前的最小ID并更改为黄色。因为顶点1的颜色在第一次迭代中没有改变,所以可以在下一个workset工作集中跳过它。
在下半部分的子图(5-6-7)中,ID 5(青色)是最小ID。下半部分的子图(5-6-7)的所有顶点将在第一次迭代中接收到它。同样,我们可以跳过未更改的顶点(顶点5)用于下一个workset。
在第二次迭代中,工作集的大小已经从7个元素减少到5个元素(顶点2、3、4、6和7)。在此迭代之后,下半部分的子图(5-6-7)已经收敛(图的cold part),因为它在workset中没有元素,而上半部分的子图(1-2-3-4)需要对剩下workset数据集中两个元素(顶点3和4)进行进一步的迭代(图的hot part )。
当工作集在第三次迭代之后为空时,迭代终止。
Superstep Synchronization
我们将迭代操作算子的每个步骤函数的执行称为单个迭代。在并行设置中,在迭代状态的不同分区上并行计算step函数的多个实例。在许多设置中,对所有并行实例上的step函数的一次评估形成了所谓的superstep,这也是同步的粒度。因此,迭代的所有并行任务都需要在初始化下一个superstep之前完成superstep。终止准则也将被评估为superstep函数。
https://ci.apache.org/projects/flink/flink-docs-release-1.8/dev/batch/iterations.html
https://flink.sojb.cn/dev/batch/iterations.html#example-propagate-minimum-in-graph
https://www.jianshu.com/p/f70eb1312c03