我想实现JOIN语义,并尝试Trident拓扑中的join方法。 我发现连接是在批次之间进行的。 如果两个流之间的连接具有数百万个元组,那么它是否必须在一个批次中?
在genderSpout中,每个批次都有3个元组,因此Spout将发出2个批次 ageSpout,每个批次有5个元组,因此Spout只会发出1个批次
我使用JoinType进行LEFT OUTER JOIN
测试代码的输出是:
1 man 15
2 woman 18
1 man 19
3 woman NULL
4 man NULL
1 woman NULL
从输出中,我发现前四个结果是在genderSpout的第一批和ageSpout的第一批之间加入。 最后两个结果是来自genderSpout的第二批与来自ageSpout的空批处理之间的连接。 因此JOIN语义的结果不正确,因为我想要的genderSpout LEFT JOIN ageSpout结果是:
1 man 15
1 man 19
2 woman 18
3 woman NULL
4 man 20
1 woman 15
1 woman 19
所以我的问题是:如果JOIN的双方(Spout)有数百万个元组,我应该将它们放在一个批处理中以获得正确的结果吗?
或者我走的路是错的,请你告诉我如何才能获得OUTER JOIN语义的正确结果?
测试代码如下:
public static void main(String[] args) throws Exception{
Fields genderField = new Field("id", "gender");
FixedBatchSpout genderSpout = new FixedBatchSpout(genderField, 3,
new Values("1", "man"),
new Values("2", "woman"),
new Values("3", "woman"),
new Values("4", "man"),
new Values("1", "woman"));
genderSpout.setCycle(false);
Fields ageField = new Field("id2", "age");
FiexedBatchSpout ageSpout = new FixedBatchSpout(new Fields("id2", "age"), 5,
new Values("1", "15"),
new Values("4", "20"),
new Values("2", "18"),
new Values("1", "19"));
ageSpout.setCycle(false);
List<Stream> allStreams = new ArrayList<Stream>();
List<Fields> allFields = new ArrayList<Fields>();
List<Fields> joinFileds = new ArrayList<Fields>();
List<JoinType> joinTypes = new ArrayList<JoinType>();
TridentTopology topology = new TridentTopology();
Stream genderStream = topology.newStream("genderIn", genderSpout);
Stream ageStream = topology.newStream("ageIn", ageSpout);
allStreams.add(genderStream);
allStreams.add(ageStream);
allFields.add(genderFields);
allFields.add(ageFields);
joinFields.add(new Field("id")));
joinFields.add(new Field("id2"));
joinTypes.add(JoinType.INNER);
joinTypes.add(JoinType.OUTER);
topology.join(allStreams, joinFields, new Filds("id", "gender", "age"), joinTypes)
LocalCluster cluster = new LocalCluster();
Config config = new Config()
config.setDebug(false);
config.setMaxSpoutPending(3);
cluster.submitTopology("trident-join-test", config, topology.build());
Thread.sleep(3000);
cluster.shutdown();
}
答案 0 :(得分:1)
我在https://groups.google.com/forum/?fromgroups=#!forum/storm-user中提出了同样的问题: https://groups.google.com/forum/?fromgroups=#!topic/storm-user/7fxAVgF2_0M
杰森杰克逊的回答是: TridentTopology.join不会跨批处理连接。您可以使用stateQuery和其中一个partitionPersist来跨批处理进行流连接。
希望有用