Apache flink RichFlatMap中带和不带keyBy的状态管理

Apache flink RichFlatMap中带和不带keyBy的状态管理,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我有这样一个流应用程序: DataStream stream1=源 .keyBy(“客户”) .flatMap(新的MyFlatMapFunction()) .名称(“Stream1”); //... 公共类MyFlatMapFunction扩展了RichFlatMapFunction{ 私人暂时价值状态价值状态; @凌驾 公共无效打开(配置参数) { StateTtlConfig ttlConfig=StateTtlConfig .新造船工(时间.分钟(12)) .setUpdateType(

我有这样一个流应用程序:

DataStream stream1=源
.keyBy(“客户”)
.flatMap(新的MyFlatMapFunction())
.名称(“Stream1”);
//...
公共类MyFlatMapFunction扩展了RichFlatMapFunction{
私人暂时价值状态价值状态;
@凌驾
公共无效打开(配置参数)
{
StateTtlConfig ttlConfig=StateTtlConfig
.新造船工(时间.分钟(12))
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.setStateVisibility(StateTtlConfig.StateVisibility.ReturnExpireDefNotCleanedUp).cleanupInBackground()
.build();
ValueStateDescriptor ValueStateDescriptor=新的ValueStateDescriptor(
“价值状态”,
类型(布尔型);
ValueStateDescriptor.enableTimeToLive(ttlConfig);
valueState=getRuntimeContext().getState(valueState);
}
@凌驾
public void flatMap(MyObject MyObject,收集器)引发异常
{
//从值状态获取值,检查它是否与某个对象匹配
//如果匹配某个条件,则选择collector.collect(myObject)
//更新每个myObject的状态
}
}
不是:3台机器上有3名工人,并行度为16。总并行度为48

在实现此代码时,我始终假设“如果ip地址1.2.3.4与条件匹配,则来自同一ip地址1.2.3.4的后续请求始终与条件匹配,直到状态被清除”。这句话对吗

从flink docs中我知道,如果ip地址1.2.3.4进入机器1(通过生成clientip的哈希值),那么来自ip地址1.2.3.4的所有请求都会进入机器1

open()
方法在taskmanager jvm中调用一次。因此,flink创建了48个flatMapOperation实例(48个实例中的1-15个驻留在machine1中,48个实例中的16-32个驻留在machine2中,48个实例中的33-48个驻留在machine3中),每个flatMapInstance都将运行open方法。这意味着开放式方法要运行48次

最后,所有48个实例都访问相同的状态,但值不同(因为状态是本地的)。我的意思是,一部分实例组(比如说机器1上的16个实例)将获得相同的状态值

最后,如果FlatMap之前没有keyBy,那么来自ip地址1.2.3.4的请求可以以随机方式进入machine1、machine2或machine3

  • 由于执行了
    keyBy(“clientip”)
    ,因此该字段具有相同值的所有记录将由相同的
    MyFlatMapFunction
    子任务处理。因此,所有记录的集合被划分为48个子任务,并且假设IP地址的计数均匀分布,每个子任务将获得大约所有记录的1/48
  • 是的,将有48个实例化的
    MyFlatMapFunction
    实例,从而有48个调用
    open()
  • 所有48个实例都访问相同的状态
    。不,状态是每个唯一键,因此状态是按键值在48个子任务之间划分的
  • 如果没有
    keyBy()
    ,则
    MyFlatMapFunction
    操作符的每个子任务都将从源中获取分区中的任何数据。这取决于您的数据源,例如,如果您正在阅读一个Kafka主题,而该主题有48个分区,则Kafka分区与
    MyFlatMapFunction
    子任务之间存在1:1的映射。如果您的Kafka分区少于48个,则您的一些
    MyFlatMapFunction
    子任务将无法获取任何数据。如果要将传入记录重新分发到所有子任务,则可以执行
    rebalance()
    。但是请注意,您将无法维护每个IP地址的状态