配合状态(state)使用的键控流(KeyedDataStream)

Keyed DataStream

键数据流(KeyedDataStream)概念:在flink中数据集为DataStream,对其进行分区时,会产生一个KeyedDataStream,然后允许使用键数据流的operator以及特有的state(如mapstate、valuestate等)

如果想使用key state,需要对DataStream指明一个key进行分区,也可以使用keyby创建一个KeyedDataStream,对这个KeyedDataStream可以使用keyed state。

keyby可以通过列下标选择使用列,也可以选择使用列名进行分区。由于flink的keyby不是key-value键值对形式,所以键是虚拟的。

使用Keyed State

keyed state有几种不同的类型,它们只能作用于KeyedStream,所以使用前,需要保证数据集为KeyedStream,比如先要调用stream.keyBy(…),相同的key都只有一个state共享使用。

将state用于程序中:

创建state必须要使用RuntimeContext进行访问,所以只能在RichFunction中才能创建和使用,例如:RichMapFunction、RichFlatMapFunction、RichFilterFunction和KeyedProcessFunction等。

  • ValueState<T>:这个state只能保存一个值,可以对value state进行更新和提取,通过调用state.update(T)和state.value()完成,判断是否为空可以通过null == state.value()。

创建value state:

import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor}

val stateDescriptor = new ValueStateDescriptor[String]("value_state", createTypeInformation[String])
val value_state: ValueState[String] = getRuntimeContext.getState[String](stateDescriptor)
  • ListState<T>:这个state可以保存一个list集合的元素,可以进行添加和遍历一个Iterable检索所有的元素。添加元素可以通过add(T)或者addAll(List<T>)进行单独和批量的添加,获取迭代器可通过state.get(),也可以通过update(List<T>)进行全部覆盖操作

创建list state:

import org.apache.flink.api.common.state.{ListStateDescriptor}

val listStateDescriptor = new ListStateDescriptor[String]("listStateDescriptor", createTypeInformation[String])

val list_state = getRuntimeContext.getListState[String](listStateDescriptor)
  •  ReducingState<T>:与ListState相似,但这个state实际值保留一个值,当有新的元素加入时,会通过ReduceFunction进行元素聚合
  • AggregatingState<IN, OUT>:与ReducingState相似,也是对新元素与旧元素聚合后只保留一个值,但不同的是AggregatingState的输入与输出是不一样的数据类型
  • MapState<key, value>:这是一个多元素的key-value形式state(使用方式类似于编程语言中的map)。使用put(key,value)或者putAll(Map<key, value>),检索使用get(key)。获取全部元素时,使用state.entries()、state.values()、state.values获取迭代器。还可以使用state.isEmpty()来判断是否是空的state。

创建一个key为string,value为List[JsonObject]形式的复合结构

import org.apache.flink.api.common.state.{MapState, MapStateDescriptor}

val ontimer_map_desc = new MapStateDescriptor[String, List[JsonObject]]("map_state", createTypeInformation[String], createTypeInformation[List[JsonObject]])

val map_state: MapState[String, List[JsonObject]] = getRuntimeContext.getMapState[String, List[JsonObject]](map_desc)

所有类型的state都可以通过state.clear清除所有元素。

state TTL(生存周期)

每个state都可以配置元素生存周期,当达到设定值时,会在后台清楚过期元素,保证state中都是有效数据。当前仅支持process time类型的TTL。

使用state TTL,需要创建一个StateTtlConfig配置对象,然后调用api进行自定义配置。

为state使用TTL示例

import org.apache.flink.api.common.state.StateTtlConfig
import org.apache.flink.api.common.state.ValueStateDescriptor
import org.apache.flink.api.common.time.Time

val ttlConfig =
    StateTtlConfig.newBuilder(Time.minutes(10)) //生存时间值
    .setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
    .setStateVisibility(StateTtlConfig.StateVisibility.ReturnExpiredIfNotCleanedUp) //允许返回过期值
    .cleanupFullSnapshot() // 在快照的时候进行删除
    .cleanupInBackground() //在后台激活清理
    .build()

val stateDescriptor = new ValueStateDescriptor[String]("text state", classOf[String])
stateDescriptor.enableTimeToLive(ttlConfig)

newBuilder是必须要有的,表示元素生存时间。

配置刷新TTL类型:

  • StateTtlConfig.UpdateType.OnCreateAndWrite -仅在创建和写访问权限时(默认此配置)
  • StateTtlConfig.UpdateType.OnReadAndWrite - 在读取和写入时

配置过期元素是否可用,当外部调用已过期但没有被清除元素时执行此配置:

  • StateTtlConfig.StateVisibility.NeverReturnExpired -永不返回过期值(默认此配置)
  • StateTtlConfig.StateVisibility.ReturnExpiredIfNotCleanedUp -如果仍然可用,没有被清除,则返回

清理过期状态:

  • 完整快照时清理(cleanupFullSnapshot):在生成完整快照时执行清理操作,减轻大小
  • 增量清理(cleanupIncrementaally):采取逐步触发清除策略,触发器拉矮子每次状态中元素的访问或者每个记录处理后的回调,如果不满足触发条件,会一直存在过期数据。
  • RocksDB压缩期间的清理(cleanupInRocksddbCompactFilter):当rockdb处理一定量的元素后,会检查到期时间,进行清除,会出现降低压缩性能的影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天佑凡人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值