Flink累加器Accumulator使用

Flink累加器Accumulator

在Flink程序中如果需要对某些数值进行累加,我们可以用到累加器

累加器也是在JobManager的内存中生成,同时传给TaskManager内存给tasks进行累加的只读数据结构,必须等task操作都操作完了之后才能在客户端读取到累加器的值。

切记:数据在线程内存中传递需要实现序列化

累加器分类

  • IntCounter
  • LongCounter
  • DoubleCounter
  • Hitogram(直方圆)>>> 一般是Flink程序内部调用
  • 自定义累加器(实现SimpleAccumulator接口)

累加器的简单使用

三步走:

1、声明累加器

2、在算子函数中添加累加器

getRuntimeContext.addAccumulator(x,x)

3、在执行完之后获取累加器的值

简单实例代码

nc -lk 9999

输入数据格式为:

1001,sensorreading01,1587778747108,32.3
1001,sensorreading02,1587778756789,36.5
1001,sensorreading01,1587778767891,38.0
1001,sensorreading03,1587778778910,35.4
1001,sensorreading03,1587778789101,33.8
1001,sensorreading01,1587778791011,34.1

package com.shufang.accumulator

import org.apache.flink.api.common.JobExecutionResult
import org.apache.flink.api.common.accumulators.{DoubleCounter, IntCounter, LongCounter}
import org.apache.flink.api.common.functions.{RichMapFunction, RuntimeContext}
import org.apache.flink.api.java.utils.ParameterTool
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.scala._

object AccumulatorDemo {
  def main(args: Array[String]): Unit = {

    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment


    val tool: ParameterTool = ParameterTool.fromPropertiesFile("src/main/resources/netcat.properties")
    val ds: DataStream[String] = env.socketTextStream(tool.get("hostname"), tool.getInt("port"))


    //
    ds.map(
      new RichMapFunction[String, String] {

        //1、声明累加器,要在富函数中声明全局的
        val normal = new LongCounter()
        val exception = new LongCounter()
        val all = new LongCounter()


        //2、在open函数中添加累加器
        override def open(parameters: Configuration): Unit ={
          val rc: RuntimeContext = getRuntimeContext
          rc.addAccumulator("normal_temperture",normal)
          rc.addAccumulator("exception_temperture",exception)
          rc.addAccumulator("all_temperture",all)
        }

        override def map(value: String): String = {

          //进行累加
          all.add(1)
          val msg = "体温过高,需要隔离进行排查!~"
          val temper: Double = value.split(",")(3).toDouble
          if (temper > 36.4){
            //进行累加
            exception.add(1)
            s"${value.split(',')(1).trim} 的体温为 $temper, $msg"
          }else{
            //进行累加
            normal.add(1)
            s"${value.split(',')(1).trim} 的体温为 $temper, 体温正常,请进入"
          }
        }
      }
    ).print("体温结果为: ")

    val result: JobExecutionResult = env.execute("accumulator")

    //3、执行完了之后获取累加器的值
    val normal: Long = result.getAccumulatorResult[Long]("normal_temperture")
    val exception: Long = result.getAccumulatorResult[Long]("exception_temperture")
    val all: Long = result.getAccumulatorResult[Long]("all_temperture")


    println(s"normal $normal")
    println(s"exception $exception")
    println(s"all $all")

    /** 实例结果
     * 体温结果为: :2> sensorreading03 的体温为 33.8, 体温正常,请进入
     * 体温结果为: :6> sensorreading03 的体温为 35.4, 体温正常,请进入
     * 体温结果为: :2> sensorreading01 的体温为 34.1, 体温正常,请进入
     * 体温结果为: :8> sensorreading01 的体温为 34.1, 体温正常,请进入
     * normal 16
     * exception 7
     * all 23
     */
  }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值