距今为止,我经手搭建过的大数据平台不说上百套,也差不多覆盖了从传统制造业到互联网电商的多个行业场景。这个标题里最值得玩的其实是“排行榜”三个字——市面上讲Hadoop搭建的教程一抓一大把,但真正从企业级落地视角去捋清楚“该选哪些组件”“各自承担什么角色”“怎么搭才不至于上线后三天两头崩”的内容却不多。所以这篇文章干脆换个讲法,从企业构建大数据平台时的选型热度、组件热度、踩坑频率这几个维度做一个实战向的盘点,既讲清楚Hadoop生态的核心组件怎么选、怎么搭,也把那些文档里不会明说的经验一并抖出来。
不管你是刚接触大数据生态的学生,还是公司里被迫从零搭平台的运维开发,这篇文章都能让你少走不少弯路。我默认你已经对Linux基本操作和Java有所了解,但深度不深没关系,我尽量把每一步的关键逻辑讲到听得懂、能复现。
1. 整体设计思路:为什么Hadoop生态至今仍是企业大数据平台的底座
1.1 企业级大数据平台的需求拆解
在聊技术选型之前,得先搞清楚企业搭建大数据平台到底要解决什么问题。按我这些年接触下来的项目经验,需求无外乎就三种:
第一,数据存储的规模化。公司业务跑起来之后,MySQL、Oracle这些传统关系型数据库扛不住海量数据的存储和增长,比如一天几个TB的日志数据入库,光写入就够呛。这时候需要一套能横向扩展、能存在普通服务器上的分布式存储系统。
第二,数据处理的多样化。数据不只是结构化表格,还有日志、图片元数据、传感器报文等半结构化和非结构化数据。传统数仓对这类数据基本束手无策,而大数据平台需要一套能统一处理格式各异数据的计算框架。
第三,数据价值的在线化。数据不能光躺在那里,还要能跑出报表、支撑推荐、帮助业务做决策。这就需要平台具备离线批处理、实时计算等多种计算能力。
在这些需求的驱动下,Hadoop生态几乎成了企业构建数据平台的首选底座。原因也很直接:它把存储(HDFS)、资源调度(YARN)、计算引擎(MapReduce/Spark/Tez)分离了,可以在同一套底层存储上跑不同的计算框架,互不干扰也互为补充。这种“平台层+计算层”分离的架构,至今依然是工业级数据平台的主流范式。
1.2 组件选型热度榜:从Hadoop生态图中挑出企业真正用得上的
现在只要搜“Hadoop生态图”,能出来一大片眼花缭乱的组件,什么Flume、Sqoop、Kafka、Zookeeper、Hive、HBase、Spark、Flink、Oozie、Atlas……新手经常会陷入选择困难,感觉每一个都该上。
但企业实际落地时,真正一上来就需要部署的组件其实就那么几类。我按热度(实际项目中出现频率)排个序:
| 排名 | 组件 | 热度(我的项目中出现率) | 核心职责 |
|---|---|---|---|
| 1 | HDFS | 100% | 分布式存储底座 |
| 2 | YARN | 100% | 集群资源统一调度 |
| 3 | ZooKeeper | 90%以上 | 分布式协调服务(NameNode HA核心依赖) |
| 4 | Hive | 90%以上 | 数据仓库SQL化分析 |
| 5 | Spark | 80%以上 | 离线/实时计算引擎 |
| 6 | HBase | 60%左右 | 在线随机读写NoSQL库 |
| 7 | Kafka | 70%以上 | 数据接入管道 |
| 8 | Flume/Sqoop | 70%左右 | 离线数据导入导出 |
| 9 | Flink | 近年新增 | 实时流计算(按需求上) |
| 10 | 调度工具Azkaban/XXL-Job | 需求而定 | 定时任务编排 |
说实话,对于大多数中小型企业来说,第1、2、3、4这四项基本是标配,第5项可以按需配额。HBase和Flink这类组件要不要引入,完全看业务场景,没有场景强行堆组件只会让平台运维复杂度成倍上升。
1.3 为什么“分布式存储+计算分离”的架构能成为主流
刚接触大数据的时候,我一直有一个困惑:HDFS为什么非要搞一个NameNode来管元数据,而不是像传统文件系统一样各管各的?后来在集群数据节点越来越多之后,我才真正明白这个设计的用意。
NameNode本质上是一个“元数据服务”,它只负责记录文件被切成了多少个Block、每个Block存放在哪些DataNode上这类“关于数据的数据”,并不存储真正的文件内容。这种设计把控制流和数据流分离了:客户端读取文件时,先从NameNode拿到Block的位置清单,然后直接在DataNode之间并行传输数据块,全程不需要再过NameNode。
这样做的好处十分显著。一是压力分散,NameNode承担的只是轻量级元数据请求,高频的数据传输都发生在DataNode节点之间,数据量再大也不会把NameNode打满。二是扩展性好,DataNode增加只需要在NameNode注册,文件自动能够分布到新节点上,很容易就扩展到几百台的规模。三是容错自然,每个Block默认3副本分布在至少2个机架上,单节点磁盘损坏数据也不丢。
也正因为这些原因,虽然这些年出现了不少宣称要取代HDFS的存储方案,但真正在企业级平台里,HDFS依然是那个“睡得最安稳”的底座。
2. 环境搭建的硬核细节:从虚拟机到多节点集群的踩坑实录
2.1 服务器规划与基础环境配置
无论你手里是几台物理机还是像我经常干的在VMware里开几台虚拟机练手,合理的服务器规划是第一关。我自己的习惯是:先用3台节点搭出一个最小可用集群,规模不大但对理解分布式原理非常有效。
节点规划参考如下:
| 主机名 | 角色分配 | 硬件建议(虚拟机) |
|---|---|---|
| hadoop-01 | NameNode、ResourceManager、SecondaryNameNode | 4核8GB |
| hadoop-02 | DataNode、NodeManager | 4核4GB |
| hadoop-03 | DataNode、NodeManager | 4核4GB |
这里有个特别要提醒的坑:很多初学者图省事,把NameNode和DataNode装在同一个节点上,然后配个单机伪分布式就以为完事了。伪分布式作为学习理解原理是没问题的,但企业级平台基本不会这么搞——原因很简单,NameNode进程挂了整个集群就全挂了,DataNode进程挂了只丢一部分存储能力,两者混在一台机器上等于把单点故障放大了一倍。所以有条件的话,一定要把NameNode单独拿出来放。
基础环境配置这块,我一般按下面这个流程走:
先改主机名、配hosts映射并做免密登录。这是三大件里最基础但最容易出错的一步。hosts文件里写清楚每台机器的内网IP对应的主机名,比如:
192.168.80.10 hadoop-01 192.168.80.11 hadoop-02 192.168.80.12 hadoop-03然后生成SSH密钥并分发,确保hadoop-01能免密登录包括自己在内的所有节点。这一步没有捷径,一次配不好后面每次启动服务都要输密码,极其折磨。
# 在hadoop-01上执行 ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa ssh-copy-id hadoop-01 ssh-copy-id hadoop-02 ssh-copy-id hadoop-03很多排错半天最后定位到是SSH没配好的情况,我见了太多。所以先把免密登录测通,建议执行一句:
ssh hadoop-02 hostname能直接返回主机名,说明这个环节就过关了。
然后是JDK的安装。Hadoop 3.x要求Java 8以上,我以前图省事装过OpenJDK 11,后来因为和某些发行版兼容性问题又换回JDK 8。个人建议生产环境乖乖用Java 8,社区支持最完整。
JDK安装完成后,编辑/etc/profile或~/.bashrc添加环境变量:
export JAVA_HOME=/usr/local/jdk1.8.0_202 export PATH=$PATH:$JAVA_HOME/bin2.2 Hadoop安装与核心配置文件逐项解析
下载Hadoop这个问题,很多新手喜欢到官网找,但官网下载地址在国外,速度不稳定。我一般建议直接找国内镜像源,比如清华源或者阿里源,速度快且文件完整。版本选择上,当前主流企业用的还是3.1.x、3.2.x或3.3.x这几个稳定版本。如果你只是学习测试,我建议装3.3.4以上,不仅修复了大量已知bug,对硬件配置的要求也更友好。
下载后的安装路径,我习惯统一放在/opt目录,便于管理:
tar -zxvf hadoop-3.3.4.tar.gz -C /opt/ mv /opt/hadoop-3.3.4 /opt/hadoop然后就是核心配置文件了。等一下,我先把话说在前头:Hadoop的配置虽然不难,但每个参数的含义一定要搞懂。这个道理和装修房子一样,施工队可以替你刷墙,但哪里放插座必须你自己想明白,否则后面住进去就要后悔。
配置文件我之前在另一篇笔记里详细写过,这次直接给一套实测没问题的配置,再针对每项作说明。
core-site.xml:核心配置,重点是默认文件系统地址。
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop-01:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop/tmp</value> </property> </configuration>fs.defaultFS是HDFS的入口地址,客户端要读写数据全靠它找到NameNode。hadoop.tmp.dir是个隐藏炸弹,我之前栽过的跟头就是没有单独配置它,结果默认写到了/tmp目录,系统一重启NameNode元数据全没了,整个集群差点重新来过。这个目录必须放在数据盘,并且要提前mkdir好,同时确保hadoop用户有写权限。
hdfs-site.xml:HDFS的专属配置,重点是副本数和NameNode的元数据路径。
<configuration> <property> <name>dfs.namenode.name.dir</name> <value>/data/hadoop/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/data/hadoop/datanode</value> </property> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>hadoop-01:9868</value> </property> </configuration>副本数设置为3是默认值,也是工业界的黄金标准,一个副本在当前节点,另一个副本在同一个机架的不同节点,第三个副本在不同机架。这样任何一个机架断电或者一台服务器磁盘损坏,至少还有一份数据活着。测试环境如果机器少,副本数也可以设为2甚至1,但生产环境别低于3。
yarn-site.xml:资源调度配置。
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop-01</value> </property> <property> <name>yarn.nodemanager.env-whitelist</name> <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value> </property> </configuration>yarn.nodemanager.aux-services这个参数我记得让不少同事困惑过,它其实就是告诉NodeManager要帮MapReduce的Shuffle过程做辅助服务。没配这项的话,即使其他配置全对,跑MapReduce任务也会一直卡在提交阶段,报错还看不太明白。
mapred-site.xml:MapReduce的运行时框架配置。
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>配置完成后,还要修改hadoop-env.sh里的JAVA_HOME:
export JAVA_HOME=/usr/local/jdk1.8.0_202顺便说一句,网上有很多教程会让在hadoop-env.sh里加一堆参数,其实没必要,只确保JAVA_HOME指对就行,加太多画蛇添足的变量反而容易造成冲突。
2.3 三节点集群的标准启动流程与验证
配置写好后,不要急着直接start-dfs.sh,我的习惯是先格式化NameNode:
hdfs namenode -format格式化这个动作,我强调一下:只有第一次启动集群前需要做,以后每次重启集群都不需要也不能再做。它做的事情是生成一个空的元数据镜像文件,后续所有集群的目录结构都基于这个镜像来修改。如果哪天集群真的出了问题你想重新格式化,请先确认是“真的需要”,因为格式化后,之前HDFS上所有文件的元数据会全部丢失,数据即使还在DataNode磁盘上也读不出来了。
一次成功的格式化后,我习惯先单独启动NameNode进程看看状态,而不是直接一把梭:
# 在hadoop-01上分别启动 hdfs --daemon start namenode hdfs --daemon start secondarynamenode然后确认进程是否正常:
jps如果能看到NameNode和SecondaryNameNode这两个进程,说明元数据服务本身是健康的。再启动DataNode:
# 在hadoop-02和hadoop-03上执行 hdfs --daemon start datanode当然日常用start-dfs.sh和start-yarn.sh来批量启动其实更省事,脚本会自动通过SSH到所有slaves节点去拉起相应进程。但新手阶段我更推荐手动一个个启动,因为批量启动如果某个节点起不来,输出日志混杂在一起,非常难定位问题。
全部启动完成后,浏览器直接访问http://hadoop-01:9870,能看到NameNode的Web界面,说明HDFS基本通了。再看YARN的管理界面,访问http://hadoop-01:8088,在这里能看到集群的总资源、运行的任务、节点健康状态等信息。
上传一个小文件做验证,这个步骤千万不能省:
hdfs dfs -mkdir -p /test echo "hello hadoop" | hdfs dfs -put - /test/hello.txt hdfs dfs -cat /test/hello.txt如果能正常输出hello hadoop,这个集群存储链路就通了。
3. 核心组件的协同作战:Hive、ZooKeeper、Spark的整合实战
3.1 ZooKeeper在Hadoop HA中扮演的角色与配置要点
Hadoop生态里有一个经常被忽略但至关重要的组件——ZooKeeper。它名字听着像动物园管理员,实际干的事情也确实是“管各种分布式应用的状态”。在企业级集群里,ZooKeeper最重要的职责是帮NameNode做高可用,也就是Active/Standby模式的主备切换。
在企业集群里,NameNode如果挂了,整个HDFS就瘫痪了,所有读写全部不可用。为了不让单一节点故障拖垮整个平台,生产环境必须部署两个NameNode,一个Active接受客户端请求,一个Standby同步Active的状态。那问题来了:怎么让这两台NameNode之间保持状态一致?怎么让客户端自动连上Active的那个?
ZooKeeper就是来管这件事的。两个NameNode都在ZooKeeper里创建一个临时节点,谁创建成功谁就是Active。Active的NameNode会把每一次的元数据变更记录,通过JournalNode同步给Standby节点,确保Standby的元数据始终是最新的。一旦Active节点挂掉,它在ZooKeeper里的临时节点会超时删除,ZooKeeper立即通知Standby切换成Active。
在部署时,我用的是三台ZooKeeper节点(数量取奇数是为了选举时能多数获胜),和Hadoop集群节点复用,也就是hadoop-01~03上同时部署ZooKeeper。配置核心在zoo.cfg里:
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper clientPort=2181 server.1=hadoop-01:2888:3888 server.2=hadoop-02:2888:3888 server.3=hadoop-03:2888:3888配置完后,还要在每台机器的dataDir目录下创建一个myid文件,内容分别是1、2、3,对应上面server.1/2/3的编号。这个文件忘了建或者内容写错,集群就会一直处于Looking状态,根本选不出Leader,这个问题我遇到的频率相当高。
3.2 Hive数据仓库的部署与离线数仓分层思路
Hive这组件在Hadoop生态里地位特殊,它把SQL翻译成MapReduce/Spark/Tez任务,让数据工程师不用写Java代码也能做数据分析。一套企业级数仓平台如果不用Hive,我反而不太信,因为离线报表、ETL、大宽表计算,绝大多数还是靠Hive来执行的。
Hive部署前需要先确认MySQL已经装好,Hive的元数据(表结构、字段、分区信息)都存在MySQL里,这比存在默认的Derby里稳定得多,还能支持多客户端同时访问。配置方面核心就两块:
hive-site.xml里配置MySQL连接:
<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://hadoop-01:3306/hive?createDatabaseIfNotExist=true</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hive</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>your_password</value> </property> </configuration>第一次使用前执行schematool -dbType mysql -initSchema初始化元数据。这个命令会往MySQL里创建一堆hive相关的表,后续你在Hive里建的表、写的SQL都记录在这些表里。
数仓分层这个思路,我在实战中一直坚持“轻分层”而不是“重分层”。有些公司一上来就ODS、DWD、DWS、ADS四层铺开,结果跑到后面发现每层数据几乎没有差异,还白增了链路时延。我比较推荐三层就够:
- ODS层:直接存原始数据,保留手工查证能力;
- DWD层:清洗后明细数据,粒度最细;
- ADS层:应用汇总层,按业务口径产出指标数据。
分层架构确定好之后,Hive建表时就要按这个逻辑规划库名,比如ods_log、dwd_order_detail、ads_daily_sales,看到库名就知道数据处于哪一层。
3.3 Spark与Hive的衔接:跑批性能的关键优化
很多新人在搭建完Hive之后,跑一个几百GB的关联查询,发现慢得让人怀疑人生,于是跑来问我是不是集群配置不够。其实大概率不是硬件问题,而是默认把Hive的执行引擎配成了MapReduce。
MapReduce作为计算引擎,一个查询中间结果要落盘多次,每次Shuffle都涉及序列化、网络传输、磁盘IO,效率自然上不去。所以我在搭建时就直接把执行引擎换成Spark:
<property> <name>hive.execution.engine</name> <value>spark</value> </property>通过Spark跑Hive SQL,中间结果尽可能放在内存里,Shuffle性能提升明显,尤其对于多表关联这种操作,速度能快上几倍到十几倍。
不过Spark跑Hive SQL有一个容易踩的坑:Spark版本和Hive版本的兼容性问题,尤其是Hive on Spark用一个固定的Spark版本编译,版本不一致就会在提交任务时抛各种奇怪的ClassNotFoundException。我的建议是,安装Hive的时候直接选一个自带Spark支持的版本,或者严格按照官网兼容矩阵来匹配这两个组件的版本。
3.4 实战:Hive多数据源接入的流程与效果
近期有个项目需要把业务库里的用户订单数据和服务器上的日志文件都接入Hive做分析,我正好把完整过程整理在这里。
第一步,用Sqoop把MySQL里的数据导入Hive。Sqoop是Hadoop生态里的传统ETL工具,操作逻辑很直观:
sqoop import \ --connect jdbc:mysql://hadoop-01:3306/business \ --username root \ --password 123456 \ --table orders \ --hive-import \ --hive-table ods.orders \ --m 4上面--m 4是并行度参数,表示启动4个Map任务同时拉数据。这里有个优化点:如果表有主键,Sqoop会自动按主键范围切分任务;如果表没有主键,建议手动指定--split-by字段,否则数据会倾斜到单个Map任务上,导入速度大打折扣。
第二步,把nginx产生的访问日志放到HDFS上。日志这类数据通常是半结构化的,我习惯用Flume做准实时采集:
flume-ng agent \ -n agent_log \ -f /opt/flume/conf/log2hdfs.conf \ -Dflume.root.logger=INFO,consoleFlume的配置核心是source(读日志文件)、channel(缓冲)、sink(写HDFS)三段,其中channel可以选择用内存(快但不安全)或文件(安全但慢)。生产环境我建议用文件channel,因为日志数据不可再生,丢一条都是事故。
第三步,在Hive里建外表关联HDFS上的日志文件,完成跨源分析。这一步的巧妙之处在于,外表只是“挂”在HDFS目录上,并不移动数据,分析完成之后直接删外表并不会影响原始文件。
CREATE EXTERNAL TABLE ods.access_log ( ip STRING, request_time STRING, request_url STRING, status INT ) PARTITIONED BY (dt STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ( 'input.regex' = '^(.*?) (.*?) "(.*?)" (\\d+)' ) LOCATION '/data/flume/access_log';建好表之后,一条SQL就能把订单数据和访问日志关联起来分析用户行为路径。这种“多源数据一表分析”的能力,正是企业上大数据平台的核心价值之一。
4. 常见问题与排查技巧:高效定位并解决Hadoop集群疑难杂症
4.1 必须收藏的N个高频报错速查表
我把自己和团队在实战里遇到的高频报错整理成了一份速查表,这里直接分享给大家。解决思路比命令本身更重要,我按照“现象 -> 原因 -> 处理”的结构来写。
| 报错现象 | 根本原因 | 处理方案 |
|---|---|---|
| NameNode进程存活但Web UI打不开 | 防火墙未放行或端口配置不正确 | 检查dfs.namenode.http-address端口是9870还是50070(旧版本),并放行对应端口 |
DataNode启动失败,日志提示Incompatible clusterIDs | 多次格式化NameNode导致DataNode保存的clusterId不匹配 | 停止集群,删除DataNode的数据目录(确认无重要数据后再删),重新格式化 |
MapReduce任务提交后一直显示ACCEPTED不执行 | YARN资源不足或调度队列配置问题 | 查看ResourceManager Web UI确认可用内存和核数,检查是否有其他大任务占满资源 |
| ZooKeeper节点一直Look for leader | myid文件配置错误或节点间网络不通 | 逐台检查myid内容和ZooKeeper端口2181/2888/3888是否互通 |
Hive查询失败提示ClassNotFoundException | Hive on Spark版本不匹配 | 按兼容矩阵调整Spark版本,或检查HIVE_AUX_JARS_PATH是否引入正确依赖 |
| 磁盘空间不足导致DataNode写入失败 | 日志或临时文件堆积 | 用hdfs dfsadmin -report查看各节点空间使用,清理无用任务日志和临时目录 |
节点启动一直处于SafeMode | 每次启动后HDFS会先进入安全模式自动检查数据块完整性 | 正常情况下等一段时间会自动退出,如果一直不退,用hdfs dfsadmin -safemode leave手动退出 |
4.2 排查问题时的两个习惯,能让你少熬夜
做了这么多年运维,我总结出两条排查问题的黄金经验。
第一,遇到问题先看日志,不要凭感觉猜。Hadoop的各种进程日志默认在$HADOOP_HOME/logs目录下,NameNode日志是hadoop-hadoop-namenode-*.log,DataNode日志是hadoop-hadoop-datanode-*.log。日志文件里会明确打印异常栈,绝大多数问题的答案就在最后那几行里。我之前见过有人不看日志,凭经验改了一堆配置,折腾一下午最后发现只是一个端口被占了,这种事说出来都心疼。
第二,复现问题要从小数据集开始。大数据平台的烧脑之处在于,数据量一大,某些概率性问题就会显现,比如OOM、数据倾斜、网络超时。如果你怀疑是某一个SQL或操作导致的,先在一个小数据集上试,跑通了再把数据量加上去。这样能够快速隔离问题变量,不至于把时间浪费在大集群的日志海里。
4.3 集群日常运维的3条实用建议
最后分享几条能让集群长期稳定运行的运维经验,都是我用真金白银的时间换来的教训。
第一,构建监控体系。单靠人肉盯集群是不现实的,一定要部署监控工具,我个人用的比较多的是Prometheus加Grafana的组合,能实时看每台机器的CPU、内存、磁盘、网络以及HDFS的关键指标。监控告警至少要做到:NameNode进程挂掉、某节点磁盘使用率超85%、HDFS数据块副本数不足这三类情况能第一时间推送报警。
第二,制定备份策略。HDFS的元数据(即NameNode里的fsimage和edits文件)必须定期备份,最简单的方式是每天凌晨打包到另一台机器上。数据文件本身因为有3副本机制相对安全,但人为误删除是另一回事,所以关键表的HDFS目录建议开启回收站机制(fs.trash.interval参数,我一般设成7天)。
第三,升级和补丁要克制。很多稳定跑着的集群并不是被业务拖垮的,而是被“手痒升级”折腾挂的。生产环境的原则是:只要当前版本没有安全漏洞和致命bug,就不要频繁升级。如果要升级,先搭一套完全一样的影子集群,把所有任务跑一遍验证没问题再动生产。
结尾
前面聊了不少关于Hadoop生态的选型、部署、组件协同和故障排查的经验,这些内容本身就是我一次次“从零搭到上线”过程中踩过坑、填过土之后沉淀下来的。如果要问我搭建这么多套平台最有感触的是什么,我觉得不是记住了多少配置参数,而是理解了“为什么”。
为什么副本数默认是3、为什么NameNode要单独放一台机器、为什么Hive要把元数据放MySQL而不是Derby——每一个看起来“约定俗成”的做法背后都有真实的生产事故在支撑。这也是我写这篇文章的初衷,希望能帮准备上手Hadoop生态的朋友少走一些弯路,从一开始就避掉那些我当年深夜踩过的坑。
最后再分享一个小技巧:如果你是在Windows电脑上用VMware搭集群练手,记得把每台虚拟机的内存至少给到2GB以上,否则HDFS和YARN的进程会频繁触发OOM,你在排障上花的时间会比真正搭建的时间还多。另外,如果你打算在公司内部推广这套平台,记得先和运维团队商量好端口开放、目录挂载和告警方案——平台搭起来只是一天的事,让它稳定跑上一年才是真本事。