flink入门了解

在线工程

在机器学习场景下,在线离线处理也会面临一些问题。首先会将离线的数据进行预处理和特征工程(如红框标注所示),然后进行离线的模型训练,训练好的模型会推到线上做推理。推理模块加载模型后,在线的数据也会有进行预处理和特征工程的过程,将处理之后的数据喂给模型做在线推理。

在机器学习领域除了离线的模型训练以外,还有在线的模型训练。如下图所示,我们通常会将预处理的数据写到一个 Message Queue 中(如 Kafka),然后进行 Online training,training 的过程是持续不断的,期间会不断的产生动态的模型,然后推送给在线的推理模块进行推理。在线的机器学习的特点就是模型的动态更新、持续训练和不断验证。同时需要比较复杂的模型监控,模型部署和模型回滚等策略。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tNVFW4nj-1598944435687)(C:\Users\sereny\AppData\Roaming\Typora\typora-user-images\image-20200807144441560.png)]

https://developer.aliyun.com/article/749461

Apache Flink是一个面向数据流处理和批量数据处理的可分布式的开源计算框架,它基于同一个流式执行模型能够支持流处理和批处理两种应用类型。

那么 Flink 在这套架构中有什么样的价值。Flink 是天生支持批流一体的计算引擎,在在线机器学习领域的预处理过程中,我们很自然地会使用 Flink 进行数据处理,在离线的机器学习训练中也可以使用 Flink 进行批次的预处理。同时,在在线推理的过程中,也会使用 Flink 进行推理(因为推理是一个对时间比较敏感的过程)。所以 Flink 在机器学习 Lambda 架构中的价值体现在在线的数据的预处理,离线数据的预处理,在线的推理**。FLINK处理特征**

  • 首先是数据的管理和获取阶段(Data Acquisition),在这个阶段 Flink 提供了非常丰富的 connector(包括对 HDFS,Kafka 等多种存储的支持),Flink 目前还没有提供对整个数据集的管理。
  • 下一个阶段是整个数据的预处理(Preprocessing)及特征工程部分,在这个阶段 Flink 已经是一个批流统一的计算引擎,并且提供了较强的 SQL 支持。
  • 之后是模型训练过程(Model Training),在这个过程中,Flink 提供了 Iterator 的支持,并且有如 Alink,MLlib 这样丰富的机器学习库支持,且支持 TensorFlow,Pytorch 这样的深度学习框架。
  • 模型产出之后是模型验证和管理阶段(Model Validation & Serving),这个阶段 Flink 目前还没有涉足。
  • 最后是线上推理阶段(Inference),这个阶段 Flink 还没有形成一套完整的方案。同时形成了 Flink ML Pipeline,以及目前正在做的 Flink AI Flow。

Flink程序包含以下组件:
1. 一个从kafka中读取数据的source
2. 一个窗口聚合操作
3. 一个将结果写往kafka的sink。

git项目

https://github.com/CheckChe0803/flink-recommandSystem-demo

实时flink和kafka

实时任务的终极目标就是7 x 24无间断运行。Spark Streaming和Flink的广播机制都能做到这点,

Flink消费kafka数据,消费者offset提交配置

Flink 提供了特殊的Kafka Connectors来从Kafka topic中读取数据或者将数据写入到Kafkatopic中,Flink的Kafka Consumer与Flink的检查点机制相结合,提供exactly-once处理语义。为了做到这一点,Flink并不完全依赖于Kafka的consumer组的offset跟踪,而是在自己的内部去跟踪和检查。

处理flink的stream数据时,常用的组件就是kafka,源数据或者处理后的数据产生后会被采集到kafka中。kafka可以作为flink的source和sink使用,任务失败时,可以通过设置kafka的offset来恢复应用来重新消费数据

代码

# Scala
val source = env.fromElements(("hello", 1), ("hello", 2))
  def testReduceWithRichReducerFails() {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val source = env.fromElements(("hello", 1), ("hello", 2))

    env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime) //设置时间域 时间的流式处理

    source
      .windowAll(SlidingEventTimeWindows.of(Time.seconds(1), Time.milliseconds(100)))
      .reduce(new RichReduceFunction[(String, Int)] {
        override def reduce(value1: (String, Int), value2: (String, Int)) = null
      })

    fail("exception was not thrown")
  }

helloworld:https://blog.csdn.net/kongxx/article/details/90166338

Flink的概念和功能介绍

(1)flink是什么,能够做什么?
(2)批/流的差异
(3)flink Job的组成
(4)flink常用算子的功能介绍
(5)Checkpoint机制的简单介绍
(6)Stateful的简单介绍
平台的使用和例子分析
(1)在平台提交Job的流程
(2)job的日常维护
(3)例子分析
(4)实时场景及解决方案的分析

更高的实时性、可靠内存模型、完善的状态管理

作业提交:
      创建项目 -> 申请资源 -> 创建作业 -> 作业上线 -> 作业启动
作业更新:
      代码更新  -> 作业上线 ->停止运行中作业 -> 启动新作业
作业的操作展示

简单ETL任务(jar)
     需求简述:
           把非格式化的一条log数据格式化之后输出相应的Json数据
     DAG图: source ->map ->sink
     核心代码分析
数据统计(sql)
   需求简述:
          统计前端上报的某个指标数据1分钟、5分钟、1个小时的和
    处理逻辑:
    
Job组成和处理过程
     operator -> operatorChain(SubTask) -> task -> job

常用算子及其功能

(1)常用转换操作:Map,flatMap,filter
(2)分区选择操作:keyBy,broadcast, forward, shuffle,rescale,rebarance
(3) KeyedStream 的ruduce,flod, aggregations(sum/min/max/avg)
(4)window(apply,reduce,flod,aggregations)
(5) processFunction

map 常用的场景:   单输入单输出 
   1. sources和sink的数据序列化和反序列化
      简单ETL处理
 FlatMap
    1.单输入零个或多个输出,可提供状态操作。
           常用场景:
            1. 复杂ETL需要有状态保留的
            2. 数据需要数据扁平化
Filter
   用于过滤数据,在Sql表现为where语句,   常用的场景:脏数据处理和数据筛选
keyBy
    用于返回一个KeyedStream, 对KeyedStream进行的操作都是在key的范围内。(state/timeService)。
rescale和rebalance区别:
      DistributionPattern不同rebalance 是:ALL-TO-ALL,而rescale是POINTWISE.
Window: Tumbling,Sliding,Session,Global
    (1)trigger:可自定义触器
    (2)evictor:窗口为结束是驱逐窗口数据
    (3)allowedLateness:定义延迟时间
processFunction
    低层Api,常用于实现比较复杂的需求。通过自管理state以及timer的结合可以模拟window计算以及做预聚合等
Asynchronous I/O
    算子目的是通过异步池的方式,提高算子并发量,从而增大算子吞吐量。常用于和外部服务交互,提高资源利用

checkpoint机制

checkpoint是flink的容错机制,通过checkpoint对触发flink内部的全局状态的持久化,来应对flink的恢复。

state介绍

状态类型:
        (1). flink自管理状态(算子本身状态,比如数据源的offset,window中content)
        (2). 用户自管理状态
               a.状态数据结构:valueSate,listState,mapState
               b.存储格式:二进制数据
               c.Backends:Memory, Fs, RocksDB
               note:平台使用RocksDB

场景-mySqlJoin-redisJoin-流Join-大窗口


任务维护

作业日常维护
jar方式:四看一注意
(1)看checkpoint时间,看GC时间情况,看内存使用情况,
看backPressure
(2)注意堆积和异常的报警
Blink-Sql
二看一注意
(1)看in/out 指标,看业务延迟指标
(2)注意延迟和异常警告

对于实时处理来说,来自传感器,移动设备或者应用日志的数据通常写入消息队列系统(如 Kafka), 消息队列负责为流处理应用提供数据的临时缓冲。然后再使用 Spark Streaming 从 Kafka 中读取数据做实时的流计算。但由于 Kafka 不会一直保存历史数据,因此如果用户的商业逻辑是结合历史数据和实时数据同时做分析,那么这条流水线实际上是没有办法完成的。因此为了补偿,需要额外开辟一条批处理的流水线,即图中" Batch "部分

处理数据

批处理的特点是有界、持久、大量,非常适合需要访问全套记录才能完成的计算工作,一般用于离线统计。

流处理的特点是无界、实时, 无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作,一般用于实时统计。

Flink 程序支持 java 和 scala 两种语言,在引入包中,有 java 和 scala 两种包时注意要使用 scala 的包。

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 向其分配任务。

流处理过程:https://gitbook.cn/books/5de886ea51f91b78e2939d3f/index.html

抽象化为一系列operator,以source开始,以sink结尾,中间的operator做的操作叫做transform,并且可以把几个操作串在一起执行

程序执行即env.execute("Java WordCount from SocketTextStream Example")这行代码。
这行代码主要做了以下事情:
生成StreamGraph。代表程序的拓扑结构,是从用户代码直接生成的图。
生成JobGraph。这个图是要交给flink去生成task的图。生成一系列配置
将JobGraph和配置交给flink集群去运行。如果不是本地运行的话,还会把jar文件通过网络发给其他节点。
以本地模式运行的话,可以看到启动过程,如启动性能度量、web模块、JobManager、ResourceManager、taskManager等等
启动任务。值得一提的是在启动任务之前,先启动了一个用户类加载器,这个类加载器可以用来做一些在运行时动态加载类的工作

分析和AI的统一工作流(AI Flow)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t1ji9cEm-1598944435690)(C:\Users\sereny\AppData\Roaming\Typora\typora-user-images\image-20200807144538877.png)]

在整个机器学习任务中,有一部分是和模型训练相关的,还有一部分是数据分析,特征工程相关的。因此 AI Flow 的目标是将这整个流程串起来,提供一个端到端的解决方案。

AI Flow 的 API 中包含了 Example(对数据的 API),Transformer(对预处理流程及推理的 API),Trainer(训练流程的 API),Model(模型管理的 API)等。在每个模块中都会产生一些中间 meta 数据,AI Flow 将这些数据存储在 Meta Store 中。这些 API 只是定义了机器学习中的一些处理逻辑,AI Flow 中的 Translator 则将这些逻辑转化为真正可执行的任务。

WaterMark 详解

http://wuchong.me/blog/2018/11/18/flink-tips-watermarks-in-apache-flink-made-easy/

*watermark 的作用,他们定义了何时不再等待更早的数据。*

Flink 中的事件时间处理依赖于一种特殊的带时间戳的元素,成为 watermark,它们会由数据源或是 watermark 生成器插入数据流中。具有时间戳 t 的 watermark 可以被理解为断言了所有时间戳小于或等于 t 的事件都(在某种合理的概率上)已经到达了。

实战

http://wuchong.me/blog/2018/11/07/use-flink-calculate-hot-items/

代码:https://github.com/wuchong/my-flink-project/blob/master/src/main/java/myflink/HotItems.java

package myflink;

public class HotItems {

  public static void main(String[] args) throws Exception {
    
  }

2

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment()--启动
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);  //设置时间分配器
env.setParallelism(1);  //设置并行度
env.getConfig().setAutoWatermarkInterval(9000);//9秒发出一个watermark

flink 支持三种时间机制:事件时间,注入时间,处理时间,同时支持 watermark 机制处理滞后数据。

程序-0628

.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[ClickLog](Time.seconds(5)) { //指定element允许滞后的最大时间
  override def extractTimestamp(element: ClickLog): Long = {
    element.clickTime.getTime
  }
Apache Flink是一个分布式系统,需要计算资源才能执行应用程序。Flink与所有常见的集群资源管理器(如Hadoop YARN,Apache Mesos和Kubernetes)集成,但也可以设置为作为独立集群运行。

flink的 webui

并行

parallelism 是并行的意思,在 Flink 里面代表每个任务的并行度,适当的提高并行度可以大大提高 job 的执行效率,比如你的 job 消费 kafka 数据过慢,适当调大可能就消费正常了。

./bin/flink run -p 10 ../word-count.jar #命令启动设置
//整个程序的并行度,那么后面如果你的每个算子不单独设置并行度覆盖的话,那么后面每个算子的并行度就都是这里设置的并行度的值了
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(10);
///每个算子后面单独的设置并行度,这样的话,就算你前面设置了 env.setParallelism(10) 也是会被覆盖的。
data.keyBy(new xxxKey())
    .flatMap(new XxxFlatMapFunction()).setParallelism(5)
    .map(new XxxMapFunction).setParallelism(5)
    .addSink(new XxxSink()).setParallelism(1)
优先级是:算子设置并行度 > env 设置并行度 > 配置文件默认并行度

什么是 slot?

图中 Task Manager 是从 Job Manager 处接收需要部署的 Task,任务的并行性由每个 Task Manager 上可用的 slot 决定。每个任务代表分配给任务槽的一组资源,slot 在 Flink 里面可以认为是资源组,Flink 将每个任务分成子任务并且将这些子任务分配到 slot 来并行执行程序。

例如,如果 Task Manager 有四个 slot,那么它将为每个 slot 分配 25% 的内存。 可以在一个 slot 中运行一个或多个线程。 同一 slot 中的线程共享相同的 JVM。 同一 JVM 中的任务共享 TCP 连接和心跳消息。Task Manager 的一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离。默认情况下,Flink 允许子任务共享 Slot,即使它们是不同 task 的 subtask,只要它们来自相同的 job。这种共享可以有更好的资源利用率。


 slot 的数量通常与每个 TaskManager 的可用 CPU 内核数成比例。一般情况下你的 slot 数是你每个 TaskManager 的 cpu 的核数。
每个 Task Manager 有三个 slot,这样我们的算子最大并行度那么就可以达到 6 个,在同一个 slot 里面可以执行 1 至多个子任务。
http://www.54tianzhisheng.cn/2019/01/14/Flink-parallelism-slot/图片中,source/map/keyby/window/apply 最大可以有 6 个并行度,sink 只用了 1 个并行

其他:https://cloud.tencent.com/developer/article/1506784

你可能感兴趣的:(大数据,推荐系统)