我正在尝试使用Python API进行流式传输在Flink上实现Kmeans Cluctering算法。我正在根据第0个索引进行key_by
,然后尝试在每个组上reduce()
进行计数汇总。
class CentroidAccumulator(ReduceFunction):
def reduce(self, val1, val2):
id1, point1, count1 = val1
id2, point2, count2 = val2
return (id1, point1.add(point2), count1+count2)
class Selector(KeySelector):
def getKey(self, value):
return value[0]
nearest_points = points \
.map(SelectNearestPoint(centroids)) \
.key_by(Selector()).reduce(CentroidAccumulator())
nearest_points.write_as_text("output.txt")
预期结果:
(1, <tuple>, count)
(2, <tuple>, count)
(3, <tuple>, count)
(4, <tuple>, count)
实际结果:
我将所有迭代的输出写入文件中(我要测试的样本中有40个点,因此输出有40行,就像这样)
(1, <kmeans_clustering.Point instance at 0x2>, 1)
(3, <kmeans_clustering.Point instance at 0x3>, 1)
(2, <kmeans_clustering.Point instance at 0x4>, 1)
(2, <kmeans_clustering.Point instance at 0x5>, 2)
.
.
.
(2, <kmeans_clustering.Point instance at 0x20>, 13)
(2, <kmeans_clustering.Point instance at 0x21>, 14)
(1, <kmeans_clustering.Point instance at 0x22>, 10)
(4, <kmeans_clustering.Point instance at 0x23>, 4)
(2, <kmeans_clustering.Point instance at 0x24>, 15)
(2, <kmeans_clustering.Point instance at 0x25>, 16)
(1, <kmeans_clustering.Point instance at 0x26>, 11)
(4, <kmeans_clustering.Point instance at 0x27>, 5)
(2, <kmeans_clustering.Point instance at 0x28>, 17)
(2, <kmeans_clustering.Point instance at 0x29>, 18)
问题是好的还原,但是我只想获取每个组的reduce转换的最后一个值(这是我应该理解的reduce的工作方式)。我在做什么错了?
答案 0 :(得分:1)
您没有做错任何事;这是流式缩减功能的预期行为。从概念上讲,数据流是无穷无尽的数据流-因此“等到最后”才能产生结果没有意义。流式传输程序的标准行为是为每个事件生成结果。
当然,这可能会带来一些不便。如果您只想查看最终结果,则必须使用某种方法来指示结束。使用批处理程序,这自然而然。在流应用程序中,有限的数据源会发送带有值MAX_WATERMARK的水印,该水印可用于检测输入是否已到达末尾-您可以使用事件时间计时器将其捕获到ProcessFunction中,但这是一个复杂的解决方案。您还可以使用Windows来实现某种解决方法。