Flink keyed state 和RichFunction测试

一 数据源及入口

def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    //设置时间语义  时间发生时间
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
    env.setParallelism(1)


    val socketSource: DataStream[String] = env.socketTextStream("localhost", 7777)

    val mapStream: DataStream[SensorReading] = socketSource
      .map(data => {
        val split: Array[String] = data.split("\\W+")
        SensorReading(split(0).trim, split(1).trim.toLong, split(2).trim.toDouble)
      })
//fun: (T, Option[S]) => (TraversableOnce[R], Option[S])): DataStream[R]
    val richFlatMapStream: DataStream[SensorReading] = mapStream.
      keyBy(_.id)
      .flatMapWithState(tmpStageChangeFunction)
    richFlatMapStream.print("warning")
    env.execute()

  }

二 key State

键控状态是根据输入数据流中定义的键(key)来维护和访问的。Flink为每个键值维护一个状态实例,并将具有相同键的所有数据,都分区到同一个算子任务中,这个任务会维护和处理这个key对应的状态。当任务处理一条数据时,它会自动将状态的访问范围限定为当前数据的key。因此,具有相同key的所有数据都会访问相同的状态。Keyed State很类似于一个分布式的key-value map数据结构,只能用于KeyedStream(keyBy算子处理之后)

Flink的Keyed State支持以下数据类型:

2.1 ValueState[T]保存单个的值,值的类型为T。

  • get操作: ValueState.value()
  • set操作: ValueState.update(value: T)

2.2 ListState[T]保存一个列表,列表里的元素的数据类型为T。基本操作如下:

  • ListState.add(value: T)
  • ListState.addAll(values: java.util.List[T])
  • ListState.get()返回Iterable[T]
  • ListState.update(values: java.util.List[T])

2.3 MapState[K, V]保存Key-Value对。

  • MapState.get(key: K)
  • MapState.put(key: K, value: V)
  • MapState.contains(key: K)
  • MapState.remove(key: K)

2.4 ReducingState[T]

2.5 AggregatingState[I, O]

2.6 State.clear()是清空操作。

三 RichFlatMapFunction

class TempFlatMapFunction(limit:Long) extends  RichFlatMapFunction[SensorReading,SensorReading]{
  // 定义状态 缓存上次的温度值
  var tmpState:MapState[String,Double]= _;


  override def open(parameters: Configuration): Unit = {
    tmpState= getRuntimeContext.getMapState(new MapStateDescriptor[String,Double]("lastTemp",classOf[String],classOf[Double]))
  }

  override def flatMap(in: SensorReading, collector: Collector[SensorReading]): Unit = {
    // 从状态中取出当前的
    val lastTmp = tmpState.get(in.id)
    val diff = (lastTmp-in.tm).abs
    if(diff > limit){
      collector.collect(in)
    }
    tmpState.put(in.id,in.tm) // 更新状态的值

  }
}

四 flatMapWithState

调用:

val richFlatMapStream: DataStream[SensorReading] = mapStream.
      keyBy(_.id)
      .flatMapWithState(tmpStageChangeFunction)
//函数
  def tmpStageChangeFunction(v:SensorReading,option: Option[Double])={

    option match {
      case None =>(List.empty,Some(v.tm))  //第一次没值的时候 取当前数据的温度
      case Some(value)=>{
        val diff: Double =(v.tm-value).abs  //有值则判断 温度变化范围是否超过了 预设的值
         if(diff> 17){
           (List(v),Some(v.tm))

         }else{
           (List.empty,None)
         }
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Master_slaves

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值