文章目录

  • 执行配置
  • 程序打包和分布式执行
  • 程序打包
  • 小结
  • 并行执行
  • 设置并行度
  • Operator 级别
  • 执行环境级别
  • 客户端级别
  • 系统级别
  • 设置最大并行度


执行配置

StreamExecutionEnvironment包含ExecutionConfig,它允许为运行时设置特定于作业的配置值。要更改影响所有作业的默认值,请参见配置。

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
ExecutionConfig executionConfig = env.getConfig();

以下是可用的配置选项:

  • setClosureCleanerLevel()。closure cleaner级别设置为ClosureCleanerLevel。默认情况下递归。闭包清理器在Flink程序中删除对周围匿名函数类的不必要引用。禁用闭包清理器后,可能会发生匿名用户函数引用周围的类,这通常是不可序列化的。这将导致序列化器产生异常。设置如下:NONE:完全禁用闭包清除器,TOP_LEVEL:只清除顶级类而不递归到字段,RECURSIVE:递归清除所有字段
  • getParallelism() / setParallelism(int parallelism)设置作业的默认并行度。
  • getMaxParallelism() / setMaxParallelism(int parallelism)设置作业的默认最大并行度。此设置确定最大并行度并指定动态缩放的上限。
  • getNumberOfExecutionRetries() / setNumberOfExecutionRetries(int numberOfExecutionRetries)设置失败的任务重新执行的次数。值为0将有效地禁用容错功能。-1表示应该使用系统默认值(与配置中定义的一样)。这是不赞成的,使用重启策略代替。
  • getExecutionRetryDelay() / setExecutionRetryDelay(long executionRetryDelay)设置任务失败后重新执行任务的延迟时间,单位为毫秒。在taskmanager上成功停止所有任务后,延迟开始,一旦延迟过去,任务将重新启动。这个参数对于延迟重新执行非常有用,以便在尝试重新执行并立即由于相同的问题再次失败之前,让某些超时相关的故障完全显露出来(比如没有完全超时的断开连接)。此参数仅在重试次数为一次或多次时有效。这是不赞成的,使用重启策略代替。
  • getExecutionMode () / setExecutionMode()。默认的执行模式是流水线。设置执行模式以执行程序。执行模式定义数据交换是以批处理方式执行还是以流水线方式执行。
  • enableForceKryo()/ disableForceKryo enableForceKryo()。Kryo默认不是强制的。强制GenericTypeInformation对POJO使用Kryo序列化器,即使我们可以将它们作为POJO进行分析。在某些情况下,这可能更可取。例如,当Flink的内部序列化器不能正确处理POJO时。
  • enableForceAvro () / disableForceAvro()。默认情况下,Avro不是强制的。强制Flink AvroTypeInfo使用Avro序列化器而不是Kryo来序列化Avro pojo。
  • enableObjectReuse() / disableObjectReuse()默认情况下,Flink中不重用对象。启用对象重用模式将指示运行时重用用户对象以获得更好的性能。请记住,当操作的用户代码函数不知道这种行为时,这可能会导致bug。
  • getGlobalJobParameters() / setGlobalJobParameters()该方法允许用户设置自定义对象作为作业的全局配置。由于ExecutionConfig在所有用户定义的函数中都可以访问,因此这是一种使配置在作业中全局可用的简单方法。
  • addDefaultKryoSerializer(Class<?> type, Serializer<?> serializer)为给定类型注册一个Kryo序列化器实例。
  • addDefaultKryoSerializer(Class<?> type, Class<? extends Serializer<?>> serializerClass)为给定类型注册一个Kryo序列化器类。
  • registerTypeWithKryoSerializer(Class<?> type, Serializer<?> serializer) 向Kryo注册给定的类型,并为其指定一个序列化器。通过向Kryo注册类型,类型的序列化将会更加高效。
  • registerKryoType(Class<?> type) 如果该类型最终使用Kryo序列化,那么将在Kryo注册它,以确保只写入标记(整数id)。如果一个类型没有在Kryo上注册,它的整个类名将被每个实例序列化,导致更高的I/O成本。
  • registerPojoType(Class<?> type)向序列化堆栈注册给定的类型。如果该类型最终被序列化为POJO,那么该类型将被注册到POJO序列化器中。如果该类型最终使用Kryo序列化,那么将在Kryo注册它,以确保只写入标记。如果一个类型没有在Kryo上注册,它的整个类名将被每个实例序列化,导致更高的I/O成本。

注意,用registerKryoType()注册的类型对Flink的POJO序列化器实例不可用。

  • disableautotyperregistration()默认启用自动类型注册。自动类型注册是用Kryo和POJO序列化器注册用户代码使用的所有类型(包括子类型)。
  • setTaskCancellationInterval(long interval)设置连续尝试取消一个正在运行的任务的等待时间间隔(毫秒)。当一个任务被取消时,如果任务线程在一定时间内没有终止,则会创建一个新线程,并周期性地调用该任务线程上的interrupt()。该参数指的是中断()的连续调用之间的时间,默认设置为30000毫秒,即30秒。

在Rich*函数中可以通过getRuntimeContext()方法访问的RuntimeContext也允许访问所有用户定义函数中的ExecutionConfig。

程序打包和分布式执行

如前所述,可以通过使用远程环境在集群上执行Flink程序。或者,程序可以打包到JAR file (Java Archives)中执行。打包程序是通过命令行接口执行它们的先决条件。

程序打包

为了支持通过命令行或web界面从打包的JAR文件执行,程序必须使用StreamExecutionEnvironment.getExecutionEnvironment()获得的环境。当JAR被提交到命令行或web界面时,这个环境将充当集群的环境。如果Flink程序的调用方式与通过这些接口调用的方式不同,则该环境将像本地环境一样工作。

要打包该程序,只需将所有涉及的类导出为JAR文件。JAR文件的清单必须指向包含程序入口点的类(具有公共main方法的类)。最简单的方法是将主类条目放入清单中(例如main-class: org.apache.flinkexample.MyProgram)。main-class属性与Java虚拟机在通过Java -jar pathToTheJarFile命令执行JAR文件时用于查找主方法的属性相同。大多数ide在导出JAR文件时都提供了自动包含该属性的功能。

小结

调用打包程序的整个过程包括两个步骤:

  • 在JAR的清单中搜索主类或程序类属性。如果找到了两个属性,则程序类属性优先于main类属性。对于JAR清单中不包含任何属性的情况,命令行和web界面都支持一个参数来手动传递入口点类名。
  • 系统调用类的main方法。

并行执行

本节介绍如何在Flink中配置程序的并行执行。Flink程序由多个任务(转换/运算符、数据源和接收器)组成。一个任务被分割成几个并行实例来执行,每个并行实例处理任务输入数据的一个子集。任务的并行实例数称为并行度。

如果要使用保存点,还应该考虑设置最大并行度(或最大并行度)。从保存点恢复时,可以更改特定运算符或整个程序的并行度,此设置指定并行度的上限。这是必需的,因为Flink内部分区状态为键组,我们不能有+Inf数量的键组,因为这将不利于性能。

设置并行度

任务的并行度可以在Flink中指定不同的级别:

Operator 级别

单个operator、数据源或数据接收器的并行度可以通过调用其setParallelism()方法来定义。例如,像这样:

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

DataStream<String> text = [...];
DataStream<Tuple2<String, Integer>> wordCounts = text
    .flatMap(new LineSplitter())
    .keyBy(value -> value.f0)
    .window(TumblingEventTimeWindows.of(Time.seconds(5)))
    .sum(1).setParallelism(5);

wordCounts.print();

env.execute("Word Count Example");

执行环境级别

如前所述,Flink程序是在执行环境的上下文中执行的。执行环境为它执行的所有操作符、数据源和数据接收器定义默认并行度。可以通过显式配置操作符的并行性来重写执行环境的并行性。

执行环境的默认并行度可以通过调用setParallelism()方法来指定。若要执行所有的运算符、数据源和数据汇的并行度为3,则设置执行环境的默认并行度如下:

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(3);

DataStream<String> text = [...];
DataStream<Tuple2<String, Integer>> wordCounts = [...];
wordCounts.print();

env.execute("Word Count Example");

客户端级别

并行度可以在向Flink提交作业时在Client上设置。客户端既可以是Java程序,也可以是Scala程序。这种客户机的一个例子是Flink的命令行接口(CLI)。

对于CLI客户端,parallelism参数可以使用-p指定。例如:

./bin/flink run -p 10 ../examples/*WordCount-java*.jar

在Java/Scala程序中,并行度设置如下:

try {
    PackagedProgram program = new PackagedProgram(file, args);
    InetSocketAddress jobManagerAddress = RemoteExecutor.getInetFromHostport("localhost:6123");
    Configuration config = new Configuration();

    Client client = new Client(jobManagerAddress, config, program.getUserCodeClassLoader());

    // set the parallelism to 10 here
    client.run(program, 10, true);

} catch (ProgramInvocationException e) {
    e.printStackTrace();
}

系统级别

可以通过在./conf/flink-conf.yaml中设置parallelism.default属性来定义所有执行环境的系统级默认并行度。详细信息请参见配置文档。

设置最大并行度

可以在也可以设置并行度的地方设置最大并行度(客户端级别和系统级别除外)。不是调用setParallelism(),而是调用setMaxParallelism()来设置最大并行度。

最大并行度的默认设置大致为operatorParallelism + (operatorParallelism / 2),下界为128,上界为32768。

将最大并行度设置为一个非常大的值可能会损害性能,因为一些状态后端必须保持内部数据结构,这些数据结构必须随键组(这是可伸缩状态的内部实现机制)的数量伸缩。