作者回复: 谢谢你的提问!其实我们在第24讲中知道,PCollection是具有无序性的,所以最简单的做法bundle在处理完成之后可以直接append到结果PCollection中。
至于为什么需要重做前面的bundle,这其实也是错误处理机制的一个trade-off了。Beam希望尽可能减少persistence cost,也就是不希望将中间结果保持在某一个worker上。可以这么想,如果我们想要不重新处理前面的bundle,我们必须要将很多中间结果转换成硬盘数据,这样一方面增加很大的时间开销,另一方面因为数据持久化了在具体一台机器上,我们也没有办法再重新动态分配bundle到不同的机器上去了。
作者回复: 谢谢你的提问!其实文章中所讲到的随机分配并不是说像分配随机数那样将bundle随机分配出去给workers,只是说根据runner的不同,bundle的分配方式也会不一样了,但最终还是还是希望能最大化并行度。
至于完美并行的背后机制,Beam会在真正处理数据前先计算优化出执行的一个有向无环图,希望保持并行处理数据的同时,能够减少每个worker之间的联系。
Beam据我所知是有的,BEAM-7131 issue就有反应这个问题。
作者回复: 谢谢留言!总结得不错!
作者回复: 谢谢你的提问!这个问题很好啊,运行大型的Beam pipeline遇到OOM也是有可能的。要配置底层资源的话要看Runner支不支持,像如果将Google Cloud Dataflow作为Runner的话,我们可以通过配置PipelineOption来达到目的。底层使用Spark的话我个人还没有使用过,不过应该是可以用SparkContextOptions来配置的。
作者回复: 的确如此
作者回复: 谢谢留言!哈哈,需要表达的内容不一样了。
作者回复: 谢谢你的提问!这个问题非常好啊,如果你所说的是stateful processing的话,那它的错误处理机制和stateful-less会不太一样。Stateful processing里的ParDo在处理每一个元素的时候会将它的state持久化,也就是保存到外部的storage中,下次需要用到这个元素的时候会再读取这个元素的state。如果是发生了错误的话,会有机制reclaim这些states或者是invalidate它们。
作者回复: 谢谢你的提问!这个依赖worker1和worker2计算结果的Transform会一直等待。但是与此同时,worker2可以做其它的计算,甚至有可能worker1的计算如果一直出错,Beam会将这个bundle重新分配给worker2来计算。
作者回复: 谢谢你的留言!前后bundle保不保留这个还要看你的执行DAG需不需要还用到这个bundle。至于保留前后关系的话主要是用于在发生错误的情况下重新trace back到最开始的那个transform,这个信息从DAG中就可以找到了。
作者回复: 谢谢你的留言!确实是可以直接学习,不过我也建议如果平时有时间的话,可以看看这些计算机的基础。像操作系统的话里面的一些调度算法或许可以给你平时的实际应用有一些启发。
作者回复: 谢谢你的留言!如果我没有理解错你的问题的话,我想你说的“边界”指的就是在第23讲中讲到的Beam的统一模型层了。
其实Beam提供的是在Dataflow Model论文里面的一种批流统一处理的思想,数据处理引擎如果能够按照这个思想提供出相应的APIs的话那这个数据处理引擎就可以成为Beam的底层Runner。
最后一问的话是的,PCollection抽象就是Spark中的RDD。
作者回复: 谢谢你的留言!你这样的理解其实也没有错,如果Beam优化器能优化合并掉一些步骤的话,那确实实际产生出来的bundle会比理论上可以产生出来的bundle要少。
作者回复: 谢谢你的提问!这个问题还是要看情况吧,如果多步骤的Transform都是ParDo的话,那确实可以按照你说的做法去做。不过当Transform涉及到Combine或者Flatten这种Transform的话, 那就必须等到这一阶段所有的Transform完成了之后才能够进行下一步的Transform了。