我干大数据平台运维这行快十年了,踩过的坑比吃过的盐还多。刚入行那会儿,以为部署个Hadoop集群就是配配XML文件、敲几条命令的事,结果被现实狠狠教育了。今天不聊那些官方文档里写烂了的东西,就说说实战中那些让人抓狂的坑,以及怎么绕过去。

先说说最基础的资源规划。很多人上来就按官方推荐配置搞,比如NameNode给32G堆内存,DataNode给24G。但实际跑起来才发现,你的数据量、副本数、文件数量才是决定参数的关键。我见过一个项目,数据量才几百GB,却按PB级别配了资源,结果YARN的Container分配不合理,MapReduce任务频繁OOM。反过来,另一个客户数据量不小,却舍不得给资源,NameNode堆内存才8G,结果集群一跑起来,GC频繁到CPU飙到90%以上,整个集群跟死了一样。所以第一步不是抄配置,而是先想清楚三个数:你的数据总量、每天新增量、文件数量级。这三个数定了,再回头调参数,基本不会出大错。
部署顺序也很有讲究。很多人喜欢先装Zookeeper,再装HDFS,装YARN,觉得按依赖顺序来没问题。但实战中发现,顺序反着来反而更稳。为什么?因为HDFS的格式化操作需要Zookeeper已经可用,而YARN的ResourceManager启动时要检查HDFS状态。如果你先把HDFS装好并格式化了,再去装Zookeeper,万一Zookeeper集群起不来,HDFS的HA状态就会一直停留在Standby,你排查半天发现是Zookeeper的myid文件写错了,那种滋味真不好受。我现在的习惯是:先搭Zookeeper,确认三台机器能互相通信,再装HDFS,格式化,装YARN和Spark。每一步都验证通过再往下走,宁可慢一点,也不要一次性全装完再排查问题。
说到配置,有个坑我必须单独拎出来讲——副本因子。默认是3,听起来很安全对吧?但如果你用的是单机伪分布式模式,或者测试环境只有两台机器,副本因子设成3会导致什么?DataNode会一直报复制不足的警告,后台任务不断尝试复制,把磁盘IO和网络都占满了。我见过一个测试环境,就两台机器,配置忘了改,结果跑个Piwik日志分析任务,慢得让人怀疑人生。后来一查,是副本复制把带宽全占了。所以,环境是单机或双机的话,副本因子记得改成1或2,别让系统做无谓的自我修复。
还有一个坑,发生在HDFS的块大小设置上。默认128MB,如果你们的业务场景是大量小文件(比如日志系统产生的几百KB的文件),那这个默认值会把NameNode的内存吃光。因为每个文件、每个块都要在NameNode里记录元数据。我之前处理过一个客户,每天产生上百万个小文件,NameNode堆内存从32G一路加到64G还是不够,实在没办法,只能做文件合并或者引入联邦机制。如果一开始就想到这个场景,把块大小调成64MB甚至更小,再把小文件合并策略做好,根本不会这么惨。
再聊聊部署后的日常运维。很多人以为部署完就万事大吉了,其实真正的挑战才刚刚开始。监控是第一个要解决的问题。别指望装个Ambari或者CDH就高枕无忧了,那些工具自带的监控项根本不够用。我自己的经验是,至少要看三个层面的指标:机器层(CPU、内存、磁盘IO、网络)、服务层(NameNode的RPC延迟、DataNode的读写吞吐、ResourceManager的调度延迟)、业务层(任务成功率、数据延迟、积压量)。这三个层面缺一个都不行。我见过有团队只看机器层,结果YARN队列满了都不知道,任务一直排队,用户还以为是集群挂了。
日志管理也是个大坑。大数据平台组件多,每个组件都有自己的日志,分散在各台机器上。出了问题,你得一台一台机器去翻日志,效率低到崩溃。我现在都强制要求部署时就把日志统一收集到ELK或者Splunk里,并且按组件、按时间、按级别做好索引。这样一来,排错时间至少缩短一半。有一次Hive查询突然变慢,我直接在ELK里搜HiveServer2的日志,发现是某个UDF函数触发了Full GC,五分钟就定位了问题。要是没有集中日志,估计得花半天。
说到排错,我分享一个最实用的技巧:别一上来就看日志,先看监控图表。监控图能告诉你问题是突发的还是渐进的,是某个节点的问题还是整个集群的问题。比如YARN任务大量失败,你先看ResourceManager的活跃节点数,如果节点数在波动,那可能是网络问题或者节点心跳超时;如果节点数稳定,再看具体任务的日志。这个思路能帮你少走很多弯路。
还有一个容易被忽略的坑——时钟同步。大数据平台的组件对时间非常敏感,HBase的RegionServer、Kafka的Broker、Zookeeper的会话超时,都依赖时间的一致性。我见过一个集群,各节点时间差了十几秒,结果Zookeeper频繁丢leader,Kafka的消费者组一直rebalance,整个链路都不稳定。后来统一配置了NTP,问题瞬间消失。这个坑太隐蔽了,排查了好久才找到原因。
说说升级和扩容。很多人觉得升级就是停服务、装新包、起服务,但实际没那么简单。跨大版本升级(比如从Hadoop 2.x升到3.x)时,NameNode的元数据格式可能不兼容,需要做升级前备份和回滚预案。扩容更是要谨慎,新加的DataNode要确保跟旧节点的配置一致,尤其是磁盘挂载路径、Java版本、系统参数这些,任何不一致都可能引发奇怪的问题。我习惯的做法是,扩容前先拿一台机器做预演,确认没问题再批量操作。
大数据平台的运维,说到底是个细致活。那些官方文档不会告诉你的坑,往往才是真正影响系统稳定性的关键。我踩过的坑远不止这些,但上面这几个,每一个都让我记忆深刻。如果你也在做这方面的工作,不妨对照检查一下自己的环境,看看有没有同样的问题潜伏着。部署运维这条路,没有捷径,但少踩一个坑,就多一分从容。


