0基础学习PyFlink——个数滚动窗口(Tumbling Count Windows)

大纲

  • [Tumbling Count Windows](#Tumbling Count Windows)
    • map
    • reduce
      • [Window Size为2](#Window Size为2)
      • [Window Size为3](#Window Size为3)
      • [Window Size为4](#Window Size为4)
      • [Window Size为5](#Window Size为5)
      • [Window Size为6](#Window Size为6)
  • 完整代码
  • 参考资料

之前的案例中,我们的Source都是确定内容的数据。而Flink是可以处理流式(Streaming)数据的,就是数据会源源不断输入。

对于这种数据,我们称之为无界流,即没有"终止的界限"。但是程序在底层一定不能等着无止境的数据都传递结束再处理,因为"无止境"就意味着"终止的界限"触发计算的条件是不存在的。那么我们可以人为的给它设置一个"界",这就是我们本节介绍的窗口。

Tumbling Count Windows

Tumbling Count Windows是指按元素个数计数的滚动窗口。

滚动窗口是指没有元素重叠的窗口 ,比如下面图是个数为2的窗口。(元素重叠的窗口我们会在《0基础学习PyFlink------个数滑动窗口(Sliding Count Windows)》介绍)

个数为3的窗口

我们用代码探索下这个概念

map

python 复制代码
word_count_data = [
    ("A",2),("A",1),
    ("B",3),("B",1),("B",2),
    ("C",3),("C",1),("C",4),("C",2),
    ("D",3),("D",1),("D",4),("D",2),("D",5),
    ("E",3),("E",1),("E",4),("E",2),("E",6),("E",5)]

def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    # write all the data to one file
    env.set_parallelism(1)

    source_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    # define the source
    # mappging
    source = env.from_collection(word_count_data, source_type_info)
    # source.print()

    # keying
    keyed=source.key_by(lambda i: i[0]) 

这段代码构造了一个KeyedStream,用于存储word_count_data中的数据。

我们并没有让Source是流的形式,是因为为了降低例子复杂度。但是我们将runntime mode设置为流(STREAMING)模式。

reduce

我们需要定义一个Reduce类,用于对元组中的数据进行计算。这个类需要继承于WindowFunction,并实现相应方法(本例中是apply)。

apply会计算一个相同key的元素个数。比如key是"E"的元组个数是6。

python 复制代码
class SumWindowFunction(WindowFunction[tuple, tuple, str, CountWindow]):
    def apply(self, key: str, window: CountWindow, inputs: Iterable[tuple]):
        return [(key,  len([e for e in inputs]))]

Window Size为2

python 复制代码
    # reducing
    reduced=keyed.count_window(2) \
                .apply(SumWindowFunction(),
                       Types.TUPLE([Types.STRING(), Types.INT()]))

    # # define the sink
    reduced.print()

    # submit for execution
    env.execute()

(A,2)

(B,2)

(C,2)

(C,2)

(D,2)

(D,2)

(E,2)

(E,2)

(E,2)

  • A的个数是2是因为A的确只有两个元组,而一个Size为2的Window正好承载了这两个元素。于是有(A,2)这个结果;
  • B的个数是3。但是会产生两个窗口,第一个窗口承载了前两个元素,第二个窗口当前只有一个元素。于是第一个窗口进行了Reduce计算,得出一个(B,2);第二个窗口还没进行reduce计算,就没有展现出结果;
  • C有4个,正好可以被2个窗口承载。这样我们就看到2个(C,2)。
  • D有5个,情况和B类似。它被分成了3个窗口,只有2个窗口满足个数条件,于是就输出2个(D,2);最后一个窗口因为元素不够,就没尽兴reduce计算了。
  • E有6个,正好被3个窗口承载。我们就看到3个(E,2)。

Window Size为3

python 复制代码
    # reducing
    reduced=keyed.count_window(3) \
                .apply(SumWindowFunction(),
                       Types.TUPLE([Types.STRING(), Types.INT()]))

(B,3)

(C,3)

(D,3)

(E,3)

(E,3)

Window Size为4

python 复制代码
    # reducing
    reduced=keyed.count_window(4) \
                .apply(SumWindowFunction(),
                       Types.TUPLE([Types.STRING(), Types.INT()]))

(C,4)

(D,4)

(E,4)

Window Size为5

python 复制代码
    # reducing
    reduced=keyed.count_window(5) \
                .apply(SumWindowFunction(),
                       Types.TUPLE([Types.STRING(), Types.INT()]))

(D,5)

(E,5)

Window Size为6

python 复制代码
    # reducing
    reduced=keyed.count_window(6) \
                .apply(SumWindowFunction(),
                       Types.TUPLE([Types.STRING(), Types.INT()]))

(E,6)

完整代码

python 复制代码
from typing import Iterable

from pyflink.common import Types
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import CountWindow

class SumWindowFunction(WindowFunction[tuple, tuple, str, CountWindow]):
    def apply(self, key: str, window: CountWindow, inputs: Iterable[tuple]):
        return [(key,  len([e for e in inputs]))]


word_count_data = [
    ("A",2),("A",1),
    ("B",3),("B",1),("B",2),
    ("C",3),("C",1),("C",4),("C",2),
    ("D",3),("D",1),("D",4),("D",2),("D",5),
    ("E",3),("E",1),("E",4),("E",2),("E",6),("E",5)]

def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    # write all the data to one file
    env.set_parallelism(1)

    source_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    # define the source
    # mappging
    source = env.from_collection(word_count_data, source_type_info)
    # source.print()

    # keying
    keyed=source.key_by(lambda i: i[0]) 
    
    # reducing
    reduced=keyed.count_window(2) \
                .apply(SumWindowFunction(),
                       Types.TUPLE([Types.STRING(), Types.INT()]))

    # # define the sink
    reduced.print()

    # submit for execution
    env.execute()

if __name__ == '__main__':
    word_count()

参考资料

相关推荐
计算机编程-吉哥5 分钟前
计算机毕业设计 基于Python的社交音乐分享平台的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
python·django·毕业设计·课程设计·毕业论文·计算机毕业设计选题·音乐分享平台
shinelord明12 分钟前
【Python】Python知识总结浅析
开发语言·人工智能·python
雷神乐乐43 分钟前
Python常用函数
开发语言·python
雪碧没有冰块1 小时前
Flink源码剖析
大数据·flink
model20052 小时前
android + tflite 分类APP开发-1
python·tflite·model maker
kkivivu2 小时前
家庭用超声波清洗机好用吗?推荐四款性能绝佳的超声波清洗机!
大数据
感谢地心引力2 小时前
【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)
c++·windows·python·qt·visual studio
大G哥3 小时前
ELK日志收集之ES的DSL查询语句
大数据·elk·elasticsearch·搜索引擎·jenkins
或许,这就是梦想吧!3 小时前
## jupyter_server
ide·python·jupyter
Bruce_Liuxiaowei3 小时前
Python小示例——质地不均匀的硬币概率统计
开发语言·python·概率统计