Flink为什么不重试操作员失败?

时间:2019-09-23 16:24:22

标签: apache-flink flink-streaming

我计划将我们的Spark应用程序之一迁移到Apache Flink。我正在尝试了解其容错功能。

我执行了以下代码,但没有看到Flink实际上尝试重试任何任务(或子任务)。这可能会导致我的数据丢失。我该怎么做才能确保Flink涵盖所有故障?

    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")
        }
      }

我希望在屏幕上几次看到throw exception here消息。但是,当我使用fixedDelayRestart时,看起来它只是忽略了此消息,而对其他消息继续。

1 个答案:

答案 0 :(得分:1)

这取决于您如何启动应用程序。

我假设您正在IDE中运行此程序。在那种情况下,StreamExecutionEnvironment.getExecutionEnvironment返回一个运行程序的LocalStreamExecutionEnvironment,并且所有Flink在单个进程中运行,即,主线程(在Flink JobManager中)和工作线程(TaskManager)在同一JVM进程中作为线程启动。 。异常终止此单个过程。因此,不存在可以重新启动程序的Flink进程。

如果要运行具有容错功能的程序,则需要将其提交到Flink环境,例如在本地计算机上运行的环境。下载Flink发行版,提取存档文件,然后运行./bin/start-cluster.sh。这将启动两个进程,即主进程和工作进程。然后,您可以通过使用StreamExecutionEnvironment.createRemoteEnvironment创建一个远程执行环境并传递主机名和端口作为参数来将程序提交给集群(请查看文档以了解详细信息)。

请注意,该异常仍将终止工作进程。因此,为了能够重新启动程序,您需要手动启动工作进程。在生产环境中,通常由Kubernetes,Yarn或Mesos来解决。

顺便说一下,我们最近在Flink文档中增加了一个操作场。这是一个基于Docker的沙盒环境,可以使用Flink的容错功能。我建议您检查一下:Flink Operations Playground

更多提示:

  • 10ms的检查点间隔非常短。
  • 文本套接字源不提供至少一次(或完全一次)保证。记录最多处理一次。
相关问题