Flink 2020尚硅谷

Flink简介

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Flink底层主要书java实现

Apache Flink 是一个框架和分布式处理引擎,用于对无界和有界数据流进行状态计算。

flink是要解决的问题就是,在高吞吐量的前提下实现实时的数据处理

flink是真的流式处理(实时处理),Spark Streaming是假的流式处理()实时处理,SpringStream是批处理,只是每批的数据比较小。

Spring Stream一般是几秒的延迟(有参数可以设置)

如今的大数据技术应用场景,对实时性的要求已经越来越高。作为新一代大数据流处理框架,由于非常好的实时性,Flink 独树一帜,在近些年引起了业内极大的兴趣和关注。Flink能够提供毫秒级别的延迟,同时保证了数据处理的低延迟、高吞吐和结果的正确性,还提供了丰富的时间类型和窗口计算、Exactly-once 语义支持,另外还可以进行状态管理,并提供了 CEP(复杂事件处理)的支持。Flink 在实时分析领域的优势,使得越来越多的公司开始将实时项目向 Flink 迁移,其社区也在快速发展壮大。
目前,Flink 已经成为各大公司实时领域的发力重点,特别是国内以阿里为代表的一众大厂,都在全力投入,不少公司为 Flink 社区贡献了大量源码。如今 Flink 已被很多人认为是大数据实时处理的方向和未来,很多公司也都在招聘和储备了解掌握 Flink 的人才。

Flink应用场景

在这里插入图片描述

传统数据处理架构

在这里插入图片描述

分析处理

用到了数据仓
在这里插入图片描述

流式处理

在这里插入图片描述

有状态的流式处理

有状态主要是指的,把流式数据存储起来(周期性的保存),方便数据处理系统异常是数据恢复。
在这里插入图片描述

流处理的演变

老式的lambda机构:批处理+流处理
先通过流处理保证数据的实时性,后期在通过批处理保证数据的正确性。

在这里插入图片描述
在这里插入图片描述

Flink特点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Flink和Spark Streaming的区别

在这里插入图片描述

Flink运行时架构

运行是时组件

在这里插入图片描述

作业管理器(JobManager)

在这里插入图片描述

任务管理器(TaskManager)

任务管理器是flink中干活的(处理业务逻辑)
在这里插入图片描述

资源管理器(ResourceManager)

在这里插入图片描述

分发器(Dispatcher)

在这里插入图片描述

任务提交流程

在这里插入图片描述
上图是从一个较为高层级的视角,来看应用中各组件的交互协作。如果部署的集群环境 不同(例如 YARN,Mesos,Kubernetes,standalone 等),其中一些步骤可以被省略,或是 有些组件会运行在同一个 JVM 进程中。

任务调度原理

第五章 Flink 流处理 API

在这里插入图片描述

5.1 Environment

在这里插入图片描述

5.2 Source(数据来源)

5.2.3 以 kafka 消息队列的数据作为来源

kafka主要是做流式数据处理,kafka是flink的最佳拍档,一般都是使用kafka做为flink的数据源。
flink kafka 的客户端可以自动根据topic的分区数启动对应的工作线程数

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka-0.11_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu</groupId>
    <artifactId>FlinkTutorial</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-scala_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.flink/flink-streaming-scala -->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-scala_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka-0.11_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.bahir</groupId>
            <artifactId>flink-connector-redis_2.11</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-elasticsearch6_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-statebackend-rocksdb_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <!-- 该插件用于将Scala代码编译成class文件 -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.4.6</version>
                <executions>
                    <execution>
                        <!-- 声明绑定到maven的compile阶段 -->
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

SourceTest.scala:

package com.atguigu.apitest

import java.util.Properties

import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.functions.source.SourceFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011

import scala.util.Random

/**
  * Copyright (c) 2018-2028 尚硅谷 All Rights Reserved 
  *
  * Project: FlinkTutorial
  * Package: com.atguigu.apitest
  * Version: 1.0
  *
  * Created by wushengran on 2019/9/17 10:11
  */

// 定义传感器数据样例类
case class SensorReading( id: String, timestamp: Long, temperature: Double )

object SourceTest {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    // 1. 从集合中读取数据
    val stream1 = env.fromCollection(List(
      SensorReading("sensor_1", 1547718199, 35.80018327300259),
      SensorReading("sensor_6", 1547718201, 15.402984393403084),
      SensorReading("sensor_7", 1547718202, 6.720945201171228),
      SensorReading("sensor_10", 1547718205, 38.101067604893444)
    ))

//    env.fromElements("flink", 1, 32, 3213, 0.324).print("test")

    // 2. 从文件中读取数据
    val stream2 = env.readTextFile("D:\\Projects\\BigData\\FlinkTutorial\\src\\main\\resources\\sensor.txt")

    // 3. 从kafka中读取数据
    // 创建kafka相关的配置
    val properties = new Properties()
    properties.setProperty("bootstrap.servers", "localhost:9092")
    properties.setProperty("group.id", "consumer-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")

    val stream3 = env.addSource(new FlinkKafkaConsumer011[String]("topic-sensor", new SimpleStringSchema(), properties))

    // sink输出
    stream3.print("stream3")
    
    // 4. 自定义数据源
 //   val stream4 = env.addSource(new SensorSource())

    // sink输出
   // stream4.print("stream4")

    env.execute("source api test")
  }
}

class SensorSource() extends SourceFunction[SensorReading]{
  // 定义一个flag:表示数据源是否还在正常运行
  var running: Boolean = true
  override def cancel(): Unit = running = false

  override def run(ctx: SourceFunction.SourceContext[SensorReading]): Unit = {
    // 创建一个随机数发生器
    val rand = new Random()

    // 随机初始换生成10个传感器的温度数据,之后在它基础随机波动生成流数据
    var curTemp = 1.to(10).map(
      i => ( "sensor_" + i, 60 + rand.nextGaussian() * 20 )
    )

    // 无限循环生成流数据,除非被cancel
    while(running){
      // 更新温度值
      curTemp = curTemp.map(
        t => (t._1, t._2 + rand.nextGaussian())
      )
      // 获取当前的时间戳
      val curTime = System.currentTimeMillis()
      // 包装成SensorReading,输出
      curTemp.foreach(
        t => ctx.collect( SensorReading(t._1, curTime, t._2) )
      )
      // 间隔100ms
      Thread.sleep(100)
    }
  }
}

5.3Transform(转换算子->数据转换)

数据转换操作代码示例

package com.atguigu.apitest

import org.apache.flink.api.common.functions.{FilterFunction, RichMapFunction}
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.scala._

/**
  * Copyright (c) 2018-2028 尚硅谷 All Rights Reserved 
  *
  * Project: FlinkTutorial
  * Package: com.atguigu.apitest
  * Version: 1.0
  *
  * Created by wushengran on 2019/9/17 11:41
  */
object TransformTest {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    // 读入数据
    val inputStream = env.readTextFile("D:\\Projects\\BigData\\FlinkTutorial\\src\\main\\resources\\sensor.txt")

    // Transform操作->转换成样例类类型

    val dataStream = inputStream
      .map(
        data => {
          val dataArray = data.split(",")
          SensorReading( dataArray(0).trim, dataArray(1).trim.toLong, dataArray(2).trim.toDouble )
        }
      )

    // 1. 聚合操作
     val stream1 = dataStream
       //以id为key进行分组
       .keyBy("id")
       //分组后再处理
      // .min("temperature")
       //.minBy("temperature")
     // .sum("temperature")
      .reduce( (x, y) => SensorReading(x.id, x.timestamp + 1, y.temperature + 10) )

    stream1.print();

    // 2. 分流,根据温度是否大于30度划分
    val splitStream = dataStream
      .split( sensorData => {
        if( sensorData.temperature > 30 ) Seq("high") else Seq("low")
      } )

    val highTempStream = splitStream.select("high")
    val lowTempStream = splitStream.select("low")
    val allTempStream = splitStream.select("high", "low")
    highTempStream.print("高")
    lowTempStream.print("低")
    allTempStream.print("所有")
    
    // 3. 合并两条流
    val warningStream = highTempStream.map( sensorData => (sensorData.id, sensorData.temperature) )
    val connectedStreams = warningStream.connect(lowTempStream)

    val coMapStream = connectedStreams.map(
      warningData => ( warningData._1, warningData._2, "high temperature warning" ),
      lowData => ( lowData.id, "healthy" )
    )

    val unionStream = highTempStream.union(lowTempStream)

    // 函数类
    dataStream.filter( new MyFilter() ).print()

    // 输出数据
//    dataStream.print()
//    highTempStream.print("high")
//    lowTempStream.print("low")
//    allTempStream.print("all")
//    unionStream.print("union")

    env.execute("transform test job")
  }
}

class MyFilter() extends FilterFunction[SensorReading]{
  override def filter(value: SensorReading): Boolean = {
    value.id.startsWith("sensor_1")
  }
}

class MyMapper() extends RichMapFunction[SensorReading, String]{
  override def map(value: SensorReading): String = {
    "flink"
  }

  override def open(parameters: Configuration): Unit = super.open(parameters)
}

简单转换算子

5.3.1 map

在这里插入图片描述

// Transform操作->转换成样例类类型

    val dataStream = inputStream
      .map(
        data => {
          val dataArray = data.split(",")
          SensorReading( dataArray(0).trim, dataArray(1).trim.toLong, dataArray(2).trim.toDouble )
        }
      )
5.3.2 flatMap

在这里插入图片描述

Filter

在这里插入图片描述

分组后再处理

5.3.4 KeyBy

在这里插入图片描述

5.3.5 滚动聚合算子(Rolling Aggregation)

在这里插入图片描述

  val stream1 = dataStream
       //以id为key进行分组
       .keyBy("id")
       //分组后再处理
      // .min("temperature")
       //.minBy("temperature")
     // .sum("temperature")
      .reduce( (x, y) => SensorReading(x.id, x.timestamp + 1, y.temperature + 10) )

    stream1.print();
复杂转换算子
5.3.6 Reduce

在这里插入图片描述
在这里插入图片描述

多流转换算子

5.3.7 Split 和 Select(分流)

实际使用场景:kafka流数据进来,只消费我需要的消息,不需要的再写回kafka供其他人消费。
在这里插入图片描述
分流:
在这里插入图片描述
在这里插入图片描述

    // 2. 分流,根据温度是否大于30度划分
    val splitStream = dataStream
      .split( sensorData => {
        if( sensorData.temperature > 30 ) Seq("high") else Seq("low")
      } )

    val highTempStream = splitStream.select("high")
    val lowTempStream = splitStream.select("low")
    val allTempStream = splitStream.select("high", "low")
    highTempStream.print("高")
    lowTempStream.print("低")
    allTempStream.print("所有")
5.3.8 Connect 和 CoMap(合流)

在这里插入图片描述
在这里插入图片描述

5.3.9 Union

在这里插入图片描述

5.6 Sink (数据输出)

在这里插入图片描述

5.6.1 Kafka

pom.xml

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka-0.11_2.12</artifactId>
            <version>1.10.1</version>
        </dependency>

主函数中添加 sink:

dataStream.addSink( new FlinkKafkaProducer011[String]("localhost:9092", "sinktest-topic", new SimpleStringSchema()) )
package com.atguigu.apitest.sinttest

import java.util.Properties

import com.atguigu.apitest.SensorReading
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.connectors.kafka.{FlinkKafkaConsumer011, FlinkKafkaProducer011}

/**
  * Copyright (c) 2018-2028 尚硅谷 All Rights Reserved 
  *
  * Project: FlinkTutorial
  * Package: com.atguigu.apitest.sinttest
  * Version: 1.0
  *
  * Created by wushengran on 2020/8/7 10:12
  */
object KafkaSinkTest {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)
    // 读取数据
//    val inputPath = "D:\\Projects\\BigData\\FlinkTutorial\\src\\main\\resources\\sensor.txt"
//    val inputStream = env.readTextFile(inputPath)

    // 从kafka读取数据
    val properties = new Properties()
    properties.setProperty("bootstrap.servers", "localhost:9092")
    properties.setProperty("group.id", "consumer-group")
    val stream = env.addSource( new FlinkKafkaConsumer011[String]("sensor", new SimpleStringSchema(), properties) )


    // 先转换成样例类类型(简单转换操作)
    val dataStream = stream
      .map( data => {
        val arr = data.split(",")
        SensorReading(arr(0), arr(1).toLong, arr(2).toDouble).toString
      } )

    dataStream.addSink( new FlinkKafkaProducer011[String]("localhost:9092", "sinktest", new SimpleStringSchema()) )

    env.execute("kafka sink test")
  }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值