简介:面向需要在 CDH6.3.2 大数据平台上集成 Flink 1.16.2 的运维与开发人员,这份资源把离线安装所需的配套包一次性备齐,省去自行编译打包 CSD 与 parcel 的繁琐环节,适合有一定 Cloudera 集群管理经验、希望快速完成 Flink on YARN 部署的中高级用户。压缩包共 7 个文件,约 518MB,包含 parcel 与 sha 校验文件、CSD 描述用的 jar 与 json 清单,以及 commons-cli、flink-shaded-hadoop-3-uber 等依赖 jar,覆盖从分发、校验到服务描述与依赖补齐的完整链路,解压后按目录对应放置即可。已有 974 人学习下载,说明该组合在实际集群环境中具备一定通用性。借助这份资源,读者可直接获得与 CDH6.3.2 版本匹配的 Flink 1.16.2 安装包,避免版本错配导致的类冲突与启动失败,同时保留校验文件便于验证包完整性,配合公开部署教程能更快跑通集群集成流程。
1. 从一次 Parcel 分发失败说起:Flink 1.16.2 装进 CDH 6.3.2 到底难在哪
上周帮一个数据平台同事处理集群扩容,新节点上 Flink 1.16.2 的 Parcel 分发卡在 87% 不动,Cloudera Manager 里显示激活失败,日志翻出来是校验和不匹配。这套组合——CDH 6.3.2 配 Flink 1.16.2——在不少存量 Hadoop 集群里都能见到,CDH 自带的是 Flink 1.9,想用 1.16 的流批一体和新 SQL 特性,就得自己打 Parcel 塞进去。装不好不是跑不起来那么简单,而是 Parcel 激活失败会连带影响该主机上其他服务的健康状态,回滚也麻烦。这篇记录面向已经熟悉 CDH 基本操作、但第一次手工做第三方 Parcel 的开发者,从版本对齐、Parcel 制作、分发激活到验证排错,一步步走完。中间会踩到的坑,我尽量提前标出来。
2. 环境与版本对齐:先确认 CDH 6.3.2 的底子和 Flink 1.16.2 的依赖
动手做 Parcel 之前,最该花时间的是版本核对。CDH 6.3.2 对应的是 Hadoop 3.0.0、JDK 8,Cloudera Manager 的 Parcel 机制要求包名、目录结构、manifest 三者严格一致,任何一处对不上,分发阶段就会报错。Flink 1.16.2 官方二进制包默认面向 Hadoop 2 和 Hadoop 3 两个变体,选错变体在 CDH 6.3.2 上会出现类找不到或者 Shade 冲突。
2.1 确认集群侧的基础版本
先在 Cloudera Manager 主机上确认三件事:CM 版本、JDK 版本、Hadoop 版本。命令不复杂,但结果要记下来,后面打 Parcel 的目录名要用。
# 查看 Cloudera Manager Server 版本 rpm -qa | grep cloudera-manager-server # 查看集群节点 JDK 版本,CDH 6.3.2 官方支持 JDK 8 java -version 2>&1 | head -n 3 # 查看 Hadoop 版本,确认是 3.0.0 基线 hadoop version | head -n 2第一行确认 CM 是 6.3.2 系列,Parcel 的目录命名规则跟 CM 大版本绑定;第二行确认 JDK 是 1.8,Flink 1.16.2 虽然支持 JDK 11,但 CDH 6.3.2 的守护进程跑在 JDK 8 上,混用容易在提交作业时出现UnsupportedClassVersionError;第三行确认 Hadoop 是 3.0.0 基线,这决定了后面选 Flink 的hadoop3变体。我一般会把这三行输出贴到变更单里,出问题时能快速回溯。
2.2 Flink 1.16.2 的发行包选择
Flink 1.16.2 的下载页提供多个二进制包,跟 CDH 场景相关的是两个:flink-1.16.2-bin-scala_2.12.tgz和带 Hadoop 集成的flink-1.16.2-bin-scala_2.12-hadoop3.tgz。CDH 6.3.2 上必须选后者,因为前者不含 Hadoop 依赖的 Shade 包,提交到 YARN 时会报NoClassDefFoundError: org/apache/hadoop/conf/Configuration。
| 包名 | 适用场景 | CDH 6.3.2 是否可用 |
|---|---|---|
| flink-1.16.2-bin-scala_2.12.tgz | 本地 Standalone 或 Kubernetes | 否,缺 Hadoop 依赖 |
| flink-1.16.2-bin-scala_2.12-hadoop3.tgz | Hadoop 3.x 集群、YARN 提交 | 是,推荐 |
| flink-1.16.2-bin-scala_2.11.tgz | Scala 2.11 生态 | 可用但需自行处理 Scala 版本冲突 |
Scala 版本这块有个取舍:CDH 6.3.2 里 Spark 用的是 Scala 2.11,如果同一个集群还要跑 Flink 的 Scala API 作业,2.12 和 2.11 的包不能混装在同一目录。常见做法是 Flink 单独用 2.12,作业侧显式声明 Scala 版本,避免依赖传递时打架。这一步想清楚,后面打 Parcel 就不会反复返工。
2.3 Parcel 目录结构与命名规则
Cloudera 的 Parcel 本质是一个 tar 包加一个 manifest.json,目录名必须符合<产品>-<版本>-<发行标识>的格式。Flink 1.16.2 在 CDH 6.3.2 上的目录名我一般写成FLINK-1.16.2-1.16.2,前半段是产品名大写,后半段是版本号,发行标识用版本号本身,避免跟官方 CDH 组件混淆。
# 建立 Parcel 工作目录,结构必须与最终 tar 包内一致 mkdir -p /opt/parcel-build/FLINK-1.16.2-1.16.2 cd /opt/parcel-build # 解压官方二进制包到目标目录 tar -xzf flink-1.16.2-bin-scala_2.12-hadoop3.tgz \ -C FLINK-1.16.2-1.16.2 --strip-components=1 # 确认目录内是 bin/conf/lib 这一层,而不是多套一层 flink-1.16.2 ls FLINK-1.16.2-1.16.2--strip-components=1的作用是去掉 tar 包自带的顶层目录,让bin、conf、lib直接落在FLINK-1.16.2-1.16.2下。这一步如果漏了,Parcel 激活后 CM 找不到启动脚本,会报alternatives链接失败。第三行ls是自检,看到的是bin conf examples lib licenses opt plugins这一组才算对。目录结构错了,后面 manifest 写得再对也白搭,这是血泪经验。
3. 制作 Flink 1.16.2 Parcel:manifest 与校验和是两道硬门槛
Parcel 制作的核心就两个文件:tar.gz 包和同名的.parcel文件,外加一个manifest.json。Cloudera Manager 通过 manifest 里的哈希值校验包完整性,哈希对不上,分发阶段就会像开头那次一样卡住。这一章把打包、写 manifest、生成校验和三步拆开,每步都给可抄的命令。
3.1 打包前的配置预埋
在打包之前,先把 Flink 的conf/flink-conf.yaml按 CDH 环境预埋几个关键项,这样 Parcel 激活后不用每台机器手改。CDH 的配置目录在/etc/flink/conf,Parcel 激活时 CM 会做 alternatives 链接,所以包内配置只作为默认值。
# conf/flink-conf.yaml 关键预埋项 jobmanager.rpc.address: localhost # 由 CM 激活后覆盖为实际主机 jobmanager.memory.process.size: 1600m # 按节点内存调整,别照抄 taskmanager.memory.process.size: 1728m taskmanager.numberOfTaskSlots: 4 parallelism.default: 4 # 指向 CDH 的 Hadoop 配置目录,避免提交时找不到 core-site.xml env.hadoop.conf.dir: /etc/hadoop/conf # 历史服务器地址,验证阶段要用 jobmanager.archive.fs.dir: hdfs:///flink/completed-jobs historyserver.web.address: 0.0.0.0env.hadoop.conf.dir这一项是 CDH 场景的关键,Flink 在 YARN 上提交作业时需要读core-site.xml和yarn-site.xml,不指这个路径,作业会报Cannot locate Hadoop configuration。jobmanager.archive.fs.dir指向 HDFS,是为了后面验证历史服务器能读到已完成作业。内存参数别照抄,按实际节点规格改,process.size是进程总内存,不是堆内存,写小了 TaskManager 起不来。
3.2 生成 tar 包与 manifest.json
打包时要注意 tar 的属主和权限,CM 分发后以flink用户运行,包内文件属主写成 root 也能跑,但目录权限必须是 755,否则激活后启动脚本不可执行。
cd /opt/parcel-build # 打包,注意目录名与包名一致 tar -czf FLINK-1.16.2-1.16.2-el7.parcel FLINK-1.16.2-1.16.2 # 计算 SHA1,manifest 里要用 sha1sum FLINK-1.16.2-1.16.2-el7.parcelel7这个后缀是发行标识,跟集群操作系统对应,CentOS 7 写el7,其他系统按实际改。sha1sum的输出要原样填进 manifest,一个字符都不能差。manifest.json 的结构如下,字段名固定,不能自创。
{ "parcelName": "FLINK-1.16.2-1.16.2-el7.parcel", "components": [ { "name": "flink", "version": "1.16.2", "pkg_version": "1.16.2" } ], "hash": "把上一步 sha1sum 的结果填这里" }parcelName必须和实际文件名完全一致,包括.parcel后缀;components里的name用小写flink,CM 用它做组件识别;hash就是 SHA1 值。常见错误是 manifest 里写了.parcel但实际文件叫.parcel.tar.gz,或者 hash 用了 MD5,这两种都会在分发阶段报校验失败。写完用python -m json.tool manifest.json过一遍,确认 JSON 合法。
3.3 放入 CM 的 Parcel 仓库目录
Parcel 仓库目录由 CM 配置项parcel_repository_url决定,默认在/opt/cloudera/parcel-repo。把.parcel和manifest.json放进去,再生成一个.sha文件,CM 靠它做二次校验。
# 拷贝到仓库目录 cp FLINK-1.16.2-1.16.2-el7.parcel /opt/cloudera/parcel-repo/ cp manifest.json /opt/cloudera/parcel-repo/ # 生成 .sha 文件,内容就是 SHA1 值 sha1sum FLINK-1.16.2-1.16.2-el7.parcel | awk '{print $1}' \ > /opt/cloudera/parcel-repo/FLINK-1.16.2-1.16.2-el7.parcel.sha # 修正属主,CM 以 cloudera-scm 用户读取 chown cloudera-scm:cloudera-scm /opt/cloudera/parcel-repo/FLINK-1.16.2-1.16.2-el7.parcel*.sha文件里只放哈希值,不要带文件名,awk '{print $1}'就是干这个的。属主改成cloudera-scm是必须的,用 root 放进去 CM 读不到,表现是 Parcel 列表里根本不显示这个包。放好后在 CM 界面点「检查新 Parcel」,能看到 FLINK 1.16.2 出现在列表里,说明仓库侧配置对了。
4. 分发、激活与 CM 集成:让 Flink 1.16.2 在 CDH 6.3.2 里跑起来
Parcel 出现在列表里只是第一步,分发到各节点、激活、再配好 CM 的服务描述,才算真正装进去。这一章按 CM 界面的操作顺序走,每步说清点哪里、看什么日志、失败怎么定位。
4.1 分发与激活的操作顺序
在 CM 主页点「Parcel」,找到 FLINK 1.16.2,先「分发」,再「激活」。分发是把包推到所有节点并解压到/opt/cloudera/parcels,激活是创建 alternatives 链接,让/opt/cloudera/parcels/FLINK指向具体版本目录。
# 分发完成后在节点上确认解压结果 ls -l /opt/cloudera/parcels/ | grep FLINK # 激活后确认软链接指向 readlink -f /opt/cloudera/parcels/FLINK第一条命令应该看到FLINK-1.16.2-1.16.2目录;第二条命令应该输出/opt/cloudera/parcels/FLINK-1.16.2-1.16.2。如果readlink输出为空或者指向旧版本,说明激活没成功,去/var/log/cloudera-scm-agent/cloudera-scm-agent.log里搜parcel关键字,常见原因是磁盘空间不足或者目录权限不对。分发阶段失败多半是网络或校验和问题,激活阶段失败多半是目录结构或权限问题,这两类日志特征不一样,分开看能省时间。
4.2 配置 Flink 的 alternatives 与环境变量
Parcel 激活后,CM 不会自动把flink命令加到 PATH,需要手工配 alternatives 或者在/etc/profile.d里加环境变量。我一般用 alternatives,跟 CDH 其他组件的管理方式保持一致。
# 注册 flink 命令到 alternatives alternatives --install /usr/bin/flink flink \ /opt/cloudera/parcels/FLINK/bin/flink 100 # 注册 flink-run 等其他脚本按需重复,这里以主命令为例 alternatives --display flink--install的三个参数分别是链接路径、名称、实际脚本路径和优先级。优先级 100 是随意定的,集群里只有一个 Flink 版本时无所谓,多版本共存时用优先级控制默认指向。--display用来确认链接生效。这一步漏了,用户在节点上敲flink会提示 command not found,但 Parcel 本身是好的,属于配置遗漏不是安装失败。
4.3 CM 服务描述与角色配置
要在 CM 界面里管理 Flink 的 JobManager 和 TaskManager,需要加服务描述文件flink.json到/opt/cloudera/csd。这个文件定义角色类型、启动命令、配置项映射,写起来比较长,核心是roles和commands两段。
{ "name": "FLINK", "label": "Apache Flink", "version": "1.16.2", "roles": [ { "name": "JOBMANAGER", "label": "JobManager", "startRunner": { "program": "/opt/cloudera/parcels/FLINK/bin/flink", "args": ["jobmanager"] } }, { "name": "TASKMANAGER", "label": "TaskManager", "startRunner": { "program": "/opt/cloudera/parcels/FLINK/bin/flink", "args": ["taskmanager"] } } ] }startRunner.program指向 Parcel 里的启动脚本,args是子命令。实际生产用的描述文件还要加配置项定义、日志目录、健康检查,这里只保留最小可用结构。放好文件后重启 CM Server,界面里才能「添加服务」。注意 CSD 文件属主也要是cloudera-scm,JSON 格式错误会导致 CM Server 启动时加载失败,表现是整个 CM 界面打不开,这个坑比较隐蔽,改完先用python -m json.tool校验。
4.4 提交一个作业做冒烟测试
服务起来后,用 Flink 自带的示例作业做冒烟测试,确认 YARN 提交链路通。
# 提交 WordCount 示例到 YARN,per-job 模式 flink run -t yarn-per-job \ -c org.apache.flink.streaming.examples.wordcount.WordCount \ /opt/cloudera/parcels/FLINK/examples/streaming/WordCount.jar \ --input /tmp/words.txt --output /tmp/out-t yarn-per-job指定部署模式,1.16 里 per-job 和 application 都可用,冒烟测试用 per-job 简单直接。-c指定入口类,jar 路径用 Parcel 里的示例包。如果报Could not find or load main class,多半是 jar 路径写错或者 Parcel 没激活;如果报 YARN 队列相关错误,去 CM 里确认 YARN 队列配置和yarn-site.xml是否被 Flink 读到。这一步跑通,说明从 Parcel 到 YARN 的整条链路是通的。
5. 避坑与排查:Flink 1.16.2 在 CDH 6.3.2 上的五类翻车记录
这套组合的坑集中在 Parcel 校验、依赖冲突、内存配置和日志定位四块。下面五条是我实际遇到过的,按「现象 → 原因 → 解决」写,遇到同类问题可以直接对号入座。
5.1 Parcel 分发卡住或校验失败
现象:CM 里 Parcel 分发进度停在某个百分比,或者激活时报hash mismatch。原因通常是 manifest 里的 hash 与实际文件不一致,或者.sha文件内容带了文件名。解决:重新sha1sum生成哈希,确认 manifest 和.sha两处都只放哈希值本身,重新分发前先删掉节点上/opt/cloudera/parcels/.flink之类的临时目录,避免旧缓存干扰。
5.2 提交作业报 Hadoop 类找不到
现象:flink run时报NoClassDefFoundError: org/apache/hadoop/conf/Configuration。原因是用错了二进制包,选了不带 hadoop3 的版本,或者env.hadoop.conf.dir没指向/etc/hadoop/conf。解决:换flink-1.16.2-bin-scala_2.12-hadoop3.tgz重新打 Parcel,并在flink-conf.yaml里补上env.hadoop.conf.dir。已经装好的集群改配置后重启 JobManager 即可,不用重打 Parcel。
5.3 TaskManager 启动即退出
现象:CM 里 TaskManager 角色显示已停止,日志里是OutOfMemoryError或者Container killed。原因多半是taskmanager.memory.process.size设得比 YARN 容器上限还大,或者numberOfTaskSlots设太多导致单 slot 内存不足。解决:把process.size调到小于 YARN 单容器上限,slot 数按process.size / 单 slot 需求反推,别拍脑袋写 8 或 16。改完在 CM 里重启角色,观察日志里内存分配那几行是否合理。
5.4 历史服务器读不到已完成作业
现象:HistoryServer 页面空白,HDFS 上jobmanager.archive.fs.dir目录里确实有文件。原因是 JobManager 写归档用的路径和 HistoryServer 读的路径不一致,或者 HDFS 权限不对。解决:确认jobmanager.archive.fs.dir和historyserver.archive.fs.dir指向同一路径,用hdfs dfs -ls看目录属主,确保 Flink 运行用户有读权限。权限问题在 CDH 里很常见,Kerberos 环境下还要确认 keytab 配置。
5.5 CSD 文件导致 CM 界面异常
现象:改完flink.json重启 CM Server 后,Web 界面打不开或者服务列表加载失败。原因是 CSD 的 JSON 格式错误,CM Server 启动时解析失败。解决:先用python -m json.tool /opt/cloudera/csd/flink.json校验,确认合法再重启;已经起不来的,把文件移走再重启 CM Server,恢复后再逐步加回。这个坑的教训是改 CSD 前先备份,别直接覆盖。
6. 装完怎么验证:三条命令确认 Flink 1.16.2 在 CDH 6.3.2 上真的跑通了
装完不等于跑通,Parcel 激活成功、服务显示绿色,都可能掩盖配置问题。我一般用三条命令做最终验证,分别覆盖本地运行、YARN 提交和历史归档,三条都过才算交付。
第一条,本地 Standalone 跑一个批作业,确认 Flink 自身二进制完整:
# 本地模式跑示例,不依赖 YARN flink run -t local \ /opt/cloudera/parcels/FLINK/examples/batch/WordCount.jar \ --input /etc/hosts --output /tmp/wc-local-out-t local让作业在单个 JVM 里跑,绕开 YARN 和 HDFS,专门验证 Parcel 里的 jar 和脚本是否完整。输出目录/tmp/wc-local-out里应该有_SUCCESS文件,没有就是本地运行链路有问题,先别急着查 YARN。
第二条,YARN per-job 提交并确认应用状态:
# 提交后拿 application id,再查状态 flink run -t yarn-per-job -d \ /opt/cloudera/parcels/FLINK/examples/streaming/WordCount.jar \ --input /tmp/words.txt --output /tmp/wc-yarn-out # 用 yarn application 确认状态为 FINISHED 或 RUNNING yarn application -list -appStates ALL | grep -i flink-d是 detached 模式,提交后立即返回,适合脚本化验证。yarn application那条命令确认应用真的被 YARN 接住了,状态是FINISHED说明批作业跑完,RUNNING说明流作业在跑。如果列表里根本没有,说明提交阶段就失败了,回去看 Flink 客户端日志。
第三条,确认历史归档落到了 HDFS:
# 查看归档目录,应该有作业的 json 归档文件 hdfs dfs -ls hdfs:///flink/completed-jobs这条命令对应jobmanager.archive.fs.dir配置,目录里出现带时间戳的子目录和jobmanager归档文件,说明归档链路通。HistoryServer 页面能刷出这个作业,才算闭环。
| 验证项 | 命令关键参数 | 通过标准 |
|---|---|---|
| 本地运行 | -t local | 输出目录有_SUCCESS |
| YARN 提交 | -t yarn-per-job -d | yarn application状态正常 |
| 历史归档 | hdfs dfs -ls | 归档目录有作业文件 |
三条里最容易翻车的是第二条,YARN 队列权限和env.hadoop.conf.dir两个点经常同时出问题。我习惯在交付前把这三条命令写进变更单的验收项,逐条打勾。从那以后我每次做第三方 Parcel,激活成功后都不直接说「装好了」,而是强制走一遍这三条验证,宁可多花十分钟,也不让同事在提交作业时才发现配置漏了。希望帮到你。
本文还有配套的精品资源,点击获取