Advertisement

码农必备!一文吃透Flink

阅读量:
在这里插入图片描述

可以说,Flink 是一个非常强大的开源流式计算框架,在处理有界的和无界的数据流方面表现突出。其中以批次形式送达的数据(有界的),比如每个月结束时的一堆订单报告;而无界的则类似于持续不断供应的实时访问记录。你可以把 Flink 比喻为一个高效的数据处理流水线:它接收不同类型的'原材料'(数据),并能灵活地根据不同的需求对其进行处理(计算),同时能够记住并利用加工过程中的关键信息(状态)。最终它会产出一系列结构化的处理结果(即系统的各种指标)。

在这里插入图片描述

1、支持事件时间语义:很多流处理框架用系统时间(处理时间)做窗口计算,Flink 支持基于事件时间(Event Time)语义进行窗口计算 ,也就是使用事件产生的时间。比如在电商场景下,用户下单时间就是事件时间,即使订单数据因网络延迟等原因乱序到达 Flink 系统,它也能根据事件时间准确统计出某个时间段内的订单数量、金额等数据,保障数据的准确性 。
2、有状态计算:在 1.4 版本中,Flink 实现了状态管理。在流式计算时,算子会把中间结果数据保存在内存或文件系统里,当下一个事件进入算子,就能从之前的状态中获取中间结果,继续计算当前结果 ,无需每次都基于全部原始数据来统计。比如统计网站实时在线用户数,每来一个用户登录或退出事件,Flink 通过维护状态(当前在线用户集合),就能快速更新在线用户数,而不是每次都遍历所有用户登录记录。
3、灵活的窗口操作:Flink 把窗口分为基于时间(Time)、数量(Count)、会话(Session)以及数据驱动(Data - driven)等类型。以电商网站统计每小时商品点击量为例,就可以用基于时间的滚动窗口;若要统计每 100 次点击的相关数据,就用基于数量的窗口;而像统计用户在网站上的活跃会话时长,就可以使用会话窗口 。而且窗口还能用灵活的触发条件定制化,以满足复杂的流传输模式。
4、高吞吐低延迟:Flink 在处理大规模数据流时,能每秒处理数百万个事件,延迟控制在毫秒级。在实时监控系统中,需要对大量的监控数据进行实时分析,Flink 能快速处理这些数据,及时发现异常情况并报警,保障系统稳定运行。
5、容错机制:Flink 基于轻量级分布式快照(CheckPoint)实现容错。当任务分布式运行在多个节点上时,若出现节点宕机、网络传输问题或者计算服务重启等异常,Flink 能通过 CheckPoints 将执行过程中的状态信息持久化存储,一旦任务异常停止,就从 Checkpoint 中自动恢复任务,确保数据处理的一致性 ,即 Exactly - Once 语义 。

在这里插入图片描述

让我们简要介绍Flink的基本使用流程。第一步需要一个数据源,如从文件、Kafka主题或socket中获取数据,例如从Kafka读取数据时,代码通常会是这样的:

复制代码
    import org.apache.flink.streaming.api.datastream.DataStream;
    import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
    import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
    import java.util.Properties;
    
    public class KafkaSourceExample {
    public static void main(String[] args) throws Exception {
        // 设置Flink执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    
        // 设置Kafka数据源参数
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "localhost:9092");
        properties.setProperty("group.id", "test-group");
        properties.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        properties.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        properties.setProperty("auto.offset.reset", "latest");
    
        // 创建Kafka数据源实例
        FlinkKafkaConsumer<String> kafkaSource = new FlinkKafkaConsumer<>("test-topic", new SimpleStringSchema(), properties);
    
        // 创建数据流
        DataStream<String> dataStream = env.addSource(kafkaSource);
    
        // 后续可对dataStream进行各种操作
        // 执行Flink程序
        env.execute("Kafka Source Example");
    }
    }

完成 数据源 处理 后 ,随后 构建 一个DataStream 对象 。然后 可以 对该DataStream对象 应用 一系列 转换 操作 ,如 map 、 filter 和 reduce 等 。其中 ,map 方法 能够 将 输入 的 数据 进行 类型 转换 ,例如 将 字符串 类型 的 字段 转换 为 整数值 ,或 者 调整 字段 格式 或 单位 。filter 方法 用于 筛选出 符合 条件 的 数据 ,例如 仅 筛选 出 金 额 超 过 100 元 的 订单 记录 。而 reduce 方法 能够 汇总 所有 符合 条件 的 数据 信 息 。

复制代码
    DataStream<Integer> mappedStream = dataStream.map(s -> Integer.parseInt(s));
    DataStream<Integer> filteredStream = mappedStream.filter(i -> i > 100);
    DataStream<Integer> reducedStream = filteredStream.keyBy(i -> 1).reduce((i1, i2) -> i1 + i2);

最后一步需配置数据接收器的实现步骤,在此基础之上将处理后的结果进行传输至外部系统进行处理。例如,在将结果保存至文件时,在Kafka主题上进行传输的情形下,默认情况下会触发相关操作。相应的Python代码如下:

复制代码
    import org.apache.flink.streaming.api.datastream.DataStream;
    import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
    import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
    
    public class KafkaSinkExample {
    public static void main(String[] args) throws Exception {
        // 设置Flink执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    
        // 设置Kafka数据接收器参数
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "localhost:9092");
        properties.setProperty("topic", "output-topic");
    
        // 创建Kafka数据接收器实例
        FlinkKafkaProducer<String> kafkaSink = new FlinkKafkaProducer<>("output-topic", new SimpleStringSchema(), properties);
    
        // 假设已经有处理好的数据流dataStream
        dataStream.addSink(kafkaSink);
    
        // 执行Flink程序
        env.execute("Kafka Sink Example");
    }
    }
在这里插入图片描述

在大数据处理领域中,Flink 常与 Spark 和 Storm 等主流框架进行对比分析。我们首先聚焦于 Flink 和 Spark 的异同点:两者均提供批处理与流处理功能,均基于内存计算,均具备统一的批流处理 API,还提供类似 SQL 的编程接口,并配有完善错误恢复机制,可保证 Exactly once 的语义一致性。然而它们之间也存在显著差异:从设计理念来看,Flink 采用事件驱动型流处理框架,按事件一行一行地进行流式处理,真正实现了流式计算;而 Spark 则基于微批模拟流计算的技术,将数据流划分为以时间为单位的批次,通过分布式数据集 RDD 实现批量处理,属于伪实时系统。
在架构配置上,Flink 包含 Jobmanager、Taskmanager 和 Slot 等主要组件;而 Spark 则由 Master、Worker、Driver 和 Executor 等角色组成。
任务调度机制方面,Flink 根据用户提交代码生成 StreamGraph 并优化后生成 JobGraph,随后提交给 JobManager 进行调度管理;JobManager 根据 ExecutionGraph 对相应的任务进行调度安排;Spark 则持续生成微小数据批次构建 DAG 并根据 DAG 中的操作指令形成 job 实例;每个 job 又会根据窄宽依赖关系生成多个执行阶段。
时间机制上,Flink 支持事件时间、注入时间和处理时间等多种时间机制,并具备 watermark 机制来处理延迟数据;能够有效应对乱序大实时数据的挑战;而 Spark 时间机制较为有限,仅支持 processing time 来模拟 event time,可能导致时间和顺序上的误差积累。
最后对比 Flink 和 Storm 的性能表现:Flink 在单线程吞吐量上远超 Storm(Identity 逻辑下 Storm 单线程吞吐量为 8.7 万条/秒,Flink 达到 35 万条/秒);Flink 还支持有状态的流式处理功能而 Storm 没有此能力。

在这里插入图片描述

在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好,在多个领域中运行良好

总结

在这里插入图片描述

在开源领域中,Flink被视为一个强大的流处理框架。它不仅支持基于事件的时间语义模型,并且能够实现高吞吐量的同时保持低延迟,在提供支持有状态计算的功能的同时还具备灵活的窗口操作特性以及较强的容错能力。无论是大数据领域的新手还是经验丰富的开发者都能从中获益匪浅。如果你对Flink也感兴趣不妨深入探索它独特的功能特点并分享你的学习心得与疑问我们共同进步!

全部评论 (0)

还没有任何评论哟~