摘要: 我正在尝试利用喷射管道进行高负载聚合。我发现绝大多数的运行时是通过通过字节流(它们实现DataSerializable)对地图记录进行序列化和反序列化来解决的。我认为将聚合操作分配给节点的目的在于它们可以直接访问堆中的分布式成员。
管道:
pipeline.drawFrom(source)
.aggregate(aggregate)
.drainTo(sink);
来源:
Sources.<Key, Record>map("mapname")
汇总:
AggregateOperation1<Entry<Key, Record>, T, Result>=
AggregateOperation
.withCreate(() -> {
Accumulator a = new Accumulator(this);
a.initialize();
return a;
}).<Entry<Key, Record>>andAccumulate(
(acc, row) -> acc.apply(row))
.andCombine(
(left, right) -> left.combine(right))
.andFinish(acc -> acc.finish());
我发现执行管道作业时,源正在读取/写入地图中的记录:
Record.readData
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.readInternal(DataSerializableSerializer.java:158)
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:105)
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:50)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:191)
at com.hazelcast.query.impl.CachedQueryEntry.getValue(CachedQueryEntry.java:75)
at Accumulator.apply(Accumulator.java:102)
触发此操作的Accumulator.apply中的代码(来自“ andAccumulate”步骤)看起来像
private void apply(Entry<IntArr, Record> entry) {
Record record = entry.getValue();
...
}
我如何创建一个Jet地图数据源,该地图数据源将地图本地条目或值提供给AggregateOperation,从而在每个节点和线程上累积调用而无需调用序列化?我在做一些特定的事情来使其表现为这种方式吗? 我相信群集已设置为使用备份记录进行聚合;那会导致这个吗? (我尚未确认每条记录都在发生这种情况)
编辑: 这是我当前的MapConfig:
MapConfig mapConfig = new MapConfig(mapName)
.setStatisticsEnabled(true)
.setReadBackupData(true)
.setInMemoryFormat(InMemoryFormat.OBJECT);
据http://docs.hazelcast.org/docs/3.10.4/manual/html-single/index.html#setting-in-memory-format所知,InMemoryFormat.OBJECT应该指示IMap将值保持为目标(反序列化)形式。
答案 0 :(得分:1)
Hazelcast IMap以序列化形式存储数据。从源头获取它时,您将得到一个Map.Entry
实例,该实例将在请求时延迟反序列化其键/值。这发生在您的entry.getValue()
通话中。
您的管道要求进行数据聚合:输出是一个反映所有输入数据的项目。为了获得该结果,Jet必须将所有部分结果发送到单个成员,在该成员中,它调用您的Accumulator.combine
方法来合并它们。与上述步骤相比,此步骤的服务/处理效果可以忽略不计。