[Flink/Java] Flink Job 运行问题 FAQ
概述: Flink Job 运行问题 FAQ
Flink Job 运行失败的原因汇总
历次处理Flink任务的错误情况,一般原因有:
- 与第三方资源(数据库、OSS等)的网络不互通(搭建环境的早期阶段)、网络不稳定
- 配置错误 (url / 用户名 / 密码; 大小写、空格等特殊字符)
- 集群/队列的CU资源不足
- Flink Job 的 JVM内存不足
- Flink CDC Job中mysql binlog过期或失效
- checkpoint保存失败
- Flink 程序的业务逻辑、数据量太大:导致性能缓慢,导致 checkpoint 超时
- Flink程序中的依赖组件(OSS、MYSQL、Redis、OLAP数据库等)不稳定/运行崩溃,导致 checkpoint 超时
- ...
Flink 并行度/算子链
- 推荐文献
Q: Flink 作业 Task 并行度设置的技巧? FlinkJobUtils#setParallelism / ...
基础常识: Operator Task = subtasks x N 个
- 当要处理的数据量非常大时,我们可以把一个算子操作,“复制”多份到多个节点,数据来了之后就可以到其中任意一个执行。这样一来,一个算子任务就被拆分成了多个并行的“子任务”(
subtasks),再将它们分发到不同节点,就真正实现了并行计算。
在Flink执行过程中,每一个算子(
operator)可以包含一个或多个子任务(operator subtask),这些子任务在不同的线程、不同的物理机或不同的容器中完全独立地执行。

- 一个特定算子的子任务(
subtask)的【个数】被称之为其【并行度】(parallelism)。这样,包含并行子任务的数据流,就是并行数据流,它需要多个分区(
stream partition)来分配并行任务。
一般情况下,一个流程序的并行度,可以认为就是其所有算子中最大的并行度。
一个程序中,不同的算子可能具有不同的并行度。
例如:如上图所示,当前数据流中有source、map、window、sink四个算子,其中sink算子的并行度为1,其他算子的并行度都为2。所以这段流处理程序的并行度就是2。
-
一个 Flink Job 由多个任务(Task) 组成(算子/Operator、数据源/Source和输出器/Sink)
-
一个 Task 包括多个并行执行的实例,且每一个实例都处理 Task 输入数据的一个子集。
-
一个 Task 的并行实例数被称为该 task 的 并行度 (parallelism)。
-
优先级
- Task(算子) 级粒度的并行度 > Job级粒度的并行度
- 代码设置的并行度(C_P) > 大数据(云)平台设置的并行度(BDP_P)
默认并行度
parallelism.default
在任何地方未指定并行度时使用的默认并行度(默认值:1)。
taskmanager.numberOfTaskSlots
任务管理器提供的插槽数(默认值:1)。 每个插槽可以接受一个任务或管道。
在 TaskManager 中拥有多个插槽有助于在并行任务或管道之间分摊某些恒定开销(JVM、应用程序库或网络连接)。
有关详细信息,请参阅任务槽和资源概念部分。
运行更多较小的 TaskManager,每个 TaskManager 有一个插槽是一个很好的起点,可以实现任务之间的最佳隔离。
将相同的资源专用于具有更多插槽的较少较大的 TaskManager 有助于提高资源利用率,但代价是任务之间的隔离较弱(更多任务共享同一个 JVM)。
- 参考文献

最佳实践 : FlinkJobUtils#setParallelism
以某个Task获取/设置并行度的过程为例
- 目的:既需要能灵活地设置 某个 Task 级的并行度,又能默认设置 Job(全局)级的并行度
支持为每个source/sink/operator设置task级并行度
import cn.johnnyzen.bdp.xxxx.yyyy.zzzz.conf.Constants;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.GlobalConfiguration;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSink;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FlinkJobUtils {
private final static Logger logger = LoggerFactory.getLogger(FlinkJobUtils.class);
/**
* 全局配置
* @description
* 1. 对应 ${FLINK_CONF_DIR}/flink-conf.yaml 配置文件
* 2. 如 : parallelism.default / taskmanager.numberOfTaskSlots / jobmanager.heap.size / taskmanager.heap.size 等配置项
*/
private static Configuration globalConfiguration;
static {
//globalConfiguration | 读取 {org.apache.flink.configuration.ConfigConstants.ENV_FLINK_CONF_DIR:FLINK_CONF_DIR}/{org.apache.flink.configuration.GlobalConfiguration.FLINK_CONF_FILENAME:"flink-conf.yaml"} 下的配置 | DLI等大数据平台的界面/全局配置也在此处
globalConfiguration = GlobalConfiguration.loadConfiguration();
logger.info("Success to loading flink global configuration!");
}
public static Integer getDataStreamParallelism(DataStream dataStream){
return dataStream.getParallelism();
}
/**
* 设置 数据流[流式源/流式算子(任务)]并行度 / setting data stream's parallelism
* @note
* 1. The parallelism of non parallel operator must be 1.(非并行运算符的并行度必须为1, 如: DataStreamSource 等)
* @param jobParameterTool | NotEmpty |
* @param dataStreamOrEnv | NotEmpty | DataStream(Source/Operator/Sink) or StreamExecutionEnvironment
* @param dataStreamParallelConfiguration | NotEmpty |
* eg : {@link cn.johnnyzen.bdp.xxxx.yyyy.zzzz.conf.Constants#FLINK_SOURCE_KAFKA_PARALLEL_PARAM } / ...
* @param defaultParallelism | Nullable | 默认并行度 (允许为空,非旁支流不建议设置默认值,即不建议非旁支流在此参数处有值)
* @reference-doc
* [1] [Deployment > Configurations > Parallelism - Apache Flink Docs](https://nightlies.apache.org/flink/flink-docs-release-1.12/deployment/config.html)
* # 1) parallelism.default
* 在任何地方未指定并行度时使用的默认并行度(默认值:1)。
* # 2) taskmanager.numberOfTaskSlots
* 任务管理器提供的插槽数(默认值:1)。 每个插槽可以接受一个任务或管道。
* 在 TaskManager 中拥有多个插槽有助于在并行任务或管道之间分摊某些恒定开销(JVM、应用程序库或网络连接)。
* 有关详细信息,请参阅任务槽和资源概念部分。
* 运行更多较小的 TaskManager,每个 TaskManager 有一个插槽是一个很好的起点,可以实现任务之间的最佳隔离。
* 将相同的资源专用于具有更多插槽的较少较大的 TaskManager 有助于提高资源利用率,但代价是任务之间的隔离较弱(更多任务共享同一个 JVM)。
*/
public static void setParallelism(ParameterTool jobParameterTool, Object dataStreamOrEnv, String dataStreamParallelConfiguration, Integer defaultParallelism){
String parallelism = null;//"1" / ...
//step1 获取 Task级粒度的并行度配置。若获取失败,则跳过 by 配置文件
parallelism = jobParameterTool.get(dataStreamParallelConfiguration, null);
logger.info("{} : {}", dataStreamParallelConfiguration, parallelism);
//step2 获取 Job 全局级粒度的默认并行度配置。若获取失败,则跳过 by 配置文件
if(ObjectUtils.isEmpty(parallelism)){
//step2.1 获取 NACOS 配置中心 或 本地的作业配置文件 中的 全局默认并行度
//注1 : jobParameterTool : 其配置来源于 NACOS 配置中心 或 本地的作业配置文件, 未合并其他出的配置,如 flink-conf.yaml
//注2 : 当然可自行优化该对象的配置数据获取逻辑
parallelism = jobParameterTool.get(Constants.DEFAULT_PARALLEL_PARAM, null);
logger.info("{} : {} | from `{}` by `jobParameterTool`", dataStreamParallelConfiguration, parallelism, Constants.DEFAULT_PARALLEL_PARAM);
//step2.2 获取 flink-conf.yaml 的作业配置文件 中的 全局默认并行度
if(ObjectUtils.isEmpty(parallelism)){
//注1 : globalConfiguration (来源于 : flink-conf.yaml )
//注2 : 如果是DLI等大数据平台上(基于YARN/K8S部署运行)时,基本上到了这一步,就不太可能没有值了,因为原则上不可能不提交 flink-conf.yaml (99.999%)
//注3 : 如果是在本地电脑部署运行时,此处取决于前面步骤是否有配置;否则, 此处仍为 null (但不影响运行)
parallelism = globalConfiguration.getString(Constants.DEFAULT_PARALLEL_PARAM, ObjectUtils.isEmpty(defaultParallelism)?null : String.valueOf(defaultParallelism) );
logger.info("{} : {} | from `{}` by `globalConfiguration`", dataStreamParallelConfiguration, parallelism, Constants.DEFAULT_PARALLEL_PARAM);
}
}
//step3 若获取配置成功,则设置,反之跳过
if(!ObjectUtils.isEmpty(parallelism)){//parallel is not empty
Integer parallelismInt = Integer.valueOf(parallelism);
String type = null;
if(dataStreamOrEnv instanceof SingleOutputStreamOperator){
SingleOutputStreamOperator dataStreamOperator = (SingleOutputStreamOperator) dataStreamOrEnv;
dataStreamOperator.setParallelism(parallelismInt);
type = SingleOutputStreamOperator.class.getCanonicalName();
} else if (dataStreamOrEnv instanceof DataStreamSource) {
DataStreamSource dataStreamSource = (DataStreamSource) dataStreamOrEnv;
dataStreamSource.setParallelism(parallelismInt);
type = DataStreamSource.class.getCanonicalName();
} else if(dataStreamOrEnv instanceof DataStreamSink){
DataStreamSink dataStreamSink = (DataStreamSink) dataStreamOrEnv;
dataStreamSink.setParallelism(parallelismInt);
type = DataStreamSink.class.getCanonicalName();
} else if (dataStreamOrEnv instanceof StreamExecutionEnvironment) {
StreamExecutionEnvironment streamExecutionEnvironment = (StreamExecutionEnvironment) dataStreamOrEnv;
streamExecutionEnvironment.setParallelism(parallelismInt);
type = StreamExecutionEnvironment.class.getCanonicalName();
} else if ( dataStreamOrEnv instanceof DataSource) {//批处理-数据源
DataSource dataSource = (DataSource) dataStreamOrEnv;
dataSource.setParallelism(parallelismInt);
type = DataSource.class.getCanonicalName();
} else if( dataStreamOrEnv instanceof MapOperator) {//批处理-Map算子
MapOperator mapOperator = (MapOperator) dataStreamOrEnv;
mapOperator.setParallelism(parallelismInt);
type = MapOperator.class.getCanonicalName();
} else {
throw new RuntimeException(String.format("Not support the class type when setting parallelism by parallelism! %s : %d", dataStreamParallelConfiguration, parallelism));
}
logger.info("Success to set parallelism({})! type: {}", parallelismInt, type);
} else {//parallel is empty
logger.warn("The `{}`'s parallelism is empty now , and will be set a default value = 1 by flink framework!", dataStreamParallelConfiguration);
}
}
}
Constants
public class Constants {
/**
* 作业(全局)默认并行度
* (Definition by Apache Flink Framework | support versions : [ flink 1.0, flink 1.18 or future version] )
* @description parallelism.default : 在任何地方未指定并行度时使用的默认并行度(默认值:1)
* @sample 作业启动时,日志中可见:
* "202X-XX-XX 17:06:02,029 INFO org.apache.flink.configuration.GlobalConfiguration [] - Loading configuration property: parallelism.default, 2"
* @reference-doc
* [1] [Deployment > Configurations - Apache Flink Docs](https://nightlies.apache.org/flink/flink-docs-release-1.12/deployment/config.html)
**/
public final static String DEFAULT_JOB_PARALLEL_PARAM = "parallelism.default";
}
Q: Kafka分区数(Partitions) 与 Flink KafkaSource 的并行度(Paralism)的关系?
-
Kafka分区数:是指Kafka主题中的分区数量,一个主题可以有多个分区。每个分区都是独立的消息队列,可以并发地接收和处理消息。在Kafka中,分区数决定了消息的并行性,即一个主题的分区数越多,可以同时处理的消息量就越大。
-
Flink并行度:是指一个任务或算子可以并行执行的并发任务数。在Flink中,每个任务或算子都可以独立地处理数据流,而并行度就是同时处理的任务或算子的数量。并行度的设置可以影响Flink任务的并发性以及整体的吞吐量。
-
Kafka分区数与 Flink KafkaSource 并行度之间存在一定的关系。
-
Kafka分区数和Flink KafkaSource 并行度之间的关系是:
- 1)通常情况下,我们希望【Flink的并行度】与【Kafka的分区数】保持一致。
这样每个Flink 任务或KafkaSource算子可以处理一个Kafka分区的数据。
这样可以最大程度地发挥消息的并行性和Flink任务的并发性,提高整体的处理能力和吞吐量。
- 2)但也可以根据具体的业务需求来调整Flink的并行度。(但必须满足:
Kafka Partitions ≥ Flink Job Kafka Source Paralism)
- 如果
Flink KafkaSource的并行度<Kafka的分区数,则:Kafka 多个分区的数据将被一个 Flink 任务或算子处理。当数据量大的时候,可能会导致Flink任务数据处理能力的下降、kafka消费组显著的消息积压。- 如果
Flink KafkaSource的并行度>Kafka的分区数,则:会存在一些任务无法处理数据的情况,Flink KafkaSource任务因部分节点无法分配到数据而夯住、无法提交checkpoint,Flink作业必将运行故障(诚然,Flink KafkaSource 也不会自动进入空闲状态)。此时,您需要降低并行度或向水印策略添加空闲超时。
- 如果在这段时间内流的某个分区中没有记录流动,则该分区被视为“空闲”,并且不会阻止Flink下游运算符中水印(watermark)的进度。
因此,在设置Flink任务的并行度时,可以考虑将
Flink KafkaSource的并行度(Paralism)设置为与Kafka分区数(Partitions)为【相等】或【倍数关系】( N*Partitions = Partitions),以达到最佳的处理性能。例如:Flink作业中KafkaSource的下游Task来不及消费/处理上游 KafkaSource Task 的数据,项目实践中可能将 KafkaSource 调小。
例如:也可将Kafka的分区数增大,但增大后,Flink Job需要重新启动或者在作业中开启Kafka的分区自动发现特性。
- 扩展: flink sink 到 kafka 时,如果
Flink的并行度>kafka的分区数时,则:会轮询把数据插入到kafka分区中,数据不会丢失。 - 扩展: flink sink 到 kafka 时,如果
Flink的并行度<kafka的分区数时,则:也会轮询把数据插入到kafka分区中,数据不会丢失。
因为如果指定key的情况下,则:producer 会按照 hash 规则,把数据hash到相应分区中,
也就是说————flink sink时,并行度之于kafka影响不大,不会存在数据丢失或者分区没有写入的情况。
- 参考文献
Q: Flink 算子链及禁用方式?
- 在 Apache Flink 中,
disableOperatorChaining()是一个用于全局禁止算子链式合并的方法。
与
disableChaining()不同,disableChaining()只是作用于某个具体的算子,而disableOperatorChaining()则会全局禁止链式合并,确保所有算子都以【独立的任务】执行。
- 作用
env#disableOperatorChaining()的主要作用是完全禁用 Flink 的算子链式优化机制。
通常,Flink 默认会将多个连续的算子(operator)合并到一个算子链(operator chain)中,以减少任务的调度和通信的 开销,提高性能。
然而,disableOperatorChaining()会禁用这个默认行为,确保所有算子都单独执行,从而提升【调试能力】或用于【特殊的性能调优需求】。
- 全局禁用算子链:所有的算子都将以独立的任务运行,无法进行链式合并。
- 细粒度的任务调度:每个算子都将独立调度和执行,允许开发者对每个算子的性能进行更细致的控制和监控。
适用于调试:便于观察各个算子的独立行为,分析每个算子对整体执行的影响。
- 使用场景
调试与监控:在调试复杂的 Flink 应用时,为了更好地观察和分析每个算子的执行行为,可能需要禁用链式合并,从而能够独立监控每个算子的性能指标。
优化性能瓶颈:在某些场景下,如果多个算子被链式合并,某个算子可能会因为资源消耗或延迟影响到其他算子。通过禁用算子链,可以避免这种情况。
复杂计算:如果应用程序中包含复杂的算子链,可能会引发背压等问题,禁用算子链可以帮助解决这些性能问题,使得每个算子独立调度并执行。
任务隔离需求:有时为了优化资源的使用或减少任务之间的相互影响,可能需要将算子进行任务隔离,这时禁用链式合并可以实现。
- 代码示例
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.datastream.DataStream;
public class DisableOperatorChainingExample {
public static void main(String[] args) throws Exception {
// 创建执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 禁用全局的算子链式合并
env.disableOperatorChaining();
// 创建数据流
DataStream<String> stream = env.fromElements("one", "two", "three", "four");
// 每个算子将独立执行,不进行链式合并
stream.map(value -> {
System.out.println("Map 1: " + value);
return value.toUpperCase();
})
.filter(value -> value.startsWith("T"))
.map(value -> "Processed: " + value);
// 执行作业
env.execute("Disable Operator Chaining Example");
}
}
- 推荐文献
Flink CDC
Flink Checkpoint/Savepoint 机制
Q: Flink运行时报 java.lang.IllegalStateException: Buffer pool is destroyed.
问题描述
- Flink运行时报
java.lang.IllegalStateException: Buffer pool is destroyed.
且这个报错在日志中与"
Could not forward element to next operator"同时存在。
java.lang.RuntimeException: Buffer pool is destroyed.
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.pushToRecordWriter(RecordWriterOutput.java:110) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.collect(RecordWriterOutput.java:89) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.collect(RecordWriterOutput.java:45) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.AbstractStreamOperator$CountingOutput.collect(AbstractStreamOperator.java:718) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.AbstractStreamOperator$CountingOutput.collect(AbstractStreamOperator.java:696) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.StreamMap.processElement(StreamMap.java:41) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.tasks.OperatorChain$CopyingChainingOutput.pushToOperator(OperatorChain.java:579) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.tasks.OperatorChain$CopyingChainingOutput.collect(OperatorChain.java:554) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.tasks.OperatorChain$CopyingChainingOutput.collect(OperatorChain.java:534) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.AbstractStreamOperator$CountingOutput.collect(AbstractStreamOperator.java:718) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.AbstractStreamOperator$CountingOutput.collect(AbstractStreamOperator.java:696) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.StreamSourceContexts$NonTimestampContext.collect(StreamSourceContexts.java:104) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at com.ucarinc.framework.flink.connectors.flexq.FlexQSource.run(FlexQSource.java:204) ~[flink-connector-flexq-1.8.500-20191206.054312-28.jar:1.8.500-SNAPSHOT]
at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:93) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.api.operators.StreamSource.run(StreamSource.java:57) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.tasks.SourceStreamTask.run(SourceStreamTask.java:97) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.tasks.StreamTask.invoke(StreamTask.java:300) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:711) [flink-runtime_2.11-1.8.1.jar:1.8.1]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_31]
Caused by: java.lang.IllegalStateException: Buffer pool is destroyed.
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.internalRequestMemorySegment(LocalBufferPool.java:264) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.requestMemorySegment(LocalBufferPool.java:240) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.buffer.LocalBufferPool.requestBufferBuilderBlocking(LocalBufferPool.java:218) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.requestNewBufferBuilder(RecordWriter.java:264) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.getBufferBuilder(RecordWriter.java:257) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.copyFromSerializerToTargetChannel(RecordWriter.java:177) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.emit(RecordWriter.java:162) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.runtime.io.network.api.writer.RecordWriter.emit(RecordWriter.java:128) ~[flink-runtime_2.11-1.8.1.jar:1.8.1]
at org.apache.flink.streaming.runtime.io.RecordWriterOutput.pushToRecordWriter(RecordWriterOutput.java:107) ~[flink-streaming-java_2.11-1.8.1.jar:1.8.1]
... 18 more
问题分析
- 一般为为任务
network buffer不足。可以调整下任务的network buffer的大小。
解决方法
-
方法1:清理/腾出运行的计算机内存资源,尔后重新提交运行 (亲测有效)
-
方法2:高级参数中添加:
taskmanager.memory.network.fraction0.2 (默认值为0.1,可根据实际情况适当调整)
参考文献
- FAQ-Buffer pool is destroyed. - 网易-有数学堂/EasyData数据开发治理平台FAQ 【推荐】
- Flink问题排查-Buffer pool is destroyed. - CSDN
Q:Flink 中 DataStream 的 sinkTo 和 addSink 的区别?
- 在 Apache Flink 中,
sinkTo和addSink是两种用于将数据写入外部存储或系统的方式。它们的主要区别在于实现方式和适用场景。
addSink
- addSink
- addSink 是 Flink 中较早的输出算子,适用于自定义实现的场景。它需要用户实现 SinkFunction 接口,并重写 invoke() 方法来定义数据写入逻辑。
- 示例代码
DataStream<String> dataStream = ...; // 数据流
dataStream.addSink(
new SinkFunction<String>() {
@Override
public void invoke(String value, Context context) {
// 自定义写入逻辑
System.out.println("写入数据: " + value);
}
}
);
- 特点:
灵活性高,适合自定义需求。
需要用户手动处理容错和事务一致性。
在 Flink 1.12 之前是主要的 Sink 实现方式。
sinkTo
-
sinkTo 是 Flink 1.12 引入的新方法,基于新的 Sink API 架构,提供了更高的抽象和易用性。它支持多种内置的 Sink,如 Kafka、文件系统、JDBC 等。
-
示例代码:
DataStream<String> dataStream = ...; // 数据流
FileSink<String> fileSink = FileSink
.forRowFormat(new Path("output/path"), new SimpleStringEncoder<>("UTF-8"))
.build();
dataStream.sinkTo(fileSink);
- 特点:
- 提供了更简洁的接口,减少了用户的实现负担。
- 支持高级功能,如分桶策略、滚动策略等。
- 更适合与 Flink 的 Checkpoint 机制结合,支持精确一次语义。
Q: Flink 作业中的 Idle Status(空闲状态)
在Flink中,Idle状态是指作业处于【空闲状态】,即没有输入数据可用于处理的状态。当Flink作业没有输入数据可供处理时,它将进入Idle状态。
理解Flink中的Idle状态可以从以下几个方面来考虑:
无输入数据:Idle状态表示当前作业没有输入数据可用于处理。这可能是因为输入源暂时没有可用的数据,或者数据流已经被处理完毕。
空闲等待:在Idle状态下,Flink作业会等待输入数据的到来。它会周期性地检查输入源是否有新的数据产生,一旦有新的数据产生,作业将从Idle状态转换为Active状态开始处理数据。
优化机会:Idle状态也给了Flink一些优化的机会。在空闲状态下,Flink可以进行一些优化操作,例如重新分配资源、调整并行度、合并任务等,以提高作业的性能和效率。
需要注意的是,Idle状态并不代表作业已经完成或者失败,它只是作业在等待输入数据的状态。一旦有新的输入数据到来,作业将离开Idle状态并开始处理数据。
Q: 提交Flink作业时,日志报java.net.BindException: Could not start actor system on any port in port range 6123
问题描述
- 提交Flink作业时,日志报 java.net.BindException: Could not start actor system on any port in port range 6123
问题分析
- 用户提交flink作业时,提示端口被占用。
解决思路
- 确保之前的老作业被关闭(如:kill掉作业),再二次提交。
参考文献
X 参考文献
参考文献
推荐文献
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号