?Flink基于zookeeper/yarn(基于zookeeper),zookeeper挂掉如何处理
?slot底层是什么
?什么时候flink的流批进行统一处理
?Flink的datastream与spark的dataframe有什么区别
?从Kafka向Flink输入数据,过程中kafka宕机,如何保证数据不丢失,不重复读取
?ack机制与checkpoint区别
?jvm堆内存一般放什么
flink:
一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算
优势:
1高性能,高吞吐,低延迟;(如何实现?)
2支持event Time(如何实现?)
3支持有状态计算(如何实现?)
4支持灵活的window(Time/Count/Session/Data-driven),灵活的触发条件(如何实现?)
5基于轻量级分布式快照CheckPoint,支持容错,将拆解成的小计算过程分布到节点上处理,checkpoint将执行状态中状态信息进行持久化存储,确保处理数据在过程中的一致性(与ack机制的区别)
6基于JVM实现独立的内存管理,将所有数据对象转化城二进制在内存中存储,降低存储大小,对内存空间充分利用
7savePoint将任务执行的快照存储,任务重启时可直接从save点恢复
什么是状态?
计算过程中产生的中间结果,每次计算新结果是基于中间结果,不需进行全量计算,减少计算过程中间损耗和硬件存储
主要应用:
实时智能推荐、复杂事件处理(工业领域)、实时欺诈检测、实时数仓、ETL类型、流数据分析类型、实时报班类型等业务场景
流处理案例:
main
val env=StreamExecutionEnvironment.getExecutionEnvironment
import org.apache.flink.streaming.api.scala._
val stream=env.sockTextStream("node1",8888)
stream.flatmap(_.split(","))
.map((_,1))
.keyby(0)
.sum(1)
.print
env.execute("wordcount")
集群基本架构
Master-Server架构原则(JobManger TaskManager)
采用多线程方式,比MR的多JVM进程方式,提高CPU效率,在多个任务和Task之间通过TaskSlot共享系统资源,每个TaskManager管理多个TaSlot资源池对资源进行管理
Slot与并行度区别:一个是实际拥有能力,一个是实际使用的并发能力
集群运行模式
Standalone:不依赖其他平台,独立部署
on yarn:
(改yarn尝试次数及关闭内存限制;下载Pre-bundied Hadoop 2.7.5连接jar包)
1session-cluster,yarn中初始化一个集群
2Pre-job-cluster,每次提交job,创建一个新的flink集群
Flink集群的HA:
依赖zookeeper和hdfs,分配多台jobmanager(写在masters文件中)
配置flink-shaded-hadoop-2-uber-2.7.5-10.0.jar依赖包
Flink On Yarn HA:
部署:
借助zookeeper完成,
配置jobmanager元数据存储路径到hdfs(flink-conf.yaml high-availabilty.storageDir:hdfs://mycluster/flink/yarnha/)
配置zookeeper集群节点
实现原理(运行逻辑):
1.启动Flink Yarn client 会话,申请资源,检查资源是否可用,上传jar包、conf到hdfs
2.client向Yarn Manager 请求 资源、ApplicationMaster、Container ,同一容器有 ApplicationMaster 和JobManager
3.Yarn Manager 分配ApplicationMaster 、JobManager
4.JobManager 分配 taskerManager
5.taskerManager 从hdfs下载 jar和conf(配置环境)
提交任务模式
1.session-cluster
YARN中提前初始化一个Flink集群(称为Flink yarn-session),开辟指定的资源。Flink集群会常驻在YARN集群中,除非手工停止(yarn application -kill id)
2.per-Job
每次提交Flink任务都会创建一个新的Flink集群,每个Flink任务之间相互独立
任务并行度设置的优先顺序:
算子层面(Operator level)>执行环境..(Execution Environment..)>客户端..(Client..)>系统..(System..)
Flink常用API
SQL/Table API(dynamic tables)
DataStream Api(Streams,windows)
ProcessFunction(events,state,time)
DataStream
Environment
DataSource
--HDFS:
env.readTextFile("hdfs://node2:8020/xx")
--Sqe:
env.fromCollection(Array(
new Tuple(,)
))
--Element:
env.fromElement(('A',1),('B',1))
--Kafka:
①读取Kafka String
val pops=new Properties()
pops.setProperty("bootstrap","nodex:9092")
pops.setProperty("key.deserializer",classOf[StringDeserializer].getName)
...
env.addSource(new FlinkKafkaConsumer[String]("name",new SimpleStringSchema(),pops)
②读取Kafka KV类型
...
val xx=new FlinkKafkaConsumer[(String,Int)])(
"name",
new KafkaDeserializationSchema[(Int, String)] {
},
props)
)
env.addSource(flinkKafkaConsumer.setStartFromLatest())
--自定义Source:
实现SourceFunction
实现ParallelSourceFunction 继承RichParallelSourceFunction
Transformation
--Map(DataStream->D)
--FlatMap(D->D)
--Filter(D->D)
--KeyBy(D->KeyStream)
--Reduce(K->D)
val reduceStream = keyedStream.reduce {
(t1, t2) =>
(t1._1, t1._2 + t2._2)}
--Aggregations(K->D)
将reduce函数进行封装,sum min max minby maxby...
--Union(D->D)
val unionStream = dataStream1.union(dataStream_02)
--Connect CoMap CoFlatMap(D->connected stream ->D)
**Union两流格式必须一样
**Connect两流或者多流格式可以不一样,connectStream后,需Comap调整为一样的格式
val connectstream=datastream1.connect(datastream2)
connectstream.map(t1=>(t1._1,t1._2),t2=>(t2,0))
--Split select(D->Split stream->D)
val splitStream=datastream.split(t=>if (t._2%2==0) seq("even")else seq("odd"))
val eventstream=splitstream.select("even")
val allstream=splitstream.select("even","odd")
Sink
--HDFS
设置滚动规则 DefaultRollingPolicy.create()
( * withInactivityInterval :桶不活跃的间隔时长,如果一个桶最近一段时间都没有写入,那么这个桶被认为是不活跃的,sink 默认会每分钟检查不活跃的桶、关闭那些超过一分钟没有数据写入的桶。
* withMaxPartSize : 设置文件多大后生成新的文件,默认128M。
* withRolloverInterval :每隔多长时间生成一个新的文件,默认1分钟)
StreamingFileSink.forRowFormat[StationLog](
new Path("hdfs://mycluster/flinkresult"),
new SimpleStringEncoder[StationLog]("UTF-8"))
.withBucketCheckInterval(1000)//检查分桶的间隔时间,默认每分钟检查桶(目录),是否生成新的桶目录,默认是每小时生成一个桶。
.withRollingPolicy(policy) )
--Redis
val confg=new FlinkJedisPoolConfig.builder().setDatabase(1).setPort(6379).build()
result.addSink(new RedisSink[(String, Int)](config,new RedisMapper[(String, Int)] {
override def getCommandDescription = new RedisCommandDescription(RedisCommand.HSET,"t_wc") //t_wc是表名
override def getKeyFromData(data: (String, Int)) = {
data._1 //单词
}
override def getValueFromData(data: (String, Int)) = {
data._2+"" //单词出现的次数
}
}
flink 梳理
最新推荐文章于 2022-07-31 15:48:59 发布
本文深入探讨了Apache Flink的核心概念,包括数据流、事件时间和窗口处理。详细解释了Flink的数据处理流程,从数据源接入到转换操作,再到结果输出。同时,文章还讨论了Flink的容错机制及其在实时流处理中的优势。
摘要由CSDN通过智能技术生成