我有一个帐户列表,对刻度执行哈希联接,并返回带有刻度数据的帐户。但是在hashjoin之后,我有了drainTo lListJet
,然后用DistributedStream
读取并返回了它。
public List<Account> populateTicksInAccounts(List<Account> accounts) {
...
...
Pipeline p = Pipeline.create();
BatchSource<Tick> ticksSource = Sources.list(TICKS_LIST_NAME);
BatchSource<Account> accountSource = Sources.fromProcessor(AccountProcessor.of(accounts));
p.drawFrom(ticksSource)
.hashJoin(p.drawFrom(accountSource), JoinClause.joinMapEntries(Tick::getTicker), accountMapper())
.drainTo(Sinks.list(TEMP_LIST));
jet.newJob(p).join();
IListJet<Account> list = jet.getList(TEMP_LIST);
return DistributedStream.fromList(list).collect(DistributedCollectors.toIList());
}
执行哈希联接后,是否可以从drainTo
到Java List
而不是lListJet
?
可能出现以下类似情况?
IListJet<Account> accountWithTicks = new ArrayList<>();
p.drawFrom(ticksSource)
.hashJoin(p.drawFrom(accountSource), JoinClause.joinMapEntries(Tick::getTicker), accountMapper())
.drainTo(<CustomSinkProcessor(accountWithTicks)>);
return accountWithTicks;
CustomSinkProcessor中的哪个位置将获取空的Java列表并返回帐户?
答案 0 :(得分:2)
请记住,您提交给Jet执行的代码是在您提交代码的过程之外运行的。从理论上讲,可以提供您所需要的API,但实际上,它只需要执行一些技巧就可以在集群的每个成员上运行代码,让所有成员将其结果发送到一个位置并填充列出一份清单给您。这将违反分布式计算的本质。
如果您认为这有助于提高代码的可读性,则可以编写如下的辅助方法:
public <T, R> List<R> drainToList(GeneralStage<T> stage) {
String tmpListName = randomListName();
SinkStage sinkStage = stage.drainTo(Sinks.list(tmpListName));
IListJet<R> tmpList = jet.getList(tmpListName);
try {
jet.newJob(sinkStage.getPipeline()).join();
return new ArrayList<>(tmpList);
} finally {
tmpList.destroy();
}
}
特别注意该行
return new ArrayList<>(tmpList);
与您的
相对IListJet<Account> list = jet.getList(TEMP_LIST);
return DistributedStream.fromList(list).collect(DistributedCollectors.toIList());
这只是将一个Hazelcast列表复制到另一个列表,并返回其句柄。现在,您在Jet群集中泄漏了两个列表。当您停止使用它们时,它们不会自动消失。
即使我提供的代码仍然可能泄漏。运行它的JVM进程可能会在Job.join()
期间死亡,而不会到达finally
。然后,临时列表仍然存在。
答案 1 :(得分:0)
不,不是,因为Jet具有分布式特性。该接收器将在多个并行处理器(工作人员)中执行。它不能添加到普通Collection
中。接收器必须能够在多个群集成员上插入项目。