Hadoop 2.6.5 + Hive 1.2.1 + HBase 1.3.6 完全分布式部署实战
Hadoop 2.6.5 + Hive 1.2.1 + HBase 1.3.6 完全分布式部署实战(附 7 个踩坑复盘)
这篇写给谁:手上已经有 4 台互通的 CentOS 7 虚拟机,准备把 Hadoop 生态真正搭成一个「完全分布式」集群的同学;以及在伪分布式上跑通了、一切到多节点就各种进程起不来的同学。
前置条件(缺一项就先补,否则下面必卡):
- 4 台机器(1 主 3 从),IP 与主机名已在
/etc/hosts互解- master 到 4 台机器(含自己)的 SSH 免密已通
- firewalld 与 SELinux 已关闭,4 台时钟已同步
- 4 台都已装好 JDK 1.8 并配置
JAVA_HOME上面这四项的具体做法见上篇:VMware + CentOS 7 手把手搭建 4 节点 Linux 集群基础环境(IP 规划 / 克隆 / SSH 免密 / NTP)。本篇从「操作系统底座已就绪」开始。
版本说明:Hadoop 2.6.5 / Hive 1.2.1 / HBase 1.3.6 是 2016~2017 年的教学组合,稳定、坑位资料齐全。生产环境早已切到 Hadoop 3.x / Hive 2.x / HBase 2.x,本文命令在新版本上仍 90% 通用,差异集中在端口号和废弃参数,我在对应位置标注。
一、集群规划
先看清依赖关系,箭头从依赖方指向被依赖方,HDFS + YARN 是最底层:
Hadoop HDFS + YARN(4 节点分布式集群,存储与计算底座)
│
├── Hive(master 上跑,把 SQL 翻译成 MapReduce 作业)
│ ├── 数据存 → HDFS
│ └── 表结构/元数据存 → MariaDB(master 单机,只存元数据)
│
└── HBase(HMaster 在 master,RegionServer 在 3 个 slave)
├── 数据存 → HDFS
└── 分布式协调 → Zookeeper(3 个 slave 上的独立集群)
安装顺序绝对不能乱:先 Hadoop → 再 Hive(依赖 HDFS 和 MySQL)→ 最后 Zookeeper + HBase(依赖 HDFS 和 ZK)。
| 节点 | IP | 主机名 | 承担角色 |
|---|---|---|---|
| 主节点 | 192.168.5.100 | master | NameNode、SecondaryNameNode、ResourceManager、JobHistoryServer、MariaDB、Hive(metastore / hiveserver2)、HMaster |
| 从节点 1 | 192.168.5.101 | slave1 | DataNode、NodeManager、Zookeeper、RegionServer |
| 从节点 2 | 192.168.5.102 | slave2 | 同上 |
| 从节点 3 | 192.168.5.103 | slave3 | 同上 |
二、Hadoop 2.6.5 安装与配置
安装包 hadoop-2.6.5.tar.gz 上传到 /opt,解压:
tar -zxf hadoop-2.6.5.tar.gz -C /usr/local
之后所有配置都在 /usr/local/hadoop-2.6.5/etc/hadoop/ 下,先在 master 上改完,再整目录分发到 slave(见 2.8)。
2.1 core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/tmp</value>
</property>
</configuration>
为什么是
/data/hadoop/tmp而不是/var/log/hadoop/tmp?hadoop.tmp.dir存的是 MapReduce 临时文件、HDFS 中间快照,不是日志。放/var/log下有两个问题:CentOS 7 的 logrotate 会清理/var/log里超过 N 天的文件,可能把临时文件误删;而且/var/log权限是root:root,Hadoop 进程未必写得了。
2.2 hadoop-env.sh / yarn-env.sh / mapred-env.sh
三个文件都设 JAVA_HOME(别漏 mapred-env.sh,漏了 MapReduce 任务启动时报找不到 JAVA_HOME):
export JAVA_HOME=/usr/java/jdk1.8.0_151
2.3 hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///data/hadoop/hdfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///data/hadoop/hdfs/data</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>master:50090</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
SecondaryNameNode 为什么也在 master 上:它的职责是定期合并 NameNode 的 fsimage + edits log,NameNode 挂了可以靠它恢复。生产环境应独立到另一台机器(比如 slave1)避免单点故障;课程环境为了简化,放在 master 可接受。要改就把
dfs.namenode.secondary.http-address改成slave1:50090。
2.4 mapred-site.xml
先复制模板再改:
cp mapred-site.xml.template mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>master:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>master:19888</value>
</property>
</configuration>
2.5 yarn-site.xml
这是最容易调崩的文件。虚拟机内存紧张时用下面这套保守配置:
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>${yarn.resourcemanager.hostname}:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>${yarn.resourcemanager.hostname}:8030</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname}:8088</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>${yarn.resourcemanager.hostname}:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>${yarn.resourcemanager.hostname}:8033</value>
</property>
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/data/hadoop/yarn/local</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/data/tmp/logs</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://master:19888/jobhistory/logs/</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<!-- 内存配置:每个 NodeManager 最多给 1024MB,Map/Reduce 任务各给 512MB -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>256</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>mapreduce.map.memory.mb</name>
<value>512</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>512</value>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>1</value>
</property>
</configuration>
为什么给 1024MB 而不是 2048MB:2GB 内存的虚拟机上要同时跑 DataNode + NodeManager + HBase RegionServer 三个 JVM,NodeManager 吃 1GB、留给系统和其他进程 1GB 才不会 OOM。内存充足可以改成 2048/2048。
为什么关
vmem-check-enabled:YARN 默认按物理内存的 2.1 倍检查虚拟内存,虚拟机开了 swap 后 MapReduce 任务刚启动就被 kill 掉,报「Container killed for exceeding memory limits」。关掉即可。
2.6 slaves
编辑 slaves 文件,删掉 localhost,改为三行:
slave1
slave2
slave3
2.7 预创建数据目录(别跳,跳了 NameNode 格式化直接失败)
配置文件里写了一堆 /data/hadoop/...,但 Hadoop 不会自动创建父目录。4 个节点都要执行:
mkdir -p /data/hadoop/hdfs/name
mkdir -p /data/hadoop/hdfs/data
mkdir -p /data/hadoop/yarn/local
mkdir -p /data/tmp/logs
mkdir -p /data/hadoop/tmp
2.8 分发、启动与验证
① 分发配置(在 master 上执行):
scp -r /usr/local/hadoop-2.6.5 slave1:/usr/local
scp -r /usr/local/hadoop-2.6.5 slave2:/usr/local
scp -r /usr/local/hadoop-2.6.5 slave3:/usr/local
② 4 台机器的 /etc/profile 追加:
export HADOOP_HOME=/usr/local/hadoop-2.6.5
export PATH=$HADOOP_HOME/bin:$PATH
source /etc/profile 生效。
③ 只在 master 格式化 NameNode(整个集群生命周期只执行一次):
cd /usr/local/hadoop-2.6.5/bin
./hdfs namenode -format
# 中途会交互式询问 "Re-format filesystem in Storage Directory ...? (Y or N)",输入 Y 回车
# 看到 "Storage directory ... has been successfully formatted" 就对了
重复格式化会导致 DataNode 与 NameNode 的 clusterID 不一致,所有 DataNode 全部连不上,只能删
/data/hadoop/hdfs/name和/data/hadoop/hdfs/data重来(见坑 1)。
④ 启动:
cd /usr/local/hadoop-2.6.5/sbin
./start-dfs.sh # HDFS:NameNode + 3 DataNode + SecondaryNameNode
./start-yarn.sh # YARN:ResourceManager + 3 NodeManager
./mr-jobhistory-daemon.sh start historyserver
⑤ 进程核对(缺任何一项都别急着往下走):
jps
# master 应有:NameNode SecondaryNameNode ResourceManager JobHistoryServer
# slave 应有:DataNode NodeManager
⑥ 实质功能验证(别只看 jps,jps 有进程不代表能读写)
HDFS 写入测试:
刚启动的 HDFS 会短暂处于安全模式(只读),若
put报SafeModeException,等 30 秒,或执行hdfs dfsadmin -safemode leave强制退出。
hdfs dfs -mkdir -p /test
hdfs dfs -put /etc/profile /test/
hdfs dfs -ls /test/
hdfs dfs -cat /test/profile | head -5
MapReduce 全链路测试(HDFS 读写 + YARN 调度 + Map/Reduce 都要通才算真通):
echo -e "hello world\nhello hadoop\nhadoop hive hbase" > /tmp/words.txt
hdfs dfs -put /tmp/words.txt /test/words.txt
hadoop jar /usr/local/hadoop-2.6.5/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar \
wordcount /test/words.txt /test/out
hdfs dfs -cat /test/out/part-r-00000
# 应输出:hello 2 / hadoop 2 / hive 1 / hbase 1 / world 1
YARN 日志:
yarn logs -applicationId application_1234567890_0001 # 换成你刚跑的 WordCount ID
⑦ 浏览器验证:先在 C:\Windows\System32\drivers\etc\hosts 加 4 行映射(192.168.5.100 master 等),然后访问:
- HDFS:http://master:50070 —— Live Nodes 必须是 3
- YARN:http://master:8088 —— Nodes 必须是 3 个 RUNNING
新版本注意:Hadoop 3.x 的 HDFS Web UI 端口从 50070 改为 9870,示例 jar 文件名带新版本号(
hadoop-mapreduce-examples-3.x.x.jar)。
三、Hive 1.2.1 安装与验证
Hive 是什么:基于 HDFS 的数据仓库工具,把你写的 SQL 翻译成 MapReduce 作业跑。它不存数据——数据在 HDFS,表结构等元数据存在关系型数据库里。
3.1 安装 MariaDB(Hive 的元数据库)
CentOS 7 的 yum 源里没有 mysql-server,对应的是 MariaDB(与 MySQL 5.x 兼容,Hive 1.x 可直接用):
# 若报 "No package mariadb-server available",说明是极简安装,先装 EPEL 源:
# yum install -y epel-release
yum install mariadb-server mariadb -y
systemctl start mariadb && systemctl enable mariadb
进 mysql(CentOS 7 装完 root@localhost 是空密码,直接敲 mysql 就能进),放开远程访问并建库:
-- 1) 创建可远程登录的 root@'%'(本机 root@localhost 保持不动)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
-- 2) 建库
CREATE DATABASE IF NOT EXISTS hive DEFAULT CHARSET utf8mb4;
验证:另开终端执行
mysql -uroot -proot -h master能登录即成功。
顺序别搞反:先建新用户、确认能登录,才允许考虑清理旧用户。先DROP USER 'root'@'localhost'再建新用户、中间任何一步出错,你会被锁在 mysql 外面,只能yum reinstall mariadb-server。
3.2 安装 Hive 1.2.1
tar -zxf apache-hive-1.2.1-bin.tar.gz -C /usr/local/
进入 /usr/local/apache-hive-1.2.1-bin/conf,把 hive-env.sh.template 改名为 hive-env.sh,末尾加:
export HADOOP_HOME=/usr/local/hadoop-2.6.5
3.3 hive-site.xml + MySQL 驱动
驱动包放进 lib 目录:
cp /opt/mysql-connector-java-5.1.32-bin.jar /usr/local/apache-hive-1.2.1-bin/lib/
hive-site.xml 关键配置:
<configuration>
<!-- 元数据库连接:Hive 把表结构存在这里 -->
<property>
<!-- URL 必须写成一整行,跨行换行会把空白字符带进连接串导致参数解析失败 -->
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://master:3306/hive?createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
<!-- HDFS 上 Hive 数据仓库的位置 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- hiveserver2 Thrift 服务:Beeline 等客户端连这个 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>master</value>
</property>
<!-- metastore thrift URI:hive CLI 与 hiveserver2 都通过它访问元数据库 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://master:9083</value>
</property>
</configuration>
驱动类名看版本:Hive 1.x + MySQL 5.x 用
com.mysql.jdbc.Driver;Hive 2.x + MySQL 8.x 用com.mysql.cj.jdbc.Driver,URL 还要加serverTimezone。
3.4 处理 jline 版本冲突(不做,Hive CLI 直接报错)
真实报错长这样:
java.lang.NoSuchMethodError: jline.TerminalFactory.get(Ljava/io/InputStream;Ljava/io/OutputStream;Ljava/lang/String;)Ljline/Terminal;
at org.apache.hadoop.hive.cli.CliDriver.<init>(CliDriver.java:111)
原因:Hadoop 2.6.5 自带 jline-0.9.94,Hive 1.2.1 用 jline-2.12,方法签名不兼容。
解决(4 个节点都要做,因为 Hadoop 已分发到 slave):
mv /usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jline-0.9.94.jar \
/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/jline-0.9.94.jar.bak
cp /usr/local/apache-hive-1.2.1-bin/lib/jline-2.12.jar \
/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/
scp /usr/local/apache-hive-1.2.1-bin/lib/jline-2.12.jar \
slave1:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/
scp /usr/local/apache-hive-1.2.1-bin/lib/jline-2.12.jar \
slave2:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/
scp /usr/local/apache-hive-1.2.1-bin/lib/jline-2.12.jar \
slave3:/usr/local/hadoop-2.6.5/share/hadoop/yarn/lib/
3.5 环境变量 + 元数据库初始化
/etc/profile 追加:
export HIVE_HOME=/usr/local/apache-hive-1.2.1-bin
export PATH=$HIVE_HOME/bin:$PATH
source /etc/profile 后初始化元数据库:
cd /usr/local/apache-hive-1.2.1-bin/bin
./schematool -dbType mysql -initSchema
报错对照:
| 报错 | 原因 |
|---|---|
Access denied for user | MySQL 权限没放开,重跑 GRANT |
ClassNotFoundException: com.mysql.jdbc.Driver | 驱动 jar 没放进 lib 目录 |
Unknown database 'hive' | 自动建库没生效,手动 CREATE DATABASE hive |
3.6 启动与验证
确保 Hadoop 已启动,然后:
# 先启 metastore(hiveserver2 依赖它)
nohup hive --service metastore > /tmp/metastore.log 2>&1 &
# 再启 hiveserver2(Beeline/JDBC 客户端连这个)
nohup hive --service hiveserver2 > /tmp/hiveserver2.log 2>&1 &
jps # master 上会多出两个 RunJar 进程
# metastore 和 hiveserver2 都是以 hadoop jar 方式启动的,jps 里都显示 RunJar,
# 不会出现叫 HiveMetaStore / HiveServer2 的进程名
验证一:hive CLI
准备 /opt/test.txt:
I am a student
I learn hadoop
I learn MapReduce
进 hive 执行:
DROP TABLE IF EXISTS words;
CREATE TABLE words(textline STRING);
LOAD DATA LOCAL INPATH '/opt/test.txt' INTO TABLE words;
SET hive.cli.print.header=true;
SELECT word, COUNT(*) AS wordcount
FROM (SELECT explode(split(textline, ' ')) AS word FROM words) tmp
GROUP BY word;
预期输出:
word wordcount
I 3
MapReduce 1
a 1
am 1
hadoop 1
learn 2
student 1
验证二:Beeline(推荐,hive CLI 在 Hive 2.x 已废弃)
# hiveserver2 默认不启用认证,-n/-p 填什么都行,甚至可以不写
beeline -u jdbc:hive2://master:10000/default -n root -p root
新版本注意:Hive 2.x 把 hive CLI 标记为废弃,Hive 3.x 彻底移除,只能用 Beeline。
四、Zookeeper 3.4.6 + HBase 1.3.6
为什么要 Zookeeper:HBase 的 HMaster 选举、RegionServer 心跳、Region 一致性同步全靠 ZK 协调,没有 ZK 起不来。3 节点是最小奇数集群(能容忍 1 台挂掉)。
4.1 Zookeeper 集群(部署在 slave1~3)
在 slave1 上操作:
tar -zxf /opt/zookeeper-3.4.6.tar.gz -C /usr/local/
cd /usr/local/zookeeper-3.4.6/conf
cp zoo_sample.cfg zoo.cfg
zoo.cfg:
# 数据目录(存快照和 myid 文件)
dataDir=/usr/lib/zookeeper
# 事务日志目录(最好与 dataDir 分盘,虚拟机无所谓)
dataLogDir=/var/log/zookeeper
clientPort=2181
tickTime=2000
# 选主超时 = tickTime × initLimit
initLimit=5
# 同步超时 = tickTime × syncLimit
syncLimit=2
server.1=slave1:2888:3888
server.2=slave2:2888:3888
server.3=slave3:2888:3888
各从节点创建目录并写 myid(数字必须与 server.N 的编号严格一致):
mkdir -p /usr/lib/zookeeper
mkdir -p /var/log/zookeeper
echo "1" > /usr/lib/zookeeper/myid # slave1
echo "2" > /usr/lib/zookeeper/myid # slave2
echo "3" > /usr/lib/zookeeper/myid # slave3
分发到 slave2、slave3:
scp -r /usr/local/zookeeper-3.4.6 slave2:/usr/local/
scp -r /usr/local/zookeeper-3.4.6 slave3:/usr/local/
各从节点 /etc/profile 追加:
export ZK_HOME=/usr/local/zookeeper-3.4.6
export PATH=$PATH:$ZK_HOME/bin
启动(没有一键启动脚本,要在每个从节点手动执行):
zkServer.sh start
# 启动后立即检查选举
zkServer.sh status
# 一个 Mode: leader,两个 Mode: follower
踩坑预警:三个节点都显示
Mode: looking就是选不出 leader,90% 是 myid 写错(比如 slave2 里写成了 1),其次是 2888/3888 端口被防火墙/SELinux 拦。
4.2 HBase 1.3.6 配置
tar -zxvf /opt/hbase-1.3.6-bin.tar.gz -C /usr/local
cd /usr/local/hbase-1.3.6/conf
hbase-site.xml
<configuration>
<!-- 数据存在 HDFS 上,路径随意,HBase 会自己建 -->
<property>
<name>hbase.rootdir</name>
<value>hdfs://master:8020/hbase</value>
</property>
<!-- 老教程常见的 hbase.master 属性在 0.96+ 已废弃,写上无害但不起作用;
HMaster 位置由「在哪台机器执行 start-hbase.sh」决定,可整段删掉 -->
<property>
<name>hbase.master</name>
<value>master</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2181</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>slave1,slave2,slave3</value>
</property>
<!-- ZK session 超时(毫秒),180000 = 3 分钟,合理值。
很多老教程写 60000000(16 小时),那是明显写错了 -->
<property>
<name>zookeeper.session.timeout</name>
<value>180000</value>
</property>
<property>
<name>dfs.support.append</name>
<value>true</value>
</property>
<!-- 容忍的节点时钟偏差(毫秒)。默认只有几十秒(30~60s,版本而异),
虚拟机时钟漂移大,这里放宽到 150000(150 秒)。
这也是上一篇必须配 NTP 的原因:超阈值 RegionServer 会主动退出 -->
<property>
<name>hbase.master.maxclockskew</name>
<value>150000</value>
</property>
</configuration>
hbase-env.sh
# JDK 8 已移除永久代,PermSize 会产生大量警告,注释掉
# export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
# export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
export HBASE_CLASSPATH=/usr/local/hadoop-2.6.5/etc/hadoop
export JAVA_HOME=/usr/java/jdk1.8.0_151
# false = 使用独立部署的 ZK 集群;true = HBase 自带单机 ZK
# 集群模式必须 false,否则 RegionServer 只连本机 ZK
export HBASE_MANAGES_ZK=false
# 内存紧张时限制 HBase 堆内存(默认 1G,2GB 机器建议 512m,
# 否则 DataNode + NodeManager + RegionServer 三个 JVM 会把内存挤爆)
export HBASE_HEAPSIZE=512
regionservers
slave1
slave2
slave3
分发与环境变量:
scp -r /usr/local/hbase-1.3.6/ slave1:/usr/local/
scp -r /usr/local/hbase-1.3.6/ slave2:/usr/local/
scp -r /usr/local/hbase-1.3.6/ slave3:/usr/local/
4 台 /etc/profile 追加:
export HBASE_HOME=/usr/local/hbase-1.3.6
export PATH=$PATH:$HBASE_HOME/bin
4.3 启动与验证
启动顺序:Hadoop → Zookeeper → HBase(前两者必须先就绪):
cd /usr/local/hbase-1.3.6/bin/
./start-hbase.sh
# 在 master 上启 HMaster → 遍历 regionservers 文件在每个 slave 上启 RegionServer
进程核对:
jps
# master 应有:HMaster
# slave1~3 应有:HRegionServer + DataNode + NodeManager + QuorumPeerMain(ZK)
RegionServer 没起来时的排查顺序:
- 看日志:
tail -200 /usr/local/hbase-1.3.6/logs/hbase-*-regionserver-*.log - 90% 是时钟偏差 →
date对比各节点 →ntpdate master - 其次 HDFS 连不上 →
hdfs dfs -ls /验证 - 再次 ZK 连不上 →
zkServer.sh status验证选举
HBase shell 功能验证(别只看浏览器首页):
hbase shell
# 建表:info 存个人信息,score 存成绩
create 'student', 'info', 'score'
# 插入
put 'student', '1001', 'info:name', 'zhangsan'
put 'student', '1001', 'info:age', '20'
put 'student', '1001', 'score:math', '85'
put 'student', '1001', 'score:english', '90'
put 'student', '1002', 'info:name', 'lisi'
put 'student', '1002', 'info:age', '21'
# 查询
scan 'student'
get 'student', '1001'
count 'student'
# 删除列 / 删除行
delete 'student', '1001', 'info:age'
deleteall 'student', '1001'
# 删表(先 disable 再 drop)
disable 'student'
drop 'student'
浏览器验证 HMaster 状态页:http://192.168.5.100:16010
五、踩坑复盘(7 个)
环境层的坑(克隆后 MAC 没改、master 没对自己免密、SELinux 没关)在上一篇里已写,本篇只覆盖大数据组件相关的。
坑 1:NameNode 重复格式化 → DataNode 全部连不上
- 现象:slave 的
jps没有 DataNode,master 有 NameNode 但 Web UI 里 Live Nodes = 0。 - 原因:格式化会生成 clusterID 写进
/data/hadoop/hdfs/name/current/VERSION,DataNode 启动时比对自身 VERSION 里的 clusterID,不一致就拒绝注册。 - 解决:
rm -rf /data/hadoop/hdfs/*(4 台都清),再执行一次hdfs namenode -format。格式化命令一辈子只跑一次。
坑 2:jline 冲突 → Hive CLI 启动直接报错
- 现象:执行
hive抛NoSuchMethodError: jline.TerminalFactory.get(...)。 - 原因:Hadoop 2.6.5 的
jline-0.9.94与 Hive 1.2.1 的jline-2.12方法签名不兼容。 - 解决:备份旧 jar、拷入新 jar,4 个节点都要替换(Hadoop 早已分发到 slave)。
坑 3:schematool -initSchema 初始化失败
- 现象:报
Access denied/ClassNotFoundException/Unknown database。 - 原因:MySQL 权限未放开 / 驱动 jar 位置不对 / hive 库没建。
- 解决:
mysql -uroot -proot -h master验证远程登录 → 确认 lib 目录有mysql-connector-java-*.jar→ 手动CREATE DATABASE hive。
坑 4:Zookeeper myid 写错 → 三个节点永远 looking
- 现象:
zkServer.sh status全是Mode: looking,选不出 leader。 - 原因:myid 必须与
server.N对应(slave2 必须写 2)。 - 解决:
cat /usr/lib/zookeeper/myid逐个核对 → 改对 →zkServer.sh restart。
坑 5:HBase RegionServer 启动 10 秒后自己退出
- 现象:slave 上
jps有 HRegionServer 但很快消失,日志里ClockOutOfSyncException或Master rejected node。 - 原因:节点时钟偏差超过
hbase.master.maxclockskew(默认只有几十秒,本文已放宽到 150 秒)。 - 解决:各节点
ntpdate master同步 →date确认差在 2 分钟内 → 重启 HBase。
坑 6:YARN 内存配置太小 → MapReduce 容器被杀
- 现象:WordCount 跑到一半 FAILED,诊断信息
Container killed by YARN for exceeding memory limits。 - 原因:NodeManager 可分配内存小于任务申请值,或虚拟内存检查(vmem)拦截。
- 解决:满足
yarn.nodemanager.resource.memory-mb≥yarn.scheduler.maximum-allocation-mb≥mapreduce.map/reduce.memory.mb,并设yarn.nodemanager.vmem-check-enabled=false。
坑 7:升级到 Hadoop 3 / Hive 2 / HBase 2 的兼容问题
- 端口:Hadoop 3 的 HDFS Web UI 从 50070 改为 9870。
- CLI:Hive 2.x 起 hive CLI 废弃,Hive 3.x 移除,只能用 Beeline。
- 驱动:MySQL 8 用
com.mysql.cj.jdbc.Driver并补serverTimezone;但schematool -dbType仍写mysql(没有 mysql8 这个值)。 - 其他:HBase 2.x 要求 JDK 8+,协处理器等部分 API 与 1.x 不兼容。
六、启动顺序速查与小结
启动顺序
| 步骤 | 在哪执行 | 命令 | 验证 |
|---|---|---|---|
| 1. HDFS | master | start-dfs.sh | jps 有 NameNode + SecondaryNameNode,slave 有 DataNode;master:50070 Live Nodes=3 |
| 2. YARN | master | start-yarn.sh + mr-jobhistory-daemon.sh start historyserver | jps 有 ResourceManager,slave 有 NodeManager;master:8088 Nodes=3 RUNNING |
| 3. MariaDB | master | systemctl start mariadb | mysql -uroot -proot -h master 能登录 |
| 4. Zookeeper | slave1~3 | zkServer.sh start | 一 leader 两 follower |
| 5. Hive | master | hive --service metastore & + hiveserver2 & | jps 多出两个 RunJar;beeline 能连 |
| 6. HBase | master | start-hbase.sh | jps 有 HMaster,slave 有 HRegionServer;master:16010 正常 |
关闭顺序反过来:HBase → Zookeeper → YARN → HDFS。
部署完你得到了什么
jps里能看到十几个 Java 进程在跑,4 个 Web UI:HDFS(50070)、YARN(8088)、JobHistory(19888)、HBase(16010)- HDFS 能存文件、YARN 能调度 MapReduce、Hive 能写 SQL 查 HDFS、HBase 能做 KV 读写
- 更重要的是理解了依赖关系:HBase 的数据在 HDFS、协调在 ZK;Hive 的数据在 HDFS、元数据在 MariaDB
伪分布式是「一台机器上每个组件各起一个进程」,完全分布式是「多台机器各司其职」。区别不在性能,而在于理解了分布式本身:为什么要规划节点、为什么组件之间要协调、为什么一台挂了服务还能继续——这些是伪分布式教不了的。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)