CDH-5.7.0 这套组合放到今天算得上是老资历了但在我接触过的不少内网项目里它仍然是承载数仓和离线计算任务的主力。而这些环境有个共同点服务器不通外网甚至连统一的内部镜像源都没有。在这种条件下用 Parcels 方式离线安装配置 CDH-5.7.0几乎是唯一稳妥的路子。所谓 Parcels可以理解为 Cloudera Manager 管理的一种二进制分发包它以压缩包加清单文件的形式存在配合本地仓库就能完成分发、激活和版本切换全程不需要节点访问外网。这篇内容我准备把从零到集群跑起来的完整链路讲透环境基线怎么定、本地 yum 源和 Parcel 仓库怎么搭、CM Server 怎么初始化、分发激活时有哪些坑。适合手上有一批内网机器、需要自己从零搭一套 Hadoop 集群的运维和开发同学也适合刚接手前人遗留集群、需要搞明白 Parcels 目录结构的人。1. 为什么离线场景我优先选Parcels而不是直接装包1.1 三种安装方式的取舍先算清楚这笔账CDH 的组件落盘方式主要有三种操作系统包管理RPM/DEB、Tarball 手工解压、Parcel 分发。这三种方式在联网环境下差别不算致命但一旦切到纯离线环境差距就会被放大。RPM 方式的逻辑是把 Hadoop 的每个组件拆成一个个系统包装到/usr/lib/hadoop、/usr/lib/hive这些固定路径下。好处是能和系统包管理体系打通rpm -qa一眼能看到装了什么坏处是组件之间的依赖关系全靠包依赖描述版本升级基本等于重新装一遍回滚更是灾难——你得把旧包一个个找回来重装。更要命的是离线环境里依赖树一旦缺一个包yum install就会卡在那里报依赖错误排查成本很高。Tarball 方式最原始解压到哪个目录全靠自己定环境变量也全靠自己配。它的优点是彻底可控缺点同样是彻底可控——Cloudera Manager 不认识你手工解压的目录集群监控、配置下发、服务启停这些能力全部用不上等于放弃了大半个 CM 的价值。Parcel 方式走的是中间路线也是我推荐的一条。它把一整套 CDH 组件打成一个压缩包附一个.sha校验文件和一个manifest.json清单由 CM 统一下发到各节点的/opt/cloudera/parcels目录解压后通过软链接指向当前激活的版本。这个设计带来的直接好处是升级只需要分发新 Parcel 再激活旧版本目录原封不动留着出问题一条命令切回去。对比维度RPM/DEB 包Tarball 手工解压Parcel 分发离线可行性中依赖容易缺高但全靠手工高仓库自包含版本共存与回滚差中靠改环境变量好软链接切换CM 纳管能力部分无完整单节点体积分散几百个包单包单包约 1.5G适合场景单机试验临时验证生产集群提示Parcel 的“激活”本质上只是切换/opt/cloudera/parcels/CDH这个软链接的指向所以磁盘上同时存在两三个 Parcel 版本是完全正常的规划磁盘时别只按一个版本算。1.2 Parcel内部结构决定了运维方式拆开一个 CDH 的 Parcel 包结构其实很朴素顶层目录名形如CDH-5.7.0-1.cdh5.7.0.p0.45里面是bin、lib、etc、sbin这些子目录本质上就是一份预编译好的安装树。真正让 CM 能识别它的是同目录下的manifest.json这个文件里记录了包名、版本、组件列表、各服务的默认配置项。理解这一点对排查问题很有帮助。比如某个服务的日志路径不对你不需要去猜 CM 做了什么魔法直接去 Parcel 目录下对应组件的etc模板里看默认值就行再比如某个 jar 冲突find /opt/cloudera/parcels -name *.jar就能把整套依赖摊开来看。还有一个细节Parcel 解压出来的目录是只读语义的CM 不会往里面写东西。所有运行时生成的数据、日志、配置副本都放在/var/run/cloudera-scm-agent/process/和/var/log/下。这个边界分得很清楚好处是 Parcel 目录可以被多个节点共享挂载虽然一般没人这么干坏处是你改了 Parcel 里的文件重新激活时会被覆盖掉所以任何定制都应该走 CM 的配置项而不是直接改包内文件。1.3 CDH 5.7.0这个版本的特殊性5.7.0 这个版本对应的是 Hadoop 2.6.0 内核Hive 1.1.0Spark 1.6.0HBase 1.2.0。这个组合在当年是很主流的配置但放到今天的操作系统上会遇到几个硬性约束提前知道能省掉大半天时间。第一它不支持 EL8 及以上的发行版官方适配的是 EL6/EL7 和 Ubuntu 12.04/14.04/16.04。如果硬往 EL8 上装会遇到 Python 默认指向 python3 导致 Agent 启动失败、OpenSSL 版本过高导致 Kerberos 握手异常这类问题。第二Agent 端依赖 Python 2.6 或 2.7必须保证/usr/bin/python指向 python2。很多新系统默认把python指向 python3这时候要么改软链接要么给 Agent 显式指定解释器路径。第三MySQL 5.7 及以上版本的默认sql_mode包含了NO_ZERO_DATE、ONLY_FULL_GROUP_BY这类严格模式CM 建表脚本会直接报错。这个坑几乎是必踩的后面章节会给出具体的改法。第四JDK 支持到 8但 8u141 之后的某些版本在 TLS 握手行为上有变化如果 CM Server 和 Agent 之间出现莫名其妙的连接中断先把 JDK 换成 8u151 之前的稳定版本试试。2. 上线前的环境盘点别急着装先把这几件事钉死2.1 最小可用拓扑与角色分配我一般建议至少三台机器起步低于三台很多服务的默认副本数配置就跑不起来了。三台的典型分法是一台同时承载 CM Server 和若干 Master 角色另外两台做纯工作节点。这个分法不算最优但对小规模集群来说资源利用率最高。主机名内存CPU磁盘角色node0132G8C系统盘 200G 数据盘 1TCM Server、NameNode、ResourceManager、Hive Metastore、ZooKeepernode0232G8C同上DataNode、NodeManager、ZooKeeper、JournalNodenode0332G8C同上DataNode、NodeManager、ZooKeeper、JournalNode磁盘规划上有一点必须提前说清楚数据盘不要用 LVM 再切一个大分区挂到/最好是独立挂到/data这类路径然后在 CM 里把 DataNode 数据目录配成/data/dfs/dn。这样做的理由是 HDFS 的存储目录一旦写满至少不会把系统盘一起拖死运维还有登录进去处理的机会。至于 ZooKeeper三节点部署时一定要是奇数个这一点很多人第一次搭会忽略。三台机器各一个 ZK 实例能容忍挂掉一台属于最低可用的高可用配置。2.2 操作系统层面的基线配置这部分内容看起来枯燥但十次安装失败里有六次能追溯到这里的某一项没做。我按执行顺序列一遍。主机名和 hosts 必须一一对应而且所有节点的 hosts 文件内容要保持完全一致。CM 在添加主机时会做正向和反向解析校验如果hostname返回的名字和hosts里配的不一致添加主机的步骤会直接卡住报“主机名无法解析”。# 三台机器统一执行 hostnamectl set-hostname node01 # 各机器改成自己的名字 cat /etc/hosts EOF 10.0.0.11 node01 10.0.0.12 node02 10.0.0.13 node03 EOFSSH 免密要在 CM Server 所在节点上对三台机器包括自己都配通因为 CM 下发 Parcel 和启动 Agent 都依赖它。ssh-keygen -t rsa -N -f ~/.ssh/id_rsa for h in node01 node02 node03; do ssh-copy-id -i ~/.ssh/id_rsa.pub root$h; done防火墙和 SELinux 在离线集群里我一般直接关掉不是偷懒是因为 CDH 组件之间通信的端口实在太多逐个开例外容易漏而且内网环境本身有边界防护。systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/configSwap 必须关掉。Hadoop 各组件对内存的预期是“我要多少就有多少”一旦发生 swapDataNode 的心跳会周期性超时表现为节点被反复标记为不健康。关法有两种临时用swapoff -a永久则要注释掉/etc/fstab里的 swap 行并且把vm.swappiness调到 1。swapoff -a sed -i /swap/s/^/#/ /etc/fstab时间同步在离线环境里是个容易被忽视的点因为没法直接用公网 NTP。做法是在内网找一台机器做时间源其余节点指向它。用 chrony 比 ntpd 好收敛快。# node01 上 /etc/chrony.conf server 127.0.0.1 iburst allow 10.0.0.0/24 local stratum 10 # node02、node03 上 server node01 iburstTransparent HugePage 建议关掉这是 HBase 和 Impala 官方都明确要求的。不改的话 HBase RegionServer 在高负载下会出现长尾延迟而且很难定位。echo never /sys/kernel/mm/transparent_hugepage/enabled echo never /sys/kernel/mm/transparent_hugepage/defrag文件句柄数和进程数上限要放开默认的 1024 根本不够 DataNode 用。cat /etc/security/limits.conf EOF * soft nofile 65536 * hard nofile 65536 * soft nproc 65536 * hard nproc 65536 EOF内核参数方面vm.swappiness1、net.core.somaxconn1024、vm.max_map_count262144这三项是我每次必调的。最后一项不调HBase 在某些场景下会直接启动失败并提示 mmap 数量不足。2.3 JDK与Python的版本红线JDK 我一般用 Oracle JDK 8装在/usr/java/jdk1.8.0_151然后建一个/usr/java/default软链接指向它。这样做的原因是 CM 添加主机时会去探测常见路径有default这个软链能少一次手工填写。环境变量里JAVA_HOME指向软链路径别指向具体版本目录将来换 JDK 只改一处。export JAVA_HOME/usr/java/default export PATH$JAVA_HOME/bin:$PATHPython 的问题前面提过再强调一次确认/usr/bin/python -V输出的是 2.7.x。如果系统只有 python3需要单独装一个 python2然后把/usr/bin/python软链过去。这里有个细节别直接改系统的 python 软链因为有些系统工具依赖 python3比较稳妥的做法是在 Agent 配置里指定agent_python参数或者用 alternatives 机制管理。2.4 元数据库选型与建库脚本CM 本身和它管理的各个服务都需要一个关系库来存元数据。可选的有 MySQL、PostgreSQL、Oracle。我这些年用下来MySQL 是最省心的社区资料也最多。建库的原则是每个服务独立库、独立账号不要图省事全塞一个库里。原因很简单将来某个服务要单独升级或者重建独立库能让你只动它一个。CREATE DATABASE scm DEFAULT CHARACTER SET utf8; CREATE DATABASE amon DEFAULT CHARACTER SET utf8; CREATE DATABASE rman DEFAULT CHARACTER SET utf8; CREATE DATABASE hive DEFAULT CHARACTER SET utf8; CREATE DATABASE hue DEFAULT CHARACTER SET utf8; CREATE DATABASE oozie DEFAULT CHARACTER SET utf8; CREATE DATABASE sentry DEFAULT CHARACTER SET utf8; CREATE USER scm% IDENTIFIED BY Scm_2024#Pwd; GRANT ALL PRIVILEGES ON scm.* TO scm%; -- 其余账号依此类推 FLUSH PRIVILEGES;MySQL 服务端参数要调整三处max_connections至少 500innodb_buffer_pool_size按物理内存的 40% 给还有最关键的一步——把严格模式去掉。[mysqld] max_connections 800 innodb_buffer_pool_size 8G innodb_flush_log_at_trx_commit 2 transaction-isolation READ-COMMITTED sql_mode STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION如果不改sql_modeCM 初始化时会报类似Invalid default value for CREATED_TIME的错误这个报错信息很模糊第一次遇到很容易往权限或者字符集方向排查白白浪费时间。JDBC 驱动也要提前放好。CM 添加数据库时会在/usr/share/java/下找mysql-connector-java.jar所以要提前把这个 jar 拷过去并改成这个名字。cp mysql-connector-java-5.1.47.jar /usr/share/java/mysql-connector-java.jar chmod 644 /usr/share/java/mysql-connector-java.jar3. 把离线源搭起来本地yum源加Parcel仓库3.1 文件清单与目录规划离线安装最怕的是文件不全装到一半发现少个包又得重新走审批流程去拷。所以出发前一定要把清单核对清楚。CM 这边的包主要是这几个cloudera-manager-daemons、cloudera-manager-server、cloudera-manager-agent如果要装内置数据库还要cloudera-manager-server-db-2。这几个包在 5.7.0 版本里是放在同一个 repo 里的加上repodata元数据目录就构成一个可用的本地源。Parcel 那边需要三个文件.parcel本体、.parcel.sha校验文件、manifest.json清单。注意有些镜像站会提供.parcel.sha1那是老格式5.7.0 用.sha。目录我习惯这样分/data/repo/ ├── cm/ # CM 的 rpm 包和 repodata │ ├── RPMS/ │ └── repodata/ ├── parcels/ # Parcel 文件和 manifest │ ├── CDH-5.7.0-1.cdh5.7.0.p0.45-el7.parcel │ ├── CDH-5.7.0-1.cdh5.7.0.p0.45-el7.parcel.sha │ └── manifest.json └── nginx/ # 发布用配置把cm和parcels分开是有理由的yum 源需要repodata元数据而 Parcel 仓库只需要原始文件加清单。混在一起的话createrepo会把那 1.5G 的 parcel 文件也扫一遍生成校验信息既慢又浪费。3.2 用createrepo生成本地yum源把所有 rpm 包丢进/data/repo/cm/RPMS/然后执行yum install -y createrepo createrepo -p -d -o /data/repo/cm /data/repo/cm/RPMS-d表示用 SQLite 数据库存储元信息-p表示生成时带上包的文件路径。这一步跑完会生成repodata目录本地的 yum 源就成型了。接下来在每台机器上配置 repo 文件。我一般在 CM Server 上用 Nginx 发布这个目录其他节点通过 HTTP 访问如果环境不允许开 Nginx也可以直接把/data/repo打包分发到各节点的同路径repo 文件写成file:///data/repo/cm。# /etc/yum.repos.d/cloudera-manager.repo [cloudera-manager] nameCloudera Manager 5.7.0 baseurlhttp://node01/repo/cm enabled1 gpgcheck0 priority1gpgcheck0在离线内网是可接受的因为包的完整性已经通过传输环节保证。但如果环境有更严格的审计要求可以把 Cloudera 的 GPG 公钥导入进去再开启校验多一道保险。3.3 Parcel的校验、放置与distribution文件Parcel 文件下载下来之后第一件事是校验这一步别跳过。1.5G 的文件在拷贝过程中出错的概率比你想象的高而损坏的 parcel 在分发阶段才报错那时候已经浪费了一轮分发的网络和磁盘 IO。cd /data/repo/parcels sha1sum -c CDH-5.7.0-1.cdh5.7.0.p0.45-el7.parcel.sha输出OK才算过关。如果报FAILED别想办法修直接重新拷一份。然后是manifest.json。这个文件列出仓库里所有可用的 parcelCM 读取它来渲染界面上的可选列表。标准格式长这样{ parcels: [ { parcelName: CDH-5.7.0-1.cdh5.7.0.p0.45-el7.parcel, components: [ {name: hdfs, version: 2.6.0-cdh5.7.0, pkg_version: 0.1.0}, {name: yarn, version: 2.6.0-cdh5.7.0, pkg_version: 0.1.0} ] } ] }大多数情况下你从官方下载下来的 parcel 包里自带的manifest.json就是完整的直接复制过来即可不需要手工写。手工改的风险在于某个组件的components项漏了导致界面上虽然能看到 parcel但激活后某个服务的角色分配页面是空的。真遇到这种情况检查 manifest 是最快的路径。3.4 用Nginx发布静态目录server { listen 80; server_name node01; root /data/repo; autoindex on; location / { sendfile on; tcp_nopush on; } }配好之后用curl -I http://node01/repo/parcels/manifest.json验一下返回 200 就说明通了。这里有个小经验sendfile on对传输大文件收益明显1.5G 的 parcel 下发速度能提升一个档次尤其是在万兆内网里瓶颈往往就在文件发送的实现上。节点端的 repo 配置文件要注意除了 CM 的源如果系统本身的依赖包也不全还需要把系统安装镜像挂成另一个本地源否则cloudera-manager-daemons的依赖项装不上会卡住。4. Cloudera Manager Server的安装与初始化4.1 安装CM Server与Agent在 CM Server 节点上yum 源配好之后一条命令就够了yum clean all yum makecache yum install -y cloudera-manager-daemons cloudera-manager-server其他节点只装 agent 和 daemonsyum install -y cloudera-manager-daemons cloudera-manager-agent装完之后Agent 的配置要改一个关键项——指向 CM Server 的主机名。默认配置里可能是localhost不改的话 Agent 起不来。# /etc/cloudera-scm-agent/config.ini [General] server_hostnode01 server_port7182server_host用主机名而不是 IP这样将来换 IP 不用改配置。前提是第 2.2 节里的 hosts 已经配对了如果这一步没做Agent 日志里会出现Connection refused或者Name or service not known。4.2 数据库初始化脚本CM 提供scm_prepare_database.sh这个脚本完成建表。它的参数顺序是数据库类型、数据库名、用户名、密码还可以额外指定主机和端口。/usr/share/cmf/schema/scm_prepare_database.sh \ mysql -h node01 -P 3306 --scm-host node01 \ scm scm Scm_2024#Pwd执行成功会输出All done, your SCM database is configured correctly!。如果报JDBC driver not found回去检查/usr/share/java/mysql-connector-java.jar是不是存在、权限对不对如果报Access denied检查 MySQL 用户授权的 host 是不是%。脚本执行完会在/etc/cloudera-scm-server/db.properties里写入连接信息。这个文件里的密码是明文存的所以权限要收紧chmod 600 /etc/cloudera-scm-server/db.properties注意如果你后续改了数据库密码这个文件必须同步改而且改完要重启 CM Server。我见过有人只改了 MySQL 侧密码CM 起不来还以为是别的服务冲突查了两小时才发现是这里。4.3 启动服务与关闭远程Parcel仓库systemctl enable cloudera-scm-server systemctl start cloudera-scm-server首次启动比较慢因为在初始化数据库表结构一般要一到三分钟。看日志确认tail -f /var/log/cloudera-scm-server/cloudera-scm-server.log看到Started JettyServer就说明起来了。这时候访问http://node01:7180默认账号密码都是admin。登录之后第一件事不是急着添加主机而是把远程 Parcel 仓库地址清空。路径是“主机 - Parcel”页面右上角的“配置”按钮把“远程 Parcel 仓库 URL”里的默认地址全部删掉只保留你自己的本地地址http://node01/repo/parcels。这一步不做CM 会尝试去连外网检查更新离线环境下会一直在界面上转圈加载还可能在分发 parcel 时优先去外网拉取而失败。5. 集群部署实操从添加主机到角色分配5.1 添加主机与Agent心跳进入“添加服务”向导选择主机时把 node01、node02、node03 一起填进去。CM 会用 SSH 连过去安装 Agent、检查环境。这一步最常见的失败是Incorrect username or password或者Host is not reachable。前者检查 SSH 免密后者检查 hosts 解析和防火墙。还有一种情况比较隐蔽SSH 连上了但 CM 报Python 版本不满足。这就是前面说的 Python 2.7 的问题回去确认/usr/bin/python。如果环境基线检查那一页出现一堆警告不用全部处理。swappiness偏高、THP 未关闭这两类属于会影响性能但不影响安装的可以先过时钟不同步、hosts 解析不一致、Python 版本过低这三类是硬性阻断必须解决。添加成功后Agent 会开始向 Server 发心跳。在“主机”页面看到三台都是“良好”状态才算这一步真正完成。有时候状态会是“存在隐患”点进去看具体原因多数是内存超配或者磁盘可用空间不足。5.2 Parcel分发、激活与目录规划主机加进来之后Parcel 页面会出现一个待分发的 CDH 包。点击“分发”CM 会并行往三台机器推送 1.5G 的文件。这里有个实操技巧如果集群规模大别在界面上点分发。更好的做法是先在某台机器的/opt/cloudera/parcel-cache目录里手工放好文件然后在配置里把parcel_max_download_size和并发数调高。或者更彻底一点把 Parcel 预置到每台机器的/opt/cloudera/parcels下并建好软链CM 检测到已经存在就不会重复下载。三台机器还行三十台的时候分发失败重试是很折磨人的。分发完成后点击“激活”本质上是解压并创建软链接。激活前可以改解压目录默认是/opt/cloudera/parcels我一般保持不变因为磁盘规划时已经把根分区给到 200G放两三个版本绰绰有余。激活后可以验证一下ls -l /opt/cloudera/parcels/ # CDH - CDH-5.7.0-1.cdh5.7.0.p0.455.3 角色分配与关键参数设置接下来进入服务安装环节CM 会给出一个默认的角色分配方案。我一般会做这几处调整。第一NameNode 和 ResourceManager 放在同一台机器上node01但不要让 DataNode 和 NameNode 抢同一块数据盘。HDFS 的数据目录我配成/data/dfs/dn和/data/dfs/nn独立目录独立配额。第二YARN 的内存参数必须手工算不能全信默认值。计算逻辑是NodeManager 可用内存 物理内存 - 系统预留一般 4G其中一部分给 DataNode 的堆和其他进程。以 32G 内存的机器为例先给 DataNode 堆 4G操作系统留 4G剩下 24G 给 YARN。然后yarn.nodemanager.resource.memory-mb设为 24576单个容器上限yarn.scheduler.maximum-allocation-mb设为 8192最小分配yarn.scheduler.minimum-allocation-mb设为 1024。CPU 那边yarn.nodemanager.resource.cpu-vcores设成物理核数 8yarn.scheduler.maximum-allocation-vcores设为 8。不要开启DominantResourceCalculator之外的复杂调度策略小集群用容量调度器加默认配置就够了。property nameyarn.nodemanager.resource.memory-mb/name value24576/value /property property nameyarn.scheduler.maximum-allocation-mb/name value8192/value /property property nameyarn.nodemanager.resource.cpu-vcores/name value8/value /property第三HDFS 的副本数保持 3。三台机器配 3 副本意味着每个 block 都有一份冗余磁盘利用率是 33%看起来浪费但这是可靠性的底线。如果磁盘实在紧张降到 2 也可以接受但要知道这时候任意一台机器宕机都会有数据块进入欠副本状态。第四Hive 的 Metastore 数据库在向导里填上之前建的hive库信息。这里有个细节Hive 的连接串要写成jdbc:mysql://node01:3306/hive?useUnicodetruecharacterEncodingUTF-8字符集不加的话中文注释会乱码。所有配置填完CM 会依次启动各个服务。第一次启动的顺序是 ZooKeeper、HDFS、YARN、Hive如果 ZooKeeper 起不来后面全会失败所以盯着第一个看就行。6. 常见问题排查与避坑速查6.1 Parcel相关的三个高频故障激活卡在“正在解压”。多半是磁盘空间不足。Parcel 激活时需要在目标目录下解压出完整内容1.5G 的包解开后大概 3G 左右加上原有的包/opt至少留 8G。用df -h确认一下。界面上看不到 Parcel。先确认manifest.json的 URL 能访问再确认内容格式合法用python -m json.tool校验一下。如果 manifest 里写的parcelName和实际文件名对不上CM 会静默忽略这个包这也是我建议直接从官方包里复制 manifest 的原因。分发过程中某个节点失败。看/var/log/cloudera-scm-agent/cloudera-scm-agent.log常见原因是该节点/opt空间不足或者 Agent 到 Server 的 7182 端口不通。还有一个隐蔽原因是parcel-cache目录里有之前失败留下的半截文件CM 校验不过就一直重试把该目录清空再分发就好。6.2 心跳与主机状态问题Agent 启动后如果 CM 界面上主机一直是“未知”状态按这个顺序查systemctl status cloudera-scm-agent看进程在不在netstat -tlnp | grep 7182在 Server 上确认端口在听telnet node01 7182从 agent 节点测连通性最后看 agent 日志里的server_host解析出来的 IP 对不对。有一种情况比较特别Agent 日志里反复出现Heartbeating to node01:7182 failed但网络是通的。这时候要看看是不是 CM Server 那边的数据库连接有问题——Server 自己都连不上库自然不会响应心跳表现却像是网络故障。现象可能原因处理方式添加主机报主机名解析失败hosts 不一致或 hostname 与 hosts 不匹配三台 hosts 统一重启网络Agent 无法启动Python 版本为 3.x切换/usr/bin/python到 2.7主机状态显示时钟偏差未做内网时间同步配 chrony 指向内网源Agent 心跳成功但状态异常内存被判定超配调整 CM 的内存超配阈值6.3 数据库与初始化失败scm_prepare_database.sh报错的情况我整理了几种。Invalid default value是sql_mode太严格按 2.4 节改Unknown database是库没建或者名字拼错Communications link failure是 MySQL 只监听了 127.0.0.1改bind-address为0.0.0.0或者本机内网 IP。还有一个坑值得单独说CM 默认会用utf8建表如果你的 MySQL 是 8.0 版本默认字符集是utf8mb4建表脚本里指定utf8时会因为排序规则不兼容报错。5.7.0 这个版本的 CM 对 MySQL 8 支持很差我的建议是老老实实用 5.6 或 5.7别折腾。6.4 服务启动失败的排查思路服务启动失败时CM 界面上给的建议通常比较笼统真正的线索在日志里。每个服务的日志路径是/var/log/服务名/比如 HDFS 在/var/log/hadoop-hdfs/。但要注意CM 托管的服务日志实际是通过 agent 收集的原始文件在/var/log/hadoop-hdfs/hadoop-cmf-hdfs-NAMENODE-node01.log.out这种格式下。几个典型场景NameNode 起不来但日志没明显错误先看是不是格式化的问题安全模式下的目录权限不对会静默失败DataNode 启动后立刻退出看dfs.datanode.data.dir指向的目录是不是不存在或者权限不对Hive Metastore 起不来九成是数据库连接或者 schema 没初始化用schematool -initSchema -dbType mysql补一下。提示任何服务改完配置之后不要只重启该服务先在 CM 里做一次“部署客户端配置”。很多配置不生效的原因是客户端节点上的配置文件还是旧的这个操作会把最新的配置推送到所有节点。6.5 性能调优的几个观察点集群跑起来之后最先暴露的往往不是功能问题而是性能问题。我一般会盯三个指标HDFS 的DFSOutputStream等待时间、YARN 的容器排队时长、以及各节点的load average。如果 HDFS 写入慢但网络和磁盘都不忙检查dfs.datanode.max.transfer.threads默认 4096 在三节点集群里偏小调到 8192 会好一些。YARN 那边如果容器一直排队但资源显示空闲多半是yarn.scheduler.minimum-allocation-mb设得太大导致碎片化严重调小到 512 或者 1024 能缓解。还有一个容易被忽略的点CM 自己也在消耗资源。如果 Server 和 NameNode 挤在同一台机器上JVM 堆别给太大NameNode 给 4G、CM Server 给 2G 是比较平衡的分配。给多了反而会因为 GC 停顿导致界面卡顿让人误以为是集群出了问题。整套流程走下来最花时间的从来不是敲命令而是那些“看起来应该没问题”的地方——hosts 少了一行、python 指错了版本、sql_mode 没改。我个人的习惯是准备一份检查清单每台机器装完之后逐项打勾比事后从日志里倒查要快得多。另外Parcel 仓库那个目录建议单独挂一块盘将来升级 5.8、5.9 的时候新旧 Parcel 并存是常态空间给足能省掉很多次“先删哪个”的纠结。
阅读完成 · 觉得有帮助?