flink

Flink作为新一代分布式计算引擎,专为高吞吐流式处理设计,强调顺序、时效和容错。它支持事件驱动,提供精确一次一致性,拥有低延迟和生态系统的广泛连接。与Spark Streaming相比,Flink以实时为主,简化架构,适用于ETL和风控等领域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

flink是什么,解决了什么问题?

是一个分布式计算引擎,可以对有界和无界数据流进行状态计算。实现了第三代的流式处理架构,已经在生产中大规模使用。

1.大数据环境下流式处理高吞吐:1秒钟几百万条。传统架构处理不了

流式,连续不断的场景

2.并行处理:分布式。任务的切分、调度、结果返回

3.资源的高效使用

4.经过网络传输和分布式,如何保证顺序、时效、不丢失、不重复

5.容错

6.方便易用的编程接口

流式处理架构演变

第一代,storm,快,纯内存,但不保证正确性。

数据不经过数据库,放内存里直接处理=》低延迟高吞吐。
但为了容错,还是要定期保存状态,为了恢复。=》安全

在这里插入图片描述
流式处理近几年才火的主要原因就是一开始无法解决顺序、时效、完整、不重复。=》

第二代的流式架构lambda

sparkstreaming,之所以划分微批,就是为了lambda架构,保证正确。但延迟慢,秒级别。不支持乱序数据,时间语义支持弱。

2套系统,一套流式保证低延迟,第二套用批处理层保证准确性

先做快速处理,来一个处理一个,结果写在快速表。同时进行批处理,存在批处理表。然后一批一批的merge,把结果写入app层。因为batch表更准,所以merge后的数据就是准的(merge就是覆盖,相当于对流处理表进行校正)。最终的结果就是用户一开始看到的数据不太准,过段时间数据会变,变准了。

在这里插入图片描述
缺点:要实现2套系统,也就意味着2套完全不同的组件、架构,维护、迭代麻烦。

第三代:flink

场景

网站点击量
在这里插入图片描述

特点

事件驱动(Event-driven)

意思就是数据来了才会计算。程序启动后处于阻塞状态,靠触发来执行,比如一个提交表单的web项目,网站是一直运行的,但只有提交表单的时候才会真正执行注册程序。
flink的driver程序执行后仅仅定义好了task,需要使用env.execute()来开启一个进程,接收流。
在这里插入图片描述

基于流,跟spark的主要区别

一切都是流,离线数据是有界的流,实时数据是一个没有界限的流。这就是所谓的有界流和无界流

分层API

越顶层越抽象,表达含义越简明,使用越方便
越底层越具体,表达能力越丰富,使用越灵活。
PF可以获取所有相关的状态,可以设置定时器。
在这里插入图片描述

支持事件时间(event-time)和处理时间(processing-time)语义

精确一次(exactly-once)的状态一致性保证

低延迟,每秒处理数百万个事件,毫秒级延迟

生态系统庞大,与众多常用存储系统的连接

高可用,动态扩展,实现7*24小时全天候运行

在这里插入图片描述

同spark区别

架构

在这里插入图片描述

spark
dstream
structureStreaming
微批次,准实时,一批一个task,一个task的生命周期包括生成task、序列化后提交到executor、放到线程池、执行、拉取结果。
spark一开始的初心是离线处理,不管离线还是实时sparkstreaming,底层都是sparkcore,sparkstreaming其实就是不断的处理微批次的数据,用批处理的方式来处理流式数据。
底层通信用的是akka

solt是对资源的抽象。一个solt意味着一个task,意味着一定数量的cpu和内存。

flink也是在driver生成task,也是放到工作节点的线程池,但只需要提交一次,task会一直运行,是真正的实时。
flink是把批处理视为一种特殊的流处理。
生态系统也在完善

场景

SparkStreaming 在聚合处理性能是Flink 的2~3倍。Spark StructStreaming也支持时间语义。Flink适合ETL 和风控(实时性要求高)

抽象模型

spark 采用 RDD 模型,spark streaming 的 DStream 实际上也就是一组组小批数据 RDD 的集合
flink 基本数据模型是数据流,以及事件(Event)序列

运行时架构

spark 基于批计算,将 DAG 划分为不同的 stage,一个完成后才可以计算下一个。
flink 是标准的流执行模式,一个事件在一个节点处理完后可以直接发往下一个节点进行处理

部署

配文参数

jobmanager.heap.size
taskmanager.memory.process.size 因为taskmanager不仅仅使用jvm的内存,所以这里不叫heap.size。除了jvm的内存,还有flink计算用的,cache的
taskmanager.memory.flink.size taskmanager.memory.process.size比这个大,这2个开一个就行,另一个注释。在使用容器时,比如yarn和k8s,需要向容器申请的资源是有上限的,所以此时要用process.size
taskmanager.numberOfTaskSlots 一个taskmanager的slot个数
parallelism.default job提交后,在flink集群的并行度,是任务层面的。但这个配置的优先级很低,要先看代码中的算子、代码中的全局(env也可以配置并行度)、提交命令中的、最后才是配文中的。numberOfTaskSlots是资源层面的,当然任务不能超过资源。如果是standalone,没设按这个,如果是在容器中,就按容器的核心数。

webUI
容错-重启策略
临时目录位置

提交任务

使用web界面、restapi、命令行

yarn

本质就是向yarn申请资源,启动flink

flink把hadoop的支持单独设置了一个jar,官方不提供全套,安装完flink后,要单独把这个jar放在flink的lib目录下。

2种模式

区别就是一个TM早就启动好,
一个是提交后每个app单独启动TM

构建项目

flink官方提供了脚手架,可以使用maven命令或者使用curl | bash -s args 来下个脚本然后直接执行的方式构建maven项目。pom.xml都设置好了。很方便。

要使用mvn命令,要配置maven的环境变量。配置完之后如果用idea的terminal,要重启idea,否则不识别mvn的环境变量。
cmd中命令的换行符是 ^,不是 \

编程

nc -lk

netcat 命令

ParameterTool

flink提供的获取jar包运行参数的工具类
在这里插入图片描述

在这里插入图片描述

跟sparkstreaming一样,要到代码最后在调用execute()开个线程。但不同的是批处理时,flink也要在最后执行execute(),spark不用。

调用execute()时会有个检查异常,此时一定不要catch,而是要throws,这样flink才能捕获并作出处理。scala会自动throws,所以不需要显式的写。

如果执行了keyBy,那么相同的key肯定会进入同一个solt。
solt的总数由逻辑核数决定,也就是常说的x核y线程,中的y,不是x。

如果读socket,则需要提前启动socket工具(nc -lk),否则程序连不上会直接报错退出

java lambda表达式无法自动推断返回值的类型,所以运行时main方法会报错,需要在后面加returns()并且参数处写明类型。或者用匿名实现类的方式。
在这里插入图片描述

flink中必须要有sink,也就是spark中的action

并行度

无论是spark还是flink,都是用的抽象数据集,spark是rdd,flink是stream。而且2者的并行度一定要在划分任务前就定好,否则driver就不知道怎么划分task了。所以rdd和stream的并行度实际上在程序运行之前就确定了的。

因为source也是运行在TaskManager上的,为了测试,flink提供了2种将本地集合并行化为stream的方式,其中parallelsim可以创建分布式的数据集,可以设置并行度。

flink可以在env设置全局,也可以在每个算子后面设置。

kafka-source


package cn._51doit.flink.kafka

import java.util.Properties

import org.apache.flink.api.common.serialization.{DeserializationSchema, SimpleStringSchema}
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer

object KafkaSourceDemo {

  def main(args: Array[String]): Unit = {

    val env = StreamExecutionEnvironment.getExecutionEnvironment

    val props = new Properties()

    props.setProperty("bootstrap.servers", "node-1.51doit.cn:9092,node-2.51doit.cn:9092,node-3.51doit.cn:9092")
    // 0.11后不需要连zookeeper
    props.setProperty("group.id", "test") // the id of the consumer group
    props.setProperty("auto.offset.reset", "earliest") // 如果没有记录偏移量,第一次从哪里消费,一般是最开始
	props.setProperty("enable.auto.commit", "false") // 消费者是否自动提交,默认为是,将偏移量存在特殊的topic: __consumer_offset。如想实现exactly once,就要自己管理偏移量,不让consumer管理。要结合checkpoint。

    val kafkaConsumer = new FlinkKafkaConsumer[String](
      "kafka-flink",
      new SimpleStringSchema,
      props
    )

    val lines: DataStream[String] = env.addSource(kafkaConsumer)

    lines.addSink(line => {
      println(line)
    })

    env.execute()
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值