Apache flink 为什么Flink不重试操作失败?
我计划将一个Spark应用程序迁移到ApacheFlink。我试图了解它的容错特性 我执行了下面的代码,我没有看到Flink实际上尝试重试任何任务(或子任务)。这可能会导致我丢失数据。我该怎么做才能确保每一次失败都被Flink覆盖Apache flink 为什么Flink不重试操作失败?,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我计划将一个Spark应用程序迁移到ApacheFlink。我试图了解它的容错特性 我执行了下面的代码,我没有看到Flink实际上尝试重试任何任务(或子任务)。这可能会导致我丢失数据。我该怎么做才能确保每一次失败都被Flink覆盖 val env = StreamExecutionEnvironment.getExecutionEnvironment env.setStateBackend(new FsStateBackend("file:///my-path", false))
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStateBackend(new FsStateBackend("file:///my-path", false))
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
3, // number of restart attempts
Time.of(0, TimeUnit.SECONDS) // delay
))
env.enableCheckpointing(10L)
val text = env.socketTextStream(hostName, port)
text
.map { input =>
List(input)
}.setParallelism(1)
.flatMap { input =>
println(s"running for $input")
List.fill(5)(input.head) ::: {
println("throw exception here")
throw new RuntimeException("some exception")
List("c")
}
}
我希望在屏幕上多次看到
抛出异常。但是,当我使用fixedDelayRestart
时,它似乎忽略了此消息,并继续为其他人发送消息。这取决于您如何启动应用程序
我假设您正在用IDE运行这个。在这种情况下,StreamExecutionEnvironment.getExecutionEnvironment
返回一个LocalStreamExecutionEnvironment
,它在一个进程中运行程序和所有Flink,即主进程(在Flink JobManager中)和工作进程(TaskManager)作为同一JVM进程中的线程启动。异常终止这个单一进程。因此,不存在可以重新启动程序的Flink进程
如果您希望以容错方式运行程序,则需要将其提交到Flink环境,例如在本地计算机上运行的环境。下载Flink发行版,提取归档文件,然后运行/bin/start cluster.sh
。这将启动两个进程,一个主进程和一个工作进程。然后,您可以通过使用StreamExecutionEnvironment.createRemoteEnvironment
创建远程执行环境,并将主机名和端口作为参数传递给群集,从而将程序提交到群集(有关详细信息,请查看文档)
请注意,异常仍将终止工作进程。因此,为了能够重新启动程序,您需要手动启动辅助进程。在生产环境中,这通常由Kubernetes、纱线或Mesos负责
顺便说一下,我们最近在Flink文档中添加了一个操作平台。这是一个基于Docker的沙箱环境,可以使用Flink的容错功能。我建议你去看看:
还有一些提示:
- 10毫秒的检查间隔非常短
- 文本套接字源不提供至少一次(或恰好一次)保证。记录最多处理一次
感谢Fabian的回答,这对我们很有帮助。你能解释一下你的提示吗?数据源最多一次是否意味着数据丢失?检查点不保留记录吗?是的,文本套接字源在发生故障时很可能会丢失记录。文本套接字源代码不是用于生产,只是用于简单的演示。它不包括检查点中的记录,因此无法重新处理上次成功检查点之后读取的所有记录。我建议通过卡夫卡或脉冲星这样的持久消息队列接收流。谢谢你,这清除了很多东西。我不想脱离问题的背景,但检查点对我来说不是很清楚。我有一个生产服务,每天使用Spark处理PB级数据。我们想把它转移到Flink,但容错机制还不是很清楚。我们的流程是;Kinesis(包含s3对象路径)->下载和处理内容->缓冲X分钟->写入s3。它必须是事务性的,检查点是保存数据(对我们来说,它非常大),还是仅仅保存元数据,比如来自动觉的偏移量?任何操作中的任何故障,我们都希望再次重新处理该文件。检查点包含两个信息:1)源的位置信息(运动偏移量),2)操作符的中间状态(缓冲的数据)。Flink的检查点算法保证检查点是一致的,即所有数据都是在“概念上”相同的时间点复制的。如果出现故障,所有内容(读取位置和缓冲数据)都将重置为最后一个完成的检查点,并且应用程序将从该一致点继续。在您的用例中,恢复的Flink程序将再次读取在最后一个检查点之后处理的所有文件。这很好,但是如果我们将数据窗口化几分钟,内存中已经有大量数据(TB),将这些数据保存在检查点中的效率如何?