flink入门到精通

1、lambada架构需要同时搭建批处理(保证数据准确)和流处理(低延迟)两套架构。而flink结合spark-streaming(高吞吐,数据准确性)和storm(低延迟)的优点,这样相当于一套架构实现了lambada架构。
2、flink,spark streaming,storm区别

  • flink和spark streaming都能保持exactlyonce,但是spark为了实现exactlyonce要做的东西很多操作
  • flink吞吐量比storm大,storm只能保持“至少一次”语意,storm不支持状态管理
  • flink是真正流处理,spark streaming是微批处理
  • flink的数据模型是dataflow,即数据流,sparkstreaming是dstream,即rdd的集合

3、flink流的wordcount中,经过map keyBy sum算的单词总数是累计值,即sum的是keyedstream的一个分区的总数据
4、flink有standalone,yarn,k8s集群模式
yarn模式下,rm会在一个nodemanager启动一个am,然后在这个am上启动flink的jobmanager,然后在其他的nodemanager启动taskmanager
5、一个slot是一个并行度,一个slot运行部分数据的整个代码流程,而spark里面一个task运行一个部分数据的某个stage代码流程
6、operator chain: 对于one-to-one的算子(窄依赖),并且并行度(分区)一样的,可以将这些算子任务封装成一个operator chain,这样一个operator chain里面的算子之间就不用进行网络传输,序列化等操作了,提升效率。其实类似于spark的stage,遇到shuffle操作就分为两个operator chain。但是flink的operator chain可以由代码控制哪些算子合并为一个operator chain
7、sparkstreaming读取Kafka,需要在程序最后面自己提交偏移量保证消费准确性。而flink消费Kafka不需要,flink自动保证这方面的准确
8、官方实现了kafkasink,essink,redissink等,但是没有实现mysqlsink,所以需要自己实现
9、window()必须在keyby后面才能使用,windowall在datastream上使用,即所有数据在一个分区
10、周期性水位线设置
1)取得当前数据里面的最大时间戳:比如取到10点的时间戳
2)设置延迟时间:比如延迟1分钟
那么得到9点59分的水位线,即表示9点59分前的数据都已经到达了,可以处理了。即10点的数据来了,并不表示10点的数据都到了,而是表示9点59前的数据都到了
11、flink端到端的exactlyonece:以下的这些策略在flink里面都实现了,不用自己实现

  • source端:利用flink-kafka-consumer可以保持source端offset的exactlyonece
  • 内部:利用checkpoint保持exactlyonece
  • sink端:
    幂等写入
    事务写入:实现方式一:预写日志。二:两阶段提交

12、table api and sql:就是将流转换成表,然后对表进行sql操作,最后将表转换成流
13、状态管理
1)checkpoint
2)state
keyed state:基于keyedstream的状态,每一个key对应一个state
operator state:非keyedstream的状态。与operator绑定的state,整个operator(transform算子)对应一个state
14、flink核心api: DataStream(流处理)和DataSet(批处理)
15、keyBy() (根据key的哈希值重新分区,分组)
16、Flink运行时包含两种类型的进程:

  • 该JobManagers(也称为Masters)协调分布式执行。他们安排任务,协调检查点,协调故障恢复等。总是至少有一个Job
    Manager。高可用性设置将具有多个JobManagers,其中一个始终是Leader,其他人处于待机状态。
  • 该TaskManagers(也叫worker)执行任务(或者更具体地说,子任务)的数据流,以及缓冲器和交换数据流。必须始终至少有一个TaskManager

一个TaskManager有多个slot,一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离
17、Flink任务提交后,Client向HDFS上传Flink的Jar包和配置,之后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster, ApplicationMaster启动后加载Flink的Jar包和配置构建环境,然后启动JobManager,之后ApplicationMaster向ResourceManager申请资源启动TaskManager,ResourceManager分配Container资源后,由ApplicationMaster通知资源所在节点的NodeManager启动TaskManager,NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager,TaskManager启动后JobManager发送心跳包,并等待JobManager向其分配任务。
18、flink闭包:对于字符串,driver节点和远程work节点都能拿到同一个值,但是这个字符串的生命必须在main函数里面,而不能在main函数外面。对于对象,在driver端赋值的对象,在work端拿不到其值,此时的现象是在本地运行没问题,放到集群上跑就显示空指针。此时可以使用广播变量(flink的广播变量很难用),或者不要再driver端初始化对象,而是在work端初始化对象。或者将这个对象在driver端转换成字符串

    val tp = "laojingyao"
	val topics2 = new util.ArrayList[String]()
    topics2.add("hahah")
    println(topics2)	//在提交job的节点输出[hahah]
    transaction.map(line => {
      println("tttt2"+topics2)		//此时topics2为[]
      println(tp)	//输出laojingyao
    })

19、flink启动参数说明
-m 运行模式,这里使用yarn-cluster,即yarn集群模式。
-ys slot个数。
-ynm Yarn application的名字。
-yn task manager 数量。
-yjm job manager 的堆内存大小。
-ytm task manager 的堆内存大小。
-d detach模式。可以运行任务后无需再控制台保持连接。
-c 指定jar包中class全名。
20、对于非KeyedStream,有timeWindowAll、countWindowAll、windowAll操作,其中最主要的是windowAll操作,它的parallelism为1
对于KeyedStream除了继承了DataStream的window相关操作,它主要用的是timeWindow、countWindow、window操作,其中最主要的是window操作
21、引用包:import org.apache.flink.streaming.api.scala.function.{AllWindowFunction, ProcessWindowFunction}
而不是import org.apache.flink.streaming.api.functions.windowing.{AllWindowFunction, ProcessWindowFunction}
22、根据消息eventtime处理的flink程序,由于消息会乱序(迟到):比如30时刻的消息,在20时刻,10时刻前面,我们应该先处理10时刻的数据而不是30的数据。那么需要指定一个时间t,等待t时间,如果t时间内,20和10的消息都没来,我们就认为30是最小的时刻,从而处理30的数据。如果t时间内,只来了20的数据,那我们任务20是最小的时刻,从而先处理20,再处理30… 这个t触发时间就称为watermark
Watermark是个时间戳,一个带有时间戳X的Watermark到达,相当于告诉Flink系统,任何Event Time小于X的数据都已到达
23、watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用watermark机制结合window来实现。虽然大部分情况下数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生(out-of-order或者说late element)。
但是对于late element,我们又不能无限期的等下去,必须要有个机制来保证一个特定的时间后,必须触发window去进行计算了。这个特别的机制,就是watermark。
24、Flink的失败恢复依赖于“检查点机制+可部分重发的数据源”。
检查点机制:
检查点定期触发,产生快照,快照中记录了(1)当前检查点开始时数据源(例如Kafka)中消息的offset,(2)记录了所有有状态的operator当前的状态信息(例如sum中的数值)。
可部分重发的数据源:
Flink选择最近完成的检查点K。然后系统重放整个分布式的数据流,然后给予每个operator他们在检查点k快照中的状态。数据源被设置为从位置Sk开始重新读取流。例如在Apache Kafka中,那意味着告诉消费者从偏移量Sk开始重新消费。
25、Flink主要有两种基础类型的状态:keyed state 和operator state。
你可以将Keyed State视为是已经被分片或分区的Operator State,每个key都有且仅有一个状态分区(state-partition)
Keyed State
顾名思义,就是基于KeyedStream上的状态。这个状态是跟特定的key绑定的,对KeyedStream流上的每一个key,可能都对应一个state。
Operator State
与Keyed State不同,Operator State跟一个特定operator的一个并发实例绑定,整个operator只对应一个state。相比较而言,在一个operator上,可能会有很多个key,从而对应多个keyed state。
从另一个维度来看, Flink 中的状态还可以分为 Managed State 和 Raw State。Managed State 是指由 Flink 的运行时环境来管理状态,而 Raw State 则是由算子自行管理状态,Raw State 的数据结构对 Flink 是透明的。
Flink 的建议是尽量使用 Managed State, 这样 Flink 可以在并行度改变等情况下重新分布状态,并且可以更好地进行内存管理。
KeyedStream上的scala api则提供了一些语法糖(封装了上述状态管理的原理的函数),让创建和使用状态更加方便:使用有状态的 map 算子(mapWithState)完成状态管理
val counts: DataStream[(String, Int)] = stream
.keyBy(record => record._1)
.mapWithState((in: (String, Int), count: Option[Int]) =>
count match {
case Some© => ( (in._1, c + in._2), Some(c + in._2) )
case None => ( (in._1, in._2), Some(in._2) )
})
26、.Flink+Druid构建实时OLAP
kafka–flink–kafka–druid(或者es)–springboot
为了确保数据的正确性,需要把明细数据备份下来,方便数据校验,一般备份的数据不需要实时性的时候,可以将数据落入hive中,而需要实时校对的时候,可以将数据落入druid或者es中
27、ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); //批处理
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); //流处理
28、DataStream中map函数有两个重载的方法,即一个是传入lamada表达式(scala语法糖),另一种是需要传入MapFunction函数

MapFunction函数,
val env = StreamExecutionEnvironment.getExecutionEnvironment
//准备数据,类型DataStreamSource
val dataStreamSource = env.fromElements("I Love You,I Love Chain")
val mapper=new MapFunction[String,String] {
  override def map(value: String): String = {
    value+"aaaaa"
  }
}
  dataStreamSource.map(mapper).print()
Lamada的方式: 其实这种方式里面还是调用了上面第一种的方式,然后再掉java源码中的map方法
另外,只有在scala的源码中,map才会有重载方法,而在java的源码中,就只有一个传入MapFunction函数一种方法
def main(args: Array[String]): Unit = {
//获取环境变量
val env = StreamExecutionEnvironment.getExecutionEnvironment
//准备数据,类型DataStreamSource
val dataStreamSource = env.fromElements("I Love You,I Love Chain")
dataStreamSource.map(value=>value+"++++++").print()

29、flink用scala开发的时候,引入的StreamExecutionEnvironment是:
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
而不是:
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
因为这个带scala的包才会有一些scala的语法糖,如果用下面这个,是没有语法糖的,如果写scala的语法糖就会报错
30、报错:No implicits found for parameter evidence 需要引包:import org.apache.flink.streaming.api.scala._
31、flink写MySQL,如果预编译sql没写对,比如多了个逗号,会有一个bug:invoke会不断的被调用
32、flink-connector-elasticsearch6_2.11和flink-connector-elasticsearch5_2.11的api有不小的差别,
用网上es5的代码去跑es6的环境,代码是报错的,所以要找对相应的版本的demo。ps:网上大部分是flink-connector-elasticsearch5_2.11的代码

你可能感兴趣的:(flink入门到精通)