Apache flink KeyBy并不是为不同的关键点创建不同的关键点流

Apache flink KeyBy并不是为不同的关键点创建不同的关键点流,apache-flink,flink-streaming,Apache Flink,Flink Streaming,我正在读取一个简单的JSON字符串作为输入,并根据两个字段a和B对流进行键控。但是KeyBy正在为B的不同值生成相同的键控流,但用于a和B的特定组合 输入: { "A": "352580084349898", "B": "1546559127", "C": "A" } 这是我的Flink代码的核心逻辑: DataStream<GenericDataObject> genericDataObjectDataStream = inputStream

我正在读取一个简单的JSON字符串作为输入,并根据两个字段
a
B
对流进行键控。但是KeyBy正在为
B
的不同值生成相同的键控流,但用于
a
B
的特定组合

输入:

{
    "A": "352580084349898",
    "B": "1546559127",
    "C": "A"
}
这是我的Flink代码的核心逻辑:

DataStream<GenericDataObject> genericDataObjectDataStream = inputStream
            .map(new MapFunction<String, GenericDataObject>() {
                @Override
                public GenericDataObject map(String s) throws Exception {
                    JSONObject jsonObject = new JSONObject(s);
                    GenericDataObject genericDataObject = new GenericDataObject();
                    genericDataObject.setA(jsonObject.getString("A"));
                    genericDataObject.setB(jsonObject.getString("B"));
                    genericDataObject.setC(jsonObject.getString("C"));
                    return genericDataObject;
                }
            });
DataStream<GenericDataObject> testStream = genericDataObjectDataStream
            .keyBy("A", "B")
            .map(new MapFunction<GenericDataObject, GenericDataObject>() {
                @Override
                public GenericDataObject map(GenericDataObject genericDataObject) throws Exception {
                    return genericDataObject;
                }
            });
testStream.print();

请注意第1行和第2行。即使它们具有不同的B值,它们也被放在同一个键控流(5)中。我一定是做错了什么,有人能给我指出正确的方向吗

首先,你没有做错什么

为什么它们在同一个子任务中

假设您有数千个密钥,ApacheFlink不可能为每个密钥创建数千个线程。因此,必须有另一种机制来确保在一个线程中单独处理一组密钥

因此,在ApacheFlink中,每个子任务都有自己的密钥组,具有相同密钥组索引的不同密钥将在同一个子任务中处理。一个子任务通常处理几个具有单独键控状态的键,以保持不同键的状态分开

keyBy并不意味着将不同的键分配给不同的子任务(或分区),而是将具有相同键的所有记录分配给相同的子任务。因此,您只能通过编程KeySelector实例来确定不同的键是否在同一组中

有关更多详细信息,您可以在ApacheFlink的官方网站上查看本文


感谢您的回复。如何控制运算符是否在同一子任务中?我似乎了解了密钥和密钥组的概念,但似乎不太明白如何应用它们来解决我的问题。另外,奇怪的是,这个问题只出现在
B
的一组特定值上,即
1546559224
1546559127
。对于所有其他值,我看到生成了不同的键控流。这取决于。因为Flink不知道它将接收多少个密钥,所以它只是根据并行性设置了几个组。因此,您只能通过编程Keyselector实例来确定两个不同的键是否在同一个键组中。但是,根据键控流的定义,不应该为不同的流分配不同的键吗?即使并行度为1,是否有办法强制执行此行为?否,
keyBy
的约定不是将不同的键分配给不同的子任务(或分区),而是将具有相同键的所有记录分配给相同的子任务。因此,子任务通常处理许多不同的键。Flink使用“已设置关键帧的状态”将不同关键帧的状态分开@bupt_ljy,你想用评论中的信息扩展你的答案吗?谢谢@FabianHueske感谢您对keyBy合同的明确解释!
5> GenericDataObject{A='352580084349898', B='1546559224', C='A'}
5> GenericDataObject{A='352580084349898', B='1546559127', C='A'}
4> GenericDataObject{A='352580084349898', B='1546559234', C='A'}
3> GenericDataObject{A='352580084349898', B='1546559254', C='A'}