StateTtlConfig
如果配置了 TTL 并且状态值已过期,可以清理状态中的值。可以通过以下配置,启用TTL功能:
StateTtlConfig ttlConfig = StateTtlConfig.newBuilder(Time.seconds(1)).setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite).setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired).build()
方法参数解析:
Time.days(1) 过期时间
setUpdateType 更新类型(存在两种模式StateTtlConfig.UpdateType.OnCreateAndWrite - 只在创建和写的时候清除 (默认),StateTtlConfig.UpdateType.OnReadAndWrite - 在读和写的时候清除)
setStateVisibility 访问state的时候是否返回过期值 (StateTtlConfig.StateVisibility.NeverReturnExpired - 不返回过期值,StateTtlConfig.StateVisibility.ReturnExpiredIfNotCleanedUp - 可以返回过期值)
NeverReturnExpired 对于 TTL 之后之前的数据数据不能再用
代码示例:
//按照设备id进行分组
KeyedStream<JSONObject, String> keyByWithMidDstream =
jsonObjStream.keyBy(jsonObj -> jsonObj.getJSONObject(“common”).getString(“id”));
SingleOutputStreamOperator filteredJsonObjDstream =
keyByWithMidDstream.filter(new RichFilterFunction() {
//定义状态用于存放最后访问的日期
ValueState lastVisitDateState = null;
//日期格式
SimpleDateFormat simpleDateFormat = null;
//初始化状态 以及时间格式器
@Override
public void open(Configuration parameters) throws Exception {
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
if (lastVisitDateState == null) {
ValueStateDescriptor<String> lastViewDateStateDescriptor =
new ValueStateDescriptor<>("lastViewDateState", String.class);
//因为统计的是当日UV,也就是日活,所有为状态设置失效时间为一天
StateTtlConfig stateTtlConfig=StateTtlConfig.newBuilder(Time.days(1)).build();
//默认值 表明当状态创建或每次写入时都会更新时间戳
//.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
//默认值 一旦这个状态过期了,那么永远不会被返回给调用方,只会返回空状态
//.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired).build();
lastViewDateStateDescriptor.enableTimeToLive(stateTtlConfig );
lastVisitDateState = getRuntimeContext().getState(lastViewDateStateDescriptor);
}
}
//首先检查当前页面是否有上页标识,如果有说明该次访问一定不是当日首次
@Override
public boolean filter(JSONObject jsonObject) throws Exception {
String lastPageId = jsonObject.getJSONObject("page").getString("last_page_id");
if(lastPageId!=null&&lastPageId.length()>0){
return false;
}
Long ts = jsonObject.getLong("ts");
String logDate = simpleDateFormat.format(ts);
String lastViewDate = lastVisitDateState.value();
if (lastViewDate!=null&&lastViewDate.length()>0&&logDate.equals(lastViewDate)){
System.out.println("已访问:lastVisit:"+lastViewDate+"|| logDate:"+ logDate);
return false;
} else {
System.out.println("未访问:lastVisit:"+lastViewDate+"|| logDate:"+logDate);
lastVisitDateState.update(logDate);
return true;
}
}
}).uid("uvFilter");
SingleOutputStreamOperator dataJsonStringDstream =
filteredJsonObjDstream.map(jsonObj -> jsonObj.toJSONString());
dataJsonStringDstream.print(“uv”);