1. 为什么离线部署CDH至今仍是刚需
聊到大数据平台搭建,CDH(Cloudera's Distribution Including Apache Hadoop)这个名字在老一批数据工程师心里分量很重。虽然Cloudera后来主推CDP,但大量存量生产集群仍然跑在CDH 5.x系列上,尤其是5.16.2这个版本,算是5系里比较成熟稳定的一个节点。很多公司的内网环境、专有网络、物理机房,压根不具备直接访问外网的条件,离线部署就成了唯一选择。
我前后在三个不同规模的环境里做过CDH 5.16.2的离线部署,最小的是6节点测试集群,最大的是40多节点的生产集群。每次都会踩到不一样的坑,有的是包依赖问题,有的是系统参数没调对,有的是Cloudera Manager Agent注册不上。这篇文章就把整个离线部署的流程、原理、参数计算和避坑经验完整梳理一遍。
这篇文章适合谁看?如果你手头有一批内网服务器,需要从零搭建一套CDH 5.16.2集群,或者你正在维护老集群需要重新部署,那这篇内容可以直接当操作手册用。即使你用的是更新版本,部署思路和排查方法也是相通的。
核心关键词:离线部署、CDH 5.16.2、Cloudera Manager、Parcel包、内网集群。
整个部署的核心逻辑其实不复杂:把所有需要的安装包提前下载好,传到内网,然后通过Cloudera Manager统一分发和安装。难点在于包与包之间的依赖关系、操作系统层面的前置配置、以及各个组件参数的合理规划。下面我按实际操作的顺序,从整体设计到细节实现,一步步拆开讲。
2. 部署方案整体设计与前置规划
2.1 离线部署的核心思路与选型考量
离线部署CDH,本质上要解决三个问题:软件包从哪来、怎么传进去、怎么装上去。
CDH的安装包主要分两类:一类是Cloudera Manager Server和Agent的RPM包,另一类是CDH核心组件的Parcel包。RPM包负责搭建管理平台本身,Parcel包则是CM用来分发和激活Hadoop生态各组件的载体。这两类包必须版本严格对应,5.16.2的CM对应5.16.2的CDH Parcel,版本错一点都可能出问题。
为什么用Parcel而不是直接用RPM装CDH组件?这是Cloudera的设计选择。Parcel的好处是自带版本管理、支持滚动升级、分发过程可校验。坏处是包体积大,CDH 5.16.2的Parcel包大概2GB左右,加上CM的RPM包和其他依赖,总共需要准备5-8GB的离线文件。所以传输前一定要确认好存储空间。
选型上还有一个关键决策:用CM管理还是纯手工搭。手工搭Hadoop集群在5个节点以内还能忍,超过10个节点,配置同步、服务启停、监控告警全是噩梦。CM虽然重,但它把集群管理这件事标准化了,离线场景下更是如此。我的建议是,只要节点数超过3个,就老老实实用CM。
2.2 集群规模与角色分配的计算逻辑
角色分配不是拍脑袋决定的,要根据数据量和并发需求算。假设你要处理的数据量在TB级别,日均任务数在几百个,下面这套分配逻辑可以参考。
管理节点(1台):跑Cloudera Manager Server、MySQL元数据库、NameNode(主)。这台机器内存至少32GB,因为CM Server本身吃内存,MySQL的元数据随着集群运行会越来越大。CPU 8核起步,磁盘建议SSD,元数据读写对IOPS敏感。
管理节点(1台):跑Standby NameNode、ResourceManager(备)、Hive Metastore。这台是热备角色,配置可以和管理主节点一致。
数据节点(N台):跑DataNode、NodeManager、JournalNode。每台的内存和磁盘根据数据量算。经验公式是:DataNode堆内存 = 每百万个block约需1GB堆。假设单节点管理50万个block,堆内存给8GB比较稳妥。磁盘方面,HDFS三副本,原始数据1TB实际占用3TB,再留20%缓冲,所以单节点可用磁盘容量 = 预期存储数据量 × 3 × 1.2 ÷ 节点数。
边缘节点(1台):跑HiveServer2、Hue、Oozie等客户端服务。这台是给分析师和开发人员用的,配置不用太高,16GB内存、4核CPU足够。
下面这张表是我在一个12节点集群里实际用的配置,可以直接参考:
| 角色 | 节点数 | CPU | 内存 | 磁盘 | 关键服务 |
|---|---|---|---|---|---|
| CM主+NN主 | 1 | 8核 | 32GB | 500GB SSD | CM Server, NameNode, MySQL |
| NN备+RM备 | 1 | 8核 | 32GB | 500GB SSD | Standby NN, Standby RM |
| DataNode | 8 | 16核 | 64GB | 4TB×4 HDD | DataNode, NodeManager |
| 边缘节点 | 1 | 4核 | 16GB | 200GB SSD | HiveServer2, Hue |
| 管理备用 | 1 | 4核 | 16GB | 200GB | JournalNode, ZK |
注意:JournalNode至少部署3台且为奇数,这是ZooKeeper和HDFS HA的硬性要求。上面表格里管理备用节点也兼了JournalNode角色,实际部署时要把ZK和JN分散到不同物理机上,避免单点故障。
2.3 操作系统层面的前置检查清单
CDH 5.16.2对操作系统的要求比较挑。官方支持RHEL/CentOS 6.8+和7.2+,Ubuntu 16.04也有支持但坑更多。我强烈建议用CentOS 7.4或7.6,这两个版本在社区里验证最充分。
部署前必须逐项确认以下内容,任何一项不满足都可能导致后续安装失败:
- 关闭SELinux:
setenforce 0临时关闭,修改/etc/selinux/config永久关闭。SELinux会拦截CM的很多操作,不关必出问题。 - 关闭防火墙:
systemctl stop firewalld && systemctl disable firewalld。内网环境如果安全策略允许,直接关掉最省事。如果必须开,需要放行大量端口,后面我会列出端口清单。 - 配置主机名和hosts:每台机器的主机名要唯一且能互相解析。
/etc/hosts里把所有节点的IP和主机名对应写清楚,不要依赖DNS。 - 时间同步:所有节点时间必须一致,偏差超过30秒CM就会报错。内网没有NTP服务器的话,选一台机器做NTP Server,其他节点指向它。
- 关闭透明大页面(THP):
echo never > /sys/kernel/mm/transparent_hugepage/enabled,并写入rc.local。THP会导致Hadoop性能抖动。 - 调整swappiness:
sysctl vm.swappiness=1,减少内存交换。 - 文件句柄数:
ulimit -n 65536,写入/etc/security/limits.conf。 - 创建统一用户:所有节点创建相同的用户名和UID,比如
cloudera用户,UID统一为2000。CM Agent以root运行,但服务进程建议用普通用户。
这些检查项看起来琐碎,但每一条都是血泪教训。我见过因为hosts文件里有一台机器的主机名写错,导致Agent注册失败排查了整整一下午的情况。
3. 离线包准备与本地仓库搭建
3.1 需要下载哪些包及其依赖关系
离线部署最怕漏包。CDH 5.16.2需要下载的东西分四类:
第一类:Cloudera Manager RPM包。包括cloudera-manager-server、cloudera-manager-daemons、cloudera-manager-agent。这三个包在Cloudera的archive仓库里能找到,5.16.2对应的路径是cm5/5.16.2/。
第二类:CDH Parcel包。核心文件是CDH-5.16.2-1.cdh5.16.2.p0.18-el7.parcel和对应的.sha校验文件,以及manifest.json。注意el7代表CentOS 7,el6是CentOS 6,下错了装不上。
第三类:操作系统依赖包。CM和CDH依赖一些系统库,比如MySQL-python、python-psycopg2、libxslt、zlib等。这些在最小化安装的CentOS上通常缺失,需要提前下载好RPM包。
第四类:数据库驱动。如果用MySQL作为CM和Hive的元数据库,需要mysql-connector-java的jar包。如果用PostgreSQL,则对应postgresql的驱动。
下载渠道方面,Cloudera的archive地址是公开的,但内网机器访问不了,需要在一台能上外网的机器上下好再传进去。下载时注意核对sha1校验值,传输过程中文件损坏是常见问题。
3.2 用createrepo搭建本地YUM源
把所有RPM包放到一个目录后,用createrepo生成仓库元数据,这样内网机器就能通过YUM直接安装,不用一个个手动rpm -ivh。
操作步骤如下:
# 安装createrepo工具(在外网机器上) yum install -y createrepo # 创建仓库目录 mkdir -p /var/www/html/cm5.16.2 # 把所有RPM包复制进去 cp /path/to/rpms/*.rpm /var/www/html/cm5.16.2/ # 生成仓库元数据 createrepo /var/www/html/cm5.16.2/ # 启动HTTP服务(用nginx或httpd都行) systemctl start httpd然后在每台内网机器的/etc/yum.repos.d/下新建一个repo文件:
[cm5.16.2] name=Cloudera Manager 5.16.2 baseurl=http://<仓库机器IP>/cm5.16.2/ enabled=1 gpgcheck=0gpgcheck=0是因为我们自己签的包没有GPG签名,内网环境可以接受。如果安全要求高,可以自己导入GPG公钥。
提示:仓库机器最好单独一台,不要和CM Server混用。HTTP服务占资源不大,但仓库目录可能有好几GB,混用会影响CM性能。
3.3 Parcel包的放置与校验
Parcel包不走YUM,而是放在CM Server能访问的HTTP路径下。默认路径是/opt/cloudera/parcel-repo/。
操作步骤:
# 在CM Server上创建parcel仓库目录 mkdir -p /opt/cloudera/parcel-repo # 复制parcel文件和校验文件 cp CDH-5.16.2-1.cdh5.16.2.p0.18-el7.parcel /opt/cloudera/parcel-repo/ cp CDH-5.16.2-1.cdh5.16.2.p0.18-el7.parcel.sha /opt/cloudera/parcel-repo/ cp manifest.json /opt/cloudera/parcel-repo/ # 修改权限 chown -R cloudera-scm:cloudera-scm /opt/cloudera/parcel-repo/这里有个细节:.sha文件里的哈希值必须和parcel文件实际哈希一致。有时候下载的sha文件内容不对,CM会一直显示"正在校验"然后失败。可以用sha1sum手动核对:
sha1sum CDH-5.16.2-1.cdh5.16.2.p0.18-el7.parcel # 对比输出的哈希值和.sha文件里的内容如果哈希不匹配,说明parcel文件下载不完整,需要重新下载。这个坑我踩过两次,一次是网络中断导致文件截断,一次是sha文件本身下错了版本。
4. Cloudera Manager与CDH集群实操部署
4.1 CM Server和Agent的安装与数据库初始化
CM Server的安装本身不复杂,关键是数据库要提前准备好。
第一步:安装MySQL并创建数据库
# 安装MySQL 5.7(CentOS 7自带的是MariaDB,建议换MySQL) yum install -y mysql-community-server systemctl start mysqld systemctl enable mysqld # 获取临时密码 grep 'temporary password' /var/log/mysqld.log # 登录并修改密码 mysql -uroot -p ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword';然后创建CM和Hive需要的数据库:
CREATE DATABASE scm DEFAULT CHARACTER SET utf8; CREATE DATABASE hive DEFAULT CHARACTER SET utf8; CREATE DATABASE oozie DEFAULT CHARACTER SET utf8; CREATE DATABASE hue DEFAULT CHARACTER SET utf8; GRANT ALL ON scm.* TO 'scm'@'%' IDENTIFIED BY 'scm_password'; GRANT ALL ON hive.* TO 'hive'@'%' IDENTIFIED BY 'hive_password'; GRANT ALL ON oozie.* TO 'oozie'@'%' IDENTIFIED BY 'oozie_password'; GRANT ALL ON hue.* TO 'hue'@'%' IDENTIFIED BY 'hue_password'; FLUSH PRIVILEGES;第二步:安装CM Server和Agent
# 在CM Server节点 yum install -y cloudera-manager-daemons cloudera-manager-server # 在所有Agent节点 yum install -y cloudera-manager-daemons cloudera-manager-agent第三步:初始化CM数据库
/opt/cloudera/cm/schema/scm_prepare_database.sh mysql scm scm scm_password这个脚本会连接MySQL,创建表结构。如果报"Access denied",检查MySQL用户权限和密码。如果报"Unknown database",检查数据库是否创建。
第四步:配置Agent指向Server
修改每台Agent节点的/etc/cloudera-scm-agent/config.ini:
server_host=<CM Server的主机名> server_port=7182第五步:启动服务
# CM Server节点 systemctl start cloudera-scm-server # 等待约1-2分钟,检查日志 tail -f /var/log/cloudera-scm-server/cloudera-scm-server.log # 看到"Started Jetty server"说明启动成功 # 所有Agent节点 systemctl start cloudera-scm-agent4.2 通过CM Web界面完成集群安装
CM Server启动后,浏览器访问http://<CM Server IP>:7180,默认账号密码都是admin。
登录后按向导走:
- 接受许可协议,选择"Cloudera Express"版本(免费版,功能足够用)。
- 指定主机:输入所有Agent节点的主机名,CM会自动扫描并检测连通性。如果某台机器显示"无法连接",检查Agent服务是否启动、防火墙是否关闭、主机名解析是否正确。
- 选择Parcel:CM会自动读取
/opt/cloudera/parcel-repo/下的parcel文件。如果没显示,检查文件权限和路径。选中CDH 5.16.2,点击"分配"和"激活"。 - 检查主机:CM会对每台机器做健康检查,包括JDK版本、Python版本、文件句柄数等。有警告项可以忽略,但错误项必须解决。
- 选择服务组合:根据你的需求选。一般选"核心Hadoop"或"自定义"。核心Hadoop包含HDFS、YARN、ZooKeeper、Hive、Hue等。
- 分配角色:按前面2.2节的规划分配。CM会给出默认分配,但默认分配往往不合理,需要手动调整。
- 配置数据库:输入Hive、Oozie等服务的数据库连接信息。
- 审核并启动:确认配置无误后,点击"继续",CM开始安装和启动所有服务。
整个过程大概需要20-40分钟,取决于节点数量和网络速度。安装过程中可以在"状态"页面看到实时进度。
4.3 关键参数配置与调优建议
CM装完后,默认参数偏保守,需要根据实际硬件调整。下面几个参数是必须改的:
HDFS相关:
| 参数 | 默认值 | 建议值 | 说明 |
|---|---|---|---|
| dfs.datanode.max.transfer.threads | 4096 | 8192 | 并发传输线程数,节点多时调大 |
| dfs.namenode.handler.count | 30 | 100 | NameNode RPC处理线程,按节点数×20估算 |
| dfs.datanode.balance.bandwidthPerSec | 10MB/s | 100MB/s | 数据均衡带宽,千兆网可调到100MB/s |
YARN相关:
| 参数 | 默认值 | 建议值 | 说明 |
|---|---|---|---|
| yarn.nodemanager.resource.memory-mb | 8GB | 物理内存×0.8 | 留给NM的内存,要扣掉系统和其他服务占用 |
| yarn.scheduler.maximum-allocation-mb | 8GB | 与上一致 | 单个容器最大内存 |
| yarn.nodemanager.resource.cpu-vcores | 8 | 物理核数×0.8 | 可用vcore数 |
内存计算示例:假设单节点64GB内存,DataNode堆8GB,NodeManager堆4GB,系统和其他服务占8GB,那么yarn.nodemanager.resource.memory-mb可以设为(64-8-4-8)×0.8 ≈ 35GB,取整35GB。
注意:
yarn.nodemanager.resource.memory-mb不能超过物理内存减去其他服务占用后的值,否则NodeManager会启动失败或频繁OOM。
4.4 部署后的验证与冒烟测试
装完不代表能用,必须做冒烟测试。
HDFS测试:
# 创建测试目录 hadoop fs -mkdir -p /tmp/smoke-test # 上传一个文件 hadoop fs -put /etc/hosts /tmp/smoke-test/ # 读取 hadoop fs -cat /tmp/smoke-test/hosts # 删除 hadoop fs -rm -r /tmp/smoke-testYARN测试:
# 跑一个WordCount示例 yarn jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar wordcount /etc/hosts /tmp/wc-outputHive测试:
-- 在Hive CLI或Beeline里执行 CREATE TABLE test_smoke (id INT, name STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; INSERT INTO test_smoke VALUES (1, 'a'), (2, 'b'); SELECT COUNT(*) FROM test_smoke; DROP TABLE test_smoke;如果这三个测试都通过,集群基本可用。如果某个失败,看对应服务的日志,通常是权限或配置问题。
5. 常见问题排查与避坑经验实录
5.1 Agent注册失败与主机识别问题
这是离线部署最高频的问题。表现是CM Web界面里主机列表为空,或者部分主机显示"无法连接"。
排查思路:
- 检查Agent服务状态:
systemctl status cloudera-scm-agent。如果没启动,看日志/var/log/cloudera-scm-agent/cloudera-scm-agent.log。 - 检查Agent配置:
/etc/cloudera-scm-agent/config.ini里的server_host是否指向正确的CM Server主机名。 - 检查网络连通性:
telnet <CM Server> 7182,7182是Agent和Server通信的端口。 - 检查主机名解析:
hostname和hostname -f的输出是否一致,/etc/hosts里是否有对应记录。 - 检查时间同步:
date命令对比各节点时间,偏差超过30秒会导致SSL握手失败。
一个隐蔽的坑:如果之前装过CM又卸载了,/var/lib/cloudera-scm-agent/目录下会残留uuid文件,导致新Agent注册时冲突。解决方法是删除该目录下的所有内容再重启Agent。
5.2 Parcel分发卡住或校验失败
Parcel分发过程中卡在某个百分比不动,或者校验失败。
原因一:磁盘空间不足。Parcel解压后占用空间是压缩包的2-3倍,/opt/cloudera/parcels/所在分区至少要有10GB空闲。
原因二:文件权限不对。/opt/cloudera/parcel-repo/下的文件属主必须是cloudera-scm:cloudera-scm,权限644。
原因三:sha文件不匹配。前面3.3节讲过,用sha1sum核对。
原因四:HTTP服务不可达。CM Server通过HTTP从parcel-repo读取文件,如果httpd没启动或端口被占,分发会失败。检查systemctl status httpd。
5.3 服务启动失败与日志定位方法
CM里某个服务显示红色,点进去看日志。但日志文件很多,怎么快速定位?
通用方法:在CM界面点击服务 → "实例" → 找到失败的实例 → "日志" → "完整日志"。搜索关键词ERROR、Exception、Caused by。
常见错误对照表:
| 错误信息 | 可能原因 | 解决方法 |
|---|---|---|
java.net.BindException: Address already in use | 端口被占 | `netstat -tlnp |
Permission denied | 文件/目录权限不对 | 检查属主和权限,HDFS目录用hdfs dfs -chown |
Connection refused | 目标服务没启动 | 检查依赖服务状态,按依赖顺序启动 |
OutOfMemoryError | 堆内存不足 | 调大对应服务的-Xmx参数 |
No space left on device | 磁盘满 | df -h检查,清理日志或扩容 |
一个实用技巧:CM的"诊断"功能可以一键收集所有节点的日志打包下载,比一个个登录去看效率高得多。
5.4 性能调优与稳定性保障的独家经验
集群跑起来之后,稳定性比性能更重要。下面几条是我在实际运维中总结的:
第一,JN和ZK不要和NN/RM混部。JournalNode对磁盘IO延迟敏感,和NameNode抢磁盘会导致HDFS写超时。ZooKeeper对网络延迟敏感,和ResourceManager混部会影响选主。
第二,DataNode磁盘做RAID0而不是RAID5。HDFS本身有三副本,RAID5的校验开销反而拖慢写入。RAID0把多块盘合成一块大容量,性能最好。
第三,定期做fsck。hdfs fsck / -files -blocks -locations可以检查块完整性。建议每周跑一次,发现损坏块及时处理。
第四,CM的监控告警要配起来。默认的告警阈值偏宽松,建议把HDFS容量告警调到70%,YARN内存告警调到80%。早发现早处理,别等集群挂了再救。
第五,备份CM的数据库。scm库里有整个集群的配置信息,丢了就得重装。用mysqldump每天备份一次,保留最近7天。
提示:CDH 5.16.2的Parcel包在Cloudera archive里还能找到,但官方已经不再维护5.x系列。如果条件允许,建议规划向CDP或更现代的发行版迁移。但在迁移完成之前,把现有集群维护好仍然是第一要务。
5.5 离线环境下的日常维护要点
离线集群的维护和外网集群有些不一样,最大的区别是不能随时yum install。所以本地仓库要维护好,新加的包及时放进仓库并createrepo --update。
另外,CM的Agent和Server版本要严格一致。如果只升级了Server没升级Agent,会出现兼容性问题。升级时先在测试环境验证,再滚动升级生产环境。
日志清理也要注意。Hadoop各组件的日志默认保留时间不长,但CM Server的日志会一直累积。在CM里配置日志轮转策略,或者写个cron脚本定期清理/var/log/cloudera-scm-server/下的旧日志。
最后,记录好每次变更。离线环境排查问题本来就比在线环境难,如果没有变更记录,出了问题根本不知道是哪次操作导致的。我习惯用简单的文本文件记录每次配置修改、服务重启、参数调整的时间和内容,看起来土但非常管用。