如果我在Flink中调用rescale()
操作,我假设没有序列化/反序列化(因为数据没有跨节点(,对吗?此外,当调用rescale()
时,假设对象未被复制/深度复制是否正确?
我之所以这么问,是因为我正在传递一些大对象,其中99%在多个线程之间是常见的,所以如果在rescale()
之后在每个线程中重新复制这些对象,那将是巨大的RAM浪费。相反,所有不同的线程都应该指向该节点的java堆中的同一个对象。
(当然,如果我调用rebalance
,我希望公共对象到其他节点会有一个序列化,即使每个其他节点上都有几十个线程?也就是说,在其他节点上,该节点的所有线程都只能共享一个公共对象的副本,对吧?(
根据rescale((文档,会有网络流量(以及序列化/反序列化(,只是没有rebalance()
那么多。但正如几位Flink提交者所指出的,与不平衡数据的成本相比,数据偏斜会使网络流量的减少变得微不足道,这就是为什么当流拓扑发生变化时,rebalance()
是默认操作。
此外,如果您正在传递大量公共数据,那么可以考虑使用广播流在节点之间更有效地共享这些数据。
最后,从概念上讲,考虑子任务与线程更容易。每个操作符都作为一个子任务运行,子任务(在一个任务管理器上(确实是线程化的,但操作符实例是独立的,这意味着你不必担心操作符级别的多线程(除非你使用类变量,这通常是个坏主意(。