Apache flink 在ApacheFlink中处理有毒消息
我正试图找出用ApacheFlink处理有毒消息/未处理异常的最佳实践。我们的工作是对物联网设备的位置数据进行实时事件处理。可能出现以下两种情况:Apache flink 在ApacheFlink中处理有毒消息,apache-flink,Apache Flink,我正试图找出用ApacheFlink处理有毒消息/未处理异常的最佳实践。我们的工作是对物联网设备的位置数据进行实时事件处理。可能出现以下两种情况: 数据在某些方面不正确-例如无效值 由于一些我们没有预料到的边缘情况,数据触发了一个bug 目前,由于只有一条消息,我所有的数据处理都停止了 我看到了两个建议: 捕获异常-这需要我用捕获每个运行时异常的东西包装每个逻辑片段 使用边输出作为一种DLQ——从我所能看出,这似乎是#1的一种变体,我必须捕获所有异常并将它们发送到边输出 除了用异常处理来包装每一
除了用异常处理来包装每一条逻辑之外,真的没有其他方法可以做到这一点吗?是否没有通用的方法来捕获异常而不让处理继续?我认为我们的想法不是捕获所有类型的异常并将它们发送到其他地方,而是使用经过良好测试且功能正常的代码,并仅对无效输入使用死信 因此,典型的管道是
source => validate => ... => sink
\=> dead letter queue
一旦记录通过validate运算符,您就希望所有错误都冒出来,因为这些运算符中的任何错误都可能导致损坏的聚合和数据,这些数据一旦写入就无法轻松恢复
验证步骤可以使用您概述的两种方法中的任何一种。通常,边输出具有更好的语义,但最终可能会得到更多的代码
现在,您可能有一个具有高SLA的服务,并且实际上希望它生成输出,即使它只是为了生成数据而损坏。或者您有一个简单的转换管道,在这里您将错过一些事件,但保留大部分(下游可以处理不完整的数据)。那么您就对了,您需要用try-catch包装所有操作符的代码。然而,您通常仍然只对脆弱的操作符执行此操作,而不是对所有操作符执行此操作。琐碎的操作符应该经过测试,然后信任它工作。此外,您通常只捕获特定类型的异常,以将范围限制为可能发生的预期异常类型 您可能想知道为什么Flink没有将其作为默认模式合并。据我所知,有两个原因:
您可以做的是将大多数复杂的逻辑内容提取到单个
ProcessFunction
中,并使用您概述的边输出。因为它是一个中心部分,所以只需要编写一次side输出函数。如果执行多次,您可以提取一个helper函数,在该函数中,您将实际代码作为runnableithexception
lambda传递,该函数隐藏了所有的边输出逻辑。确保使用大量的finally
块来确保状态正常
我还将添加许多IT案例,并使用突变测试来更快地强化您的管道。如果您保持测试数据的内联,那么变体也可能准确地模拟您意外的数据问题,这样您的验证操作符就更完整了。我认为想法不是捕获所有类型的异常并将它们发送到其他地方,而是要有经过良好测试和运行的代码,并且只对无效输入使用死信 因此,典型的管道是
source => validate => ... => sink
\=> dead letter queue
一旦记录通过validate运算符,您就希望所有错误都冒出来,因为这些运算符中的任何错误都可能导致损坏的聚合和数据,这些数据一旦写入就无法轻松恢复
验证步骤可以使用您概述的两种方法中的任何一种。通常,边输出具有更好的语义,但最终可能会得到更多的代码
现在,您可能有一个具有高SLA的服务,并且实际上希望它生成输出,即使它只是为了生成数据而损坏。或者您有一个简单的转换管道,在这里您将错过一些事件,但保留大部分(下游可以处理不完整的数据)。那么您就对了,您需要用try-catch包装所有操作符的代码。然而,您通常仍然只对脆弱的操作符执行此操作,而不是对所有操作符执行此操作。琐碎的操作符应该经过测试,然后信任它工作。此外,您通常只捕获特定类型的异常,以将范围限制为可能发生的预期异常类型 您可能想知道为什么Flink没有将其作为默认模式合并。据我所知,有两个原因: