Pulsar 与 Apache Flink 的集成 是构建现代实时数据架构的核心组合。Pulsar 作为高性能、持久化、多租户的 消息与事件流平台,而 Flink 作为强大的 流批一体计算引擎,二者结合可实现:
- ✅ 精确一次(Exactly-Once)语义
- ✅ 低延迟流处理
- ✅ 事件时间窗口计算
- ✅ 状态管理与容错
- ✅ 流批统一处理
这一切通过官方维护的 pulsar-flink-connector 实现,支持 Flink 1.14+ 版本。
📘 Pulsar 与流处理引擎集成:Apache Flink 详解
一、为什么选择 Pulsar + Flink?
| 需求 | Pulsar 提供 | Flink 提供 |
|---|---|---|
| ✅ 高吞吐消息传递 | 分层架构、BookKeeper 持久化 | - |
| ✅ 多租户与资源隔离 | Tenant/Namespace 隔离 | - |
| ✅ 消息回放与重处理 | 保留策略、游标重置 | - |
| ✅ 精确一次处理 | Producer 去重 + 事务(可选) | Checkpoint + 两阶段提交 |
| ✅ 窗口计算 | - | 滚动、滑动、会话窗口 |
| ✅ 状态管理 | - | RocksDB / Memory State Backend |
| ✅ 事件时间处理 | 事件时间戳(Event Time) | Watermark 机制 |
| ✅ 容错恢复 | BookKeeper 高可用 | Checkpoint / Savepoint |
✅ Pulsar 是“管道”,Flink 是“处理器” —— 两者协同,构建完整的实时数据流水线。
二、pulsar-flink-connector 核心特性
官方连接器:pulsar-flink-connector
GitHub:apache/pulsar-flink
1. 支持的 Flink 版本
| Flink 版本 | Connector Artifact |
|---|---|
| Flink 1.14+ | pulsar-flink-connector_2.12 或 _2.11 |
| Flink 1.17+ | 推荐使用 pulsar-flink-connector(统一模块) |
2. 核心功能
| 功能 | 说明 |
|---|---|
| ✅ Source(输入) | 从 Pulsar Topic 读取消息 |
| ✅ Sink(输出) | 将处理结果写入 Pulsar Topic |
| ✅ Exactly-Once 语义 | 基于 Flink Checkpoint + Pulsar Ack |
| ✅ 支持 Event Time | 自动提取事件时间戳 |
| ✅ 支持 Schema | JSON、Avro、Protobuf 自动反序列化 |
| ✅ 支持 Key_Shared 订阅 | 保证 Key 级顺序 |
| ✅ 支持事务写入(Flink 1.15+) | 实现端到端 Exactly-Once |
三、集成配置与依赖
1. Maven 依赖(Flink 1.17 + Pulsar 3.0+)
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>1.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java</artifactId>
<version>1.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-flink-connector</artifactId>
<version>3.0.0</version>
</dependency>
⚠️ 注意版本兼容性!建议使用 Pulsar 2.10+ 和 Flink 1.14+。
2. 打包方式
- 使用
maven-shade-plugin打成 Fat JAR。 - 或将
pulsar-flink-connector.jar放入 Flink 的lib/目录。
四、Flink 作为 Pulsar Source(消费消息)
1. 基本配置
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 启用 Checkpoint(Exactly-Once 的基础)
env.enableCheckpointing(10_000, CheckpointingMode.EXACTLY_ONCE);
// 创建 Pulsar Source
PulsarSource<String> source = PulsarSource.builder()
.serviceUrl("pulsar://localhost:6650")
.adminUrl("http://localhost:8080")
.subscriptionName("flink-sub")
.topic("persistent://public/default/input-topic")
.deserializationSchema(PulsarDeserializationSchema.flinkSchema(Schema.STRING))
.subscriptionType(SubscriptionType.Shared)
.build();
// 添加 Source
DataStream<String> stream = env.fromSource(source, WatermarkStrategy.noWatermarks(), "Pulsar Source");
2. 支持 Event Time
// 提取事件时间
WatermarkStrategy<String> strategy = WatermarkStrategy.<String>forBoundedOutOfOrderness(Duration.ofSeconds(5))
.withTimestampAssigner((event, timestamp) -> {
// 假设消息中包含事件时间
return extractEventTime(event);
});
DataStream<String> stream = env.fromSource(source, strategy, "Pulsar Source");
3. 支持 Schema(Avro 示例)
Schema<User> pulsarSchema = Schema.AVRO(User.class);
PulsarDeserializationSchema<User> deserializer =
PulsarDeserializationSchema.pulsarSchema(pulsarSchema);
PulsarSource<User> source = PulsarSource.builder()
.topic("users")
.deserializationSchema(deserializer)
.build();
五、Flink 作为 Pulsar Sink(写入消息)
1. 基本配置
// 处理后的流
DataStream<String> processedStream = stream.map(String::toUpperCase);
// 创建 Pulsar Sink
PulsarSink<String> sink = PulsarSink.builder()
.serviceUrl("pulsar://localhost:6650")
.adminUrl("http://localhost:8080")
.topic("persistent://public/default/output-topic")
.serializationSchema(PulsarSerializationSchema.flinkSchema(Schema.STRING))
.producerConfigurations(
ProducerConfigurationData.builder()
.batchingMaxPublishDelay(10, TimeUnit.MILLISECONDS)
.compressionType(CompressionType.LZ4)
.build()
)
.build();
// 添加 Sink
processedStream.sinkTo(sink);
2. 支持 Exactly-Once 写入(事务模式)
PulsarSink<String> sink = PulsarSink.builder()
.serviceUrl("pulsar://localhost:6650")
.adminUrl("http://localhost:8080")
.topic("output-topic")
.serializationSchema(PulsarSerializationSchema.flinkSchema(Schema.STRING))
.enableTransaction(true) // 启用事务
.build();
✅ 要求 Flink Checkpoint + Pulsar 事务支持。
六、完整示例:实时词频统计
public class WordCountFromPulsar {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.enableCheckpointing(10_000, CheckpointingMode.EXACTLY_ONCE);
// Source: 从 Pulsar 读取
PulsarSource<String> source = PulsarSource.builder()
.serviceUrl("pulsar://localhost:6650")
.adminUrl("http://localhost:8080")
.topic("persistent://public/default/sentences")
.subscriptionName("flink-wordcount")
.deserializationSchema(PulsarDeserializationSchema.flinkSchema(Schema.STRING))
.build();
DataStream<String> lines = env.fromSource(source, WatermarkStrategy.noWatermarks(), "Pulsar Source");
// 处理:分词 + 计数
DataStream<Tuple2<String, Integer>> counts = lines
.flatMap((String line, Collector<String> out) -> {
for (String word : line.toLowerCase().split("\\W+")) {
if (word.length() > 0) out.collect(word);
}
})
.keyBy(value -> value)
.window(TumblingProcessingTimeWindows.of(Time.seconds(10)))
.sum(1);
// Sink: 写回 Pulsar
PulsarSink<Tuple2<String, Integer>> sink = PulsarSink.builder()
.serviceUrl("pulsar://localhost:6650")
.adminUrl("http://localhost:8080")
.topic("persistent://public/default/word-count")
.serializationSchema(PulsarSerializationSchema.flinkSchema(Schema.AVRO(WordCount.class)))
.build();
counts.sinkTo(sink);
env.execute("Pulsar WordCount");
}
}
七、部署方式
| 方式 | 说明 |
|---|---|
| Flink Job Cluster | 提交 JAR 到独立 Flink 集群 |
| Flink on Kubernetes | 使用 flink-kubernetes-operator 部署 |
| YARN / Mesos | 企业已有资源管理平台 |
| Standalone | 测试环境 |
✅ 推荐生产环境使用 Flink on Kubernetes,弹性伸缩、高可用。
八、性能调优建议
| 优化点 | 建议 |
|---|---|
| ✅ 启用 Checkpoint | 间隔 5~10 秒,模式 EXACTLY_ONCE |
| ✅ 合理设置并行度 | 匹配 Pulsar Topic 分区数 |
| ✅ 批量写入 | Sink 启用 batching |
| ✅ 压缩 | 启用 LZ4 或 ZSTD |
| ✅ 状态后端 | 生产用 RocksDB,测试用 Memory |
| ✅ 监控 | 集成 Prometheus + Grafana |
九、监控与可观测性
| 指标 | 采集方式 |
|---|---|
| Flink Checkpoint 时长 | Flink Metrics → Prometheus |
| Pulsar 消费延迟 | pulsar_broker_subscription_backlog |
| Flink 处理延迟 | Flink Web UI 或 Metrics |
| 端到端延迟 | 在消息中注入时间戳 |
✅ 总结
| 特性 | 说明 |
|---|---|
| ✅ 无缝集成 | pulsar-flink-connector 官方维护 |
| ✅ Exactly-Once | Checkpoint + 事务保证 |
| ✅ 事件时间处理 | 支持窗口计算 |
| ✅ Schema 支持 | 类型安全 |
| ✅ 云原生部署 | Flink on K8s + Pulsar on K8s |
| ✅ 流批统一 | Flink 批处理模式读取历史消息 |
📌 一句话总结:
Pulsar + Flink = 实时数据系统的“黄金搭档” —— Pulsar 提供可靠的消息管道,Flink 提供强大的计算能力,二者通过
pulsar-flink-connector紧密集成,构建端到端的实时流处理平台。
1062

被折叠的 条评论
为什么被折叠?



