为了解决公司模型&特征迭代的系统性问题,提升算法开发与迭代效率,部门立项了特征平台项目。特征平台旨在解决数据存储分散、口径重复、提取复杂、链路过长等问题,在大数据与算法间架起科学桥梁,提供强有力的样本及特征数据支撑。平台从 Hive 、Hbase 结合关系型数据库等大数据 ODS ( Operational Data store ) 层、DWD、DWS层进行快速的数据 ETL ,将数据抽取到特征平台进行管理,并统一了数据出口,供数据科学家、数据工程师、机器学习工程师做算法模型的数据测试、训练、推理及其他数据应用。
本篇文章主要分享特征平台 flink on K8s 的部署实践,文章主要分以下几个方面进行介绍。首先本文对 K8s 基本概念及 Flink 任务执行图进行简要介绍,接着文章对比了现有的几种 Flink on K8s 部署方式,
为什么flink 要基于K8s做部署?
主要有以下几个优势:
Kubernetes 为您提供了一个可弹性运行分布式系统的框架。Kubernetes 会满足您的扩展要求、故障转移、部署模式等,Kubernetes 项目的本质,是为用户提供一个具有普遍意义的容器编排工具。
基本组件
Pod: K8s 的原子调度单位,是一个或多个 Container 的组合,Container 共享同一个网络、存储。
Deployment: 对一组相同 Pod 的高级抽象,可以自动重启恢复,保障高可用。
Service: 定义服务的访问入口,通过 Label Selector 绑定后端 Pod 副本集。如果 K8s 内部有一个服务,需要在外部进行访问,此时可以通过 Service 用 LoadBalancer 或者 NodePort 的方式将其暴露出去。如果不希望或不需要对外暴露服务,可以把 Service 设置为 Cluster IP 或者是 None 模式。
ConfigMap: K-V 结构数据,通常的用法是将 ConfigMap 挂载到 Pod ,作为配置文件提供 Pod 里新的进程使用。
Stateful - 有状态应用部署
Job与Cronjob-离线业务
Apache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算
Flink 架构图跟常见的大数据组建类似,都是采用主流的主从架构,一个 JobManager,多个 TaskManager,并可对JobManager进行HA部署。
Flink 代码从提交到真正执行,需要经过几次 Graph 图的转换,过程如下:StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图
多个 Job 提交共享同一个 JobManager,Flink Cluster的实例已经被创建,并被所有Job共享的。Flink任务由Client提交,client做一些预备工作, 并在 Flink Client 上生成 JobGraph,这种方式的缺点是:一个Job导致的JobManager失败可能会导致所有的Job失败。
为每次 Job 提交启动专用 JM,JM 将只执行此作业,然后退出。在 Flink Client 上生成 JobGraph,
可以理解为 Client 模式的Application Mode,这种模式充分利用资源管理框架的优势,例如Yarn,Mesos等,达到更强的资源隔离性,flink应用之间不会相互影响。一个Job一个Cluster实例。
Flink提交的程序,被当做集群内部Application,不再需要Client端做繁重的准备工作例如执行main函数
数,生成JobGraph,下载依赖并分发到各个节点等),main函数被提交给JobManager执行。
一个Application一个Cluster实例。
通过Flink standalone和 native 模式的分析,standalone需要配合 kubectl + yaml 部署,Flink 无法感知 K8s 集群的存在,资源被动申请,而Native部署仅使用 flink 客户端 kubernetes-session.sh or flink run 部署,Flink 主动与 K8s 申请资源,而成为最佳的部署方式,另外因为任务主要是离线批处理,每个appllication可以包含多个job 比较适合业务需求。
这边只演示 k8s native部署模式,Standalone 部署需要手动去提前创建 ConfigMap、Service、JobManager Deployment、TaskManager Deployment 等比较麻烦。
K8s >= 1.9 or Minikube
KubeConfig (可以查看、创建、删除 pods 和 services)
启用 Kubernetes DNS
具有 RBAC 权限的 Service Account 可以创建、删除 pods
FROM flink:1.12.1-scala_2.11-java8
# 安装 python3 and pip3 及需要的debug工具
RUN apt-get update -y && \
apt-get install -y python3.7 python3-pip python3.7-dev \
&& rm -rf /var/lib/apt/lists/*
RUN rm -rf /usr/bin/python
RUN ln -s /usr/bin/python3 /usr/bin/python
# 安装 Python Flink
RUN pip3 install apache-flink==1.12.1
# 如果有引用第三方 Python 依赖库, 可以在构建镜像时安装上这些依赖
#COPY /path/to/requirements.txt /opt/requirements.txt
#RUN pip3 install -r requirements.txt
# 如果有引用第三方 Java 依赖, 也可以在构建镜像时加入到 ${FLINK_HOME}/usrlib 目录下
RUN mkdir -p $FLINK_HOME/usrlib
COPY /path/of/external/jar/dependencies $FLINK_HOME/usrlib/
COPY /path/of/python/codes /opt/python_codes
Docker build 部署需要的 pyflink 镜像
Flink image -> PyFlink image -> PyFlink App image
操作方式:flink application on k8s native模式非常简单,直接一条命令搞定了Application模式的运行提交 Job
./bin/flink run-application -p 2 -t kubernetes-application \
-Dkubernetes.cluster-id=app-cluster \
-Dtaskmanager.memory.process.size=4096m \
-Dkubernetes.taskmanager.cpu=2 \
-Dtaskmanager.numberOfTaskSlots=4 \
-Dkubernetes.container.image=demo-pyflink-app:1.12.1 \
-pyfs /opt/python_codes \
-pym new_word_count
启动流程图:
Flink应用编写流程如下图:
这块产品主要是采用flink sql去完成 功能,运行模式比较统一,注册source、sink、 执行sq,因此可以采用同一份代码,提供给用户sql编辑框或者用户界面上选择所需要读取的库表字段后端组合成sql语句,最终统一任务运行形成一个离线计算平台,通过动态传递参数进行flink应用的提交和执行。
后端在数据库中配置好source和sink的类型以及连接信息暴露给前端。
前端去选择对应的数据源比如说mysql、hive,然后选择所需要读取的库表,展示table schema ,用户 可以选择需要读取的库表字段。同时选择需要存储的数据汇如说elasticsearch、mysql等,获取这些动态参数后,通过k8s java client 去创建 job去提交flink应用。
flink应用启动时获取这些db、库表信息、库表字段后传递给FLink程序,flink程序构造成flinksql去执行应用,具体不在详细执行。
本文为大家分享 flink on K8s 部署的实践经验,简要介绍了 K8s 基本概念与 Flink 执行图,对 Flink 不同的部署方式进行了对比,并使用具体 demo 分析了 Pyflink on K8s 部署的过程中组件间的协调过程,协助大家在上手使用的同时了解底层执行过程。
[1] Apache Flink 1.12 Documentation: Deployment
[2] Apache Flink 1.12 Documentation: Kubernetes Setup
[3] Apache Flink 1.12 Documentation: Native Kubernetes
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。