입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))

지도:

val streamMap = stream.map {x => x * 2}

flatMap

즉, 중첩 된 컬렉션은 중첩되지 않은 컬렉션으로 변환되고 병합됩니다.
예를 들어, 목록이 공백으로 구분 된 데이터를 분리하고 추출하려는 경우 다음을 수행 할 수 있습니다.
List ( "ab", "cd"). flatMap (line => line. split ( ""))의
최종 결과는 다음과 같습니다. List (a, b, c, d
val streamFlatMap = stream.flatMap {
x => x.split ( "")
}

필터

if 필터링, 람다 표현식 제공, bool 유형의 값 반환과 유사하며 최종 결과가 참인지 여부에 따라 현재 결과가 유지되는지 여부를 판단합니다
.val streamFilter = stream.filter {
x => x == 1
}

KeyBy는
입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))
먼저 그룹화 한 다음 집계됩니다
.DataStream-> KeyedStream : 스트림을 분리 된 파티션으로 논리적으로 분할합니다. 각 파티션은 동일한 키 요소를 포함하며 내부적으로 해시 형식으로 구현됩니다.

롤링 집계 연산자 (롤링 집계)
이 연산자는 KeyedStream의 각 분기에 대해 집계를 수행 할 수 있습니다.
sum ()
min ()
max ()
minBy ()
maxBy ()

줄이다

분할 및 선택

스플릿

DataStream-> SplitStream : 특정 특성에 따라 DataStram을 둘 이상의 DataStream으로 분할합니다.

고르다

입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))
SplitStream-> DataStream : SplitStream에서 하나 이상의 DataStream을 가져옵니다.

요구 사항 : 센서 데이터는 온도 (경계로 30도)에 따라 두 개의 스트림으로 나뉩니다.

연결 및 CoMap

스트림은 병합되지만 두 스트림 만 하나의 스트림으로 병합됩니다. 병합 된 두 스트림은 여전히 ​​독립적이며 서로 영향을주지 않습니다.

입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))

DataStream, DataStream-> ConnectedStreams : 유형을 유지하는 두 개의 데이터 스트림을 연결합니다. 두 데이터 스트림이 연결된 후에는 동일한 스트림에만 배치됩니다. 두 데이터 스트림의 내부 데이터 및 형식은 변경되지 않습니다. 스트림은 서로 독립적입니다.
CoMap, CoFlatMap

입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))

ConnectedStreams-> DataStream : ConnectedStreams에서 작동하는 기능은 map 및 flatMap과 동일하며 ConnectedStreams의 각 Stream은 각각 map 및 flatMap으로 처리됩니다.

노동 조합

스트림 병합은 두 스트림의 데이터를 하나의 스트림으로 직접 병합하는 것으로 두 스트림의 데이터는 일관성이 있어야하며 그렇지 않으면 사용할 수 없습니다.

입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))

주위:

새 패키지 com.mafei.apitest를 만들고 새 scala 개체 클래스 TransformTest를 만듭니다.

package com.mafei.apitest

import org.apache.flink.api.common.functions.ReduceFunction
import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment, createTypeInformation}

//获取传感器数据

case class SensorReadingTest(id: String,timestamp: Long, temperature: Double)

object TransformTest {
  def main(args: Array[String]): Unit = {
    //创建执行环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    val inputStream= env.readTextFile("/opt/java2020_study/maven/flink1/src/main/resources/sensor.txt")
    env.setParallelism(1)

//    inputStream.print()
    //先转换成样例类类型
    val dataStream = inputStream
      .map(data =>{
        val arr = data.split(",")   //按照,分割数据,获取结果
        SensorReadingTest(arr(0), arr(1).toLong,arr(2).toDouble)  //生成一个传感器类的数据,参数中传toLong和toDouble是因为默认分割后是字符串类别
      })
    /**
     * dataStream.print()  输出样例
      1> SensorReadingTest(sensor4,1603766240,40.1)
      4> SensorReadingTest(sensor4,1603766284,44.0)
      2> SensorReadingTest(sensor1,1603766281,41.0)
      3> SensorReadingTest(sensor3,1603766283,43.0)
      2> SensorReadingTest(sensor2,1603766282,42.0)

     */

    //分组聚合,输出每个传感器当前最小值
    val aggStream = dataStream
      .keyBy("id")   //根据id来进行分组
//      .min("temperature")  //获取每一组中temperature 为最小的数据
      .min("temperature")  //获取每一组中temperature 为最小的数据

    /**
    aggStream.print()

      1> SensorReadingTest(sensor1,1603766281,41.0)
      2> SensorReadingTest(sensor3,1603766283,43.0)
      4> SensorReadingTest(sensor2,1603766282,42.0)
      1> SensorReadingTest(sensor4,1603766240,40.1)   // 所有sensor的数据只会输出最小的值
      1> SensorReadingTest(sensor4,1603766240,40.1)   // 所有sensor的数据只会输出最小的值
     */

    //需要输出当前最小的温度值,以及最近的时间戳,要用到reduce
    val resultStream = dataStream
      .keyBy("id")
//      .reduce((curState, newData)=>{
//        SensorReadingTest(curState.id,newData.timestamp, curState.temperature.min(newData.timestamp))
//      })
      .reduce( new MyreduceFunction)   //如果不用上面的lambda表达式,也可以自己写实现类,一样的效果,二选一

    /**

    print(resultStream.print())
    SensorReadingTest(sensor2,1603766282,42.0)
    SensorReadingTest(sensor3,1603766283,43.0)
    SensorReadingTest(sensor4,1603766240,40.1)
    SensorReadingTest(sensor4,1603766284,40.1)  //可以看到虽然sensor4的时间戳还是在更新,但是temperature 一直是最小的一个
    SensorReadingTest(sensor4,1603766249,40.1)
     */

    // 多流转换操作
    //分流,将传感器温度数据分成低温、高温两条流
    val splitStream = dataStream
      .split(data =>{
        if (data.temperature > 30.0 ) Seq("high") else Seq("low")
      })

    val highStream = splitStream.select("high")
    val lowStream = splitStream.select("low")

    val allStream = splitStream.select("high", "low")

    /**
     *
     * 数据输出样例: 大于30的都在high里面,小于30都在low
     * highStream.print("high")
     * lowStream.print("low")
     * allStream.print("all")
     *
     * all> SensorReadingTest(sensor1,1603766281,41.0)
     * high> SensorReadingTest(sensor1,1603766281,41.0)
     * all> SensorReadingTest(sensor2,1603766282,42.0)
     * high> SensorReadingTest(sensor2,1603766282,42.0)
     * all> SensorReadingTest(sensor4,1603766284,20.0)
     * low> SensorReadingTest(sensor4,1603766284,20.0)
     * all> SensorReadingTest(sensor4,1603766249,40.2)
     * high> SensorReadingTest(sensor4,1603766249,40.2)
     * all> SensorReadingTest(sensor3,1603766283,43.0)
     * high> SensorReadingTest(sensor3,1603766283,43.0)
     * all> SensorReadingTest(sensor4,1603766240,40.1)
     * high> SensorReadingTest(sensor4,1603766240,40.1)
     */

    //合流,connect
    val warningStream = highStream.map(data =>(data.id, data.temperature))

    val connectedStreams = warningStream.connect(lowStream)

    //用coMap对数据进行分别处理
    val coMapResultStream = connectedStreams
      .map(
        warningData =>(warningData._1,warningData._2,"warning"),
        lowTempData => (lowTempData.id, "healthy")
      )

    /**
     * coMapResultStream.print()
     *
     * (sensor1,41.0,warning)
     * (sensor4,healthy)
     * (sensor2,42.0,warning)
     * (sensor4,40.2,warning)
     * (sensor3,43.0,warning)
     * (sensor4,40.1,warning)
     */

    env.execute("stream test")

  }

}

class MyreduceFunction extends  ReduceFunction[SensorReadingTest]{
  override def reduce(t: SensorReadingTest, t1: SensorReadingTest): SensorReadingTest =
    SensorReadingTest(t.id, t1.timestamp, t.temperature.min(t1.temperature))
}

사용 된 데이터 sensor.txt
센서
1,1603766281,41
센서
2,1603766282,42
센서
3,1603766283,43 센서 4,1603766240,40.1 센서 4,1603766284,44 센서 4,1603766249,40.2

최종 코드 구조 :

입력에서 실제 향기로 Flink (5, Flink 다양한 데이터 변환 작업 (변환))

추천

출처blog.51cto.com/mapengfei/2547236