0

我们正在构建一个流式管道,其中数据可能会在几个步骤中遇到不同的错误,例如序列化错误、验证错误和写入存储时的运行时错误。每当发生错误时,我们将数据定向到侧面输出。这些侧输出的错误处理逻辑是相同的。我们将数据写入通用错误存储以进行后期处理/报告。

构建管道至少有三个选项。(下面的伪代码)

  1. 使用转换的新实例处理每个侧输出。

    sideOutput1.apply(new HandleErrorTransform());
    sideOutput2.apply(new HandleErrorTransform());
    
  2. 使用转换的单个实例处理每个侧输出。

    Transform errorTransform = new HandleErrorTransform();
    sideOutput1.apply(errorTransform);
    sideOutput2.apply(errorTransofrm);
    
  3. 将这些侧输出的输出展平,并使用单个转换来处理所有错误。

    PCollectionList.of(sideOutput1).and(sideOutput2)
      .apply(Flatten.<ErrorMessage>pCollections())
      .apply(new HandleErrorTransform());
    

对于使用哪一个以获得更好的可扩展性和性能,是否有任何建议?或者也许没关系?

4

1 回答 1

0

1 和 2 基本相同——因为管道是序列化的,所以共享没有任何优势。

选项 3 可能具有一些优势,因为您可以更轻松地向该路径添加更多逻辑。扩展可能会更容易一些,因为只有一个源将元素写入最终位置,这意味着更少的缓冲区,更多批处理元素的机会等。

3 的一个缺点是使用 flatten 将阻止在 中创建的任何窗口,HandleErrorTransform直到所有主管道都处理了这些时间戳。这可能是可取的——此窗口中记录的所有错误——但如果不是,则可以使用触发器来解决。

于 2017-02-06T17:09:54.187 回答