我们正在构建一个流式传输管道,其中数据可能会在几个步骤中遇到不同的错误,例如序列化错误,验证错误和写入存储时的运行时错误。每当错误发生时,我们将数据定向到侧输出。错误处理逻辑在这些侧输出上是相同的。我们将数据写入常见错误存储区以进行后期处理/报告。
构建pipleine至少有三种选择。 (下面的伪代码)
使用新的变换实例处理每个侧面输出。
sideOutput1.apply(new HandleErrorTransform());
sideOutput2.apply(new HandleErrorTransform());
使用单个变换实例处理每个侧面输出。
Transform errorTransform = new HandleErrorTransform();
sideOutput1.apply(errorTransform);
sideOutput2.apply(errorTransofrm);
展平这些侧输出的输出,并使用单个转换来处理所有错误。
PCollectionList.of(sideOutput1).and(sideOutput2)
.apply(Flatten.<ErrorMessage>pCollections())
.apply(new HandleErrorTransform());
是否有任何关于使用哪一个的建议,以获得更好的可扩展性和性能?或者也许没关系?
答案 0 :(得分:0)
1和2基本相同 - 因为管道是序列化的,所以共享没有任何优势。
选项3可能具有一些优势,因为您可以更轻松地向该路径添加更多逻辑。它可能会更容易扩展,因为最终位置只有一个源写入元素,这意味着缓冲区更少,批处理元素的机会更多等。
3的一个缺点是使用flatten将阻止在HandleErrorTransform
中创建的任何窗口,直到所有主要管道都处理了这些时间戳。这可能是可取的 - 来自此窗口中记录的所有错误 - 但如果不是,则可以使用触发器来解决。