PyFlink快速上手 - 批/实时WordCount数据统计案例

我们将一起探索Apache Flink的Python API,也就是PyFlink,并通过一个批处理和实时WordCount的案例来深入了解其在大数据处理中的应用。在开始之前,我们需要确保已经正确地安装了PyFlink,以及相关的环境变量也已经配置完毕。

环境设置

1、搭建虚拟环境
到Miniconda官网下载适用于Linux的Python 3版本安装包,例如:

# 官网
https://docs.conda.io/en/latest/miniconda.html#installing
# 按照自己的系统来下载安装即可
[hadoop@node01 opt]$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
# 运行下载的脚本进行安装,按照提示操作即可,可以将Miniconda安装到默认位置,也可以自定义安装目录。
[hadoop@node01 opt]$ bash Miniconda3-latest-Linux-x86_64.sh

# 安装完成后,重新载入PATH环境变量
[hadoop@node01 opt]$ source /etc/profile

2、Miniconda3的使用

# 查看当前的conda环境
conda info --envs
# 创建新环境
conda create -n pyflink17 python=3.10
# 激活某个环境
conda activate pyflink17
# 删除环境
conda remove -n pyflink17 --all
# 安装包 
conda install numpy
# 更新包
conda update numpy
# 退出激活的虚拟环境
conda deactivate

3、安装pyflink
无论是Window、Mac、Linux都只需要在命令行中输入以下命令,就可以使用pip来安装PyFlink,目前pyflink支持Python 3.7, 3.8, 3.9 or 3.10。

# 官网
https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/dev/python/datastream_tutorial/
# 进入 pyflink17 虚拟环境,执行
python -m pip install apache-flink

Java 环境建议安装 java8或者java11,至此我们就可以开始编写Python代码了。

WordCount案例

WordCount 是一个经典的案例,它可以帮助我们理解如何使用 PyFlink 处理数据。我们的任务是统计文本中每个单词的实时出现次数。为了实现这个功能,我们需要对输入的数据进行切割、分组和计数。

1、导入必要的模块

from pyflink.common import Types
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode

2、创建 StreamExecutionEnvironment 执行环境

# 创建执行环境
env = StreamExecutionEnvironment.get_execution_environment()
# env.set_runtime_mode(RuntimeExecutionMode.BATCH)
env.set_parallelism(1)
# 定义输入数据源和输出结果
file_name = '/Users/oscar/data/word.txt'
# 读取数据:从文件中读取,一行一行的读取
data_source = env.read_text_file(file_name)

word.txt里的数据格式如下所示:

hello flink
hello spark
hello spark
hello python
hello flink
hello spark
hello flink
hello flink

3、切分

# 切分函数
def get_words(lines):
    yield from lines.split(' ')

data_source.flat_map(get_words)
# 从 flat_map() 的源码知道,要传入一个func函数,所以这里就是切割函数:get_words()
def flat_map(self,
             func: Union[Callable, FlatMapFunction],
             output_type: TypeInformation = None) -> 'DataStream':

切分后的结果是:

['hello', 'flink']
['hello', 'spark']
['hello', 'java']
['hello', 'python']
['hello', 'golang']
['hello', 'php']
['hello', 'mysql']
['hello', 'doris']

4、转换:(word, 1)

# 使用 lambda 匿名函数方式把格式转换成 (word, 1)
.map(lambda x: (x, 1), output_type=Types.TUPLE([Types.STRING(), Types.INT()]))
# Map 源码
def map(self, func: Union[Callable, MapFunction], output_type: TypeInformation = None) \
        -> 'DataStream':

转换后的结果如下所示:

(hello, 1)
(flink, 1)

4、分组
按照 key 分组,把key相同的分在同一组

# (flink, 1) 元组,x[0]取的值就是 flink
.key_by(lambda x: x[0])

分组后的结果

(flink,1)
(flink,1)
(flink,1)
(flink,1)

(hello,1)
(hello,1)
(hello,1)
(hello,1)
(hello,1)
(hello,1)
(hello,1)
(hello,1)

(spark,1)
(spark,1)
(spark,1)

(python,1)

5、分组内聚合
按照key把值累加起来就得到最后的结果

.reduce(lambda i, j: (i[0], i[1] + j[1]))

批处理案例

from pyflink.common import Types
from pyflink.datastream import StreamExecutionEnvironment


def get_flat_map(lines):
    r = lines.split(' ')
    yield from r


def word_count_batch_demo():
    """
    DataStream 实现 WordCount 有界流(读文件)
    :return:
    """
    # 1、创建执行环境
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_parallelism(1)
    # 2、从文件中读取数据
    file_name = '/Users/oscar/projects/big_data/flink_tutorial/data/word.txt'
    data_source = env.read_text_file(file_path=file_name)

    # 3、数据处理
    ds = data_source\
        .flat_map(get_flat_map)\
        .map(lambda x: (x, 1), output_type=Types.TUPLE([Types.STRING(), Types.INT()]))\
        .key_by(lambda x: x[0]).sum(1)
    # 4、输出
    ds.print()
    # 5、执行
    env.execute()


if __name__ == '__main__':
    word_count_batch_demo()

流处理案例

#!/usr/bin/python
# -*- coding:UTF-8 -*-
from pyflink.common import SimpleStringSchema, WatermarkStrategy
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.datastream.connectors.kafka import KafkaSource, KafkaOffsetsInitializer


def word_count_unbounded_demo():
    """
    DataStream 实现 WordCount 无界流(读kafka)
    :return:
    """
    # 1、创建执行环境
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_parallelism(1)

    # 2、读取数据:kafka
    brokers = "node01:9092"
    source = KafkaSource.builder() \
        .set_bootstrap_servers(brokers) \
        .set_topics("flink_tutorial") \
        .set_group_id("flink-tutorial") \
        .set_starting_offsets(KafkaOffsetsInitializer.latest()) \
        .set_value_only_deserializer(SimpleStringSchema()) \
        .build()

    ds = env.from_source(source, WatermarkStrategy.no_watermarks(), "Kafka Source")
    # 3、数据处理
    result = ds.flat_map(lambda x: x.split(' ')).map(lambda x: (x, 1)).key_by(lambda x: x[0]).sum(1)
    # 4、输出
    result.print()
    # 5、执行
    env.execute()


if __name__ == '__main__':
    word_count_unbounded_demo()

通过今天的课程,我们学习了如何使用PyFlink的DataStream API实现实时WordCount。希望这个案例能够帮助大家更好地理解PyFlink在实时数据流处理中的应用。如果你想了解更多关于PyFlink的内容,可以继续观看后面的课程,或者参考我们在视频描述中提供的代码和学习资源链接。

详细资料关注公众号
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值