点击蓝字
关注~~
在上一篇Flink实战: 窗口TopN分析与实现中实现了在一个窗口内的分组topN,但是在实际中也会遇到没有窗口期的topN,例如在一些实时大屏监控展示中,展示历史到现在所有的TopN数据,将这个称之为全局topN,仍然以计算区域维度销售额topN的商品为例,看一下全局TopN的实现方法。先将需求分解为以下几步:
按照区域areaId+商品gdsId分组,计算每个分组的累计销售额
将得到的区域areaId+商品gdsId维度的销售额按照区域areaId分组,然后求得TopN的销售额商品,并且定时更新输出
与窗口TopN不同,全局TopN没有时间窗口的概念,也就没有时间的概念,因此使用ProcessingTime语义即可,并且也不能再使用Window算子来操作,但是在这个过程中需要完成数据累加操作与定时输出功能,选择ProcessFunction函数来完成,使用State保存中间结果数据,保证数据一致性语义,使用定时器来完成定时输出功能。
销售额统计
对数据流按照区域areaId+商品gdsId分组,不断累加销售额保存起来,然后输出到下游。
val env =StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val kafkaConfig =newProperties();
kafkaConfig.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"localhost:9092");
kafkaConfig.put(ConsumerConfig.GROUP_ID_CONFIG,"test1");
val consumer =newFlinkKafkaConsumer011[String]("topic1",newSimpleStringSchema(), kafkaConfig)
val orderStream = env.addSource(consumer)
.map(x =>{
val a = x.split(",")
Order(a(0), a(1).toLong, a(2), a(3).toDouble, a(4))
})
val salesStream=orderStream.keyBy(x =>{
x.areaId +"_"+ x.gdsId
}).process(newKeyedProcessFunction[String,Order,GdsSales](){
var orderState:ValueState[Double]= _
var orderStateDesc:ValueStateDescriptor[Double]= _
override def open(parameters:Configuration):Unit={
orderStateDesc =newValueStateDescriptor[Double]("order-state",TypeInformation.of(classOf[Double]))
orderState = getRuntimeContext.getState(orderStateDesc)
}
override def processElement