五、ZooKeeper、Kafka、Hadoop、HBase、Spark、Flink集群化软件的部署
1.作用
一句话:集群=把多台 Linux 服务器拧成“一台大机器”,让系统更稳、更快、能随时加机器顶住流量,还能不停机维护。
主要作用(通俗说法)
- 不怕宕机(高可用):一台挂了,其他顶上;服务不中断。
- 能扛流量(横向扩展):来了更多用户,就多加几台机器分担。
- 跑得更快(并行/分片):把任务或数据切成多份同时处理。
- 维护不打扰(滚动升级):一台台升级、发版,用户基本无感。
- 数据更安全(多副本/容灾):同一份数据放多处,单点坏了不丢。
对实战项目有什么用?(直接举例)
- Web/接口服务:Nginx/HAProxy 做负载均衡,多副本应用 → 高并发不炸。
- 缓存:Redis Sentinel/Cluster → 会话共享、热点数据加速且可自动切主。
- 消息队列:RabbitMQ 集群 + quorum 队列 → 异步削峰,节点故障不丢消息。
- 搜索/日志:Elasticsearch 多节点 → 搜索快、日志检索稳定不怕单点。
- 数据库主备/读写分离:MySQL 主从或集群 → 宕机可切换,读性能提升。
2.集群化软件
分类 | 主要用途(一句话) | 常见软件(代表) | 典型场景 |
---|---|---|---|
计算/调度 | 统一调度作业与资源、弹性伸缩 | Kubernetes、YARN、Ray、Dask | 应用编排、批处理/AI 任务调度 |
消息与流 | 解耦与削峰、流式数据管道 | Kafka、Pulsar、RocketMQ | 日志/埋点、订单事件、实时 ETL |
批处理/交互式 SQL | 大数据 SQL 查询与离线分析 | Hive、Trino(Presto)、Impala | 数仓离线报表、即席查询 |
实时计算 | 低延迟流计算与复杂事件处理 | Flink、Spark Streaming、Storm | 实时看板、风控、告警 |
分布式存储/数据库 | 海量数据存储与高并发读写/分析 | HDFS、Ceph/MinIO、ClickHouse/Doris、Cassandra/TiDB | 数据湖文件、OLAP 分析、弹性数据库 |
数据湖表格式 | 为数据湖提供 ACID/时光回溯/模式演进 | Iceberg、Delta Lake、Hudi | 统一湖仓表、增量写入与回滚 |
数据集成/采集/CDC | 异构系统数据同步与变更捕获 | Kafka Connect/Debezium/Flink CDC、NiFi、Logstash/Fluentd/Filebeat | 库表同步、日志采集、实时入湖 |
元数据/权限/安全 | 数据资产、血缘与权限治理 | Hive Metastore、Atlas/DataHub、Ranger、Kerberos | 数据目录、合规审计、统一认证 |
协调/注册/配置 | 一致性、服务发现与配置中心 | ZooKeeper、etcd、Consul、Nacos/Apollo | 分布式锁、服务注册、动态配置 |
网关/负载均衡/服务网格 | 北向入口与流量治理 | Nginx、HAProxy、Envoy、Istio | 反向代理、限流熔断、灰度发布 |
监控/日志/可观测 | 指标监控、日志检索与告警 | Prometheus+Grafana、ELK/EFK、Loki | 系统健康、故障定位、告警联动 |
3.集群化环境前置准备
配置多台/Linux虚拟机
虚拟机关机,左侧栏新建一个名为“虚拟机集群”的文件夹,右键,选择管理中的克隆,创建出一个完整的克隆虚拟机(状态任选,按它默认给的就可以但要选择完整克隆),命名按序号(node1)就可以。创建成功后放入刚刚新建的文件夹中。
克隆出两台虚拟机:node2、node3(左侧目录显示 node1 / node2 / node3)。
启动 node1,把主机名改为
node1
,并把 IP 固定为192.168.88.131
:hostnamectl set-hostname node1 vim /etc/sysconfig/network-scripts/ifcfg-ens33 # 在文件中设置: IPADDR="192.168.88.131" # 重启网络 systemctl restart network # 或: systemctl stop network && systemctl start network
启动 node2 与 node3,做相同配置:
node2 主机名node2
,IP192.168.88.132
;
node3 主机名node3
,IP192.168.88.133
。在 FinalShell 中分别创建到 node1、node2、node3 的连接;提示里建议为了简单起见使用 root 用户登录。
准备主机映射名
1)Windows 上添加(如果你用 Windows 作为运维机)
- 以管理员身份打开记事本,编辑:
C:\Windows\System32\drivers\etc\hosts
- 追加三行:
192.168.88.131 node1
192.168.88.132 node2
192.168.88.133 node3
- 保存即可(若权限不够,先把文件拷到桌面改好再拷回去并覆盖)。这里是你自己设置的固定ip地址
2)Linux 上添加(3 台都要加)
sudo -i
cat >> /etc/hosts <<'EOF'
192.168.88.131 node1
192.168.88.132 node2
192.168.88.133 node3
EOF
3)设置每台机器的主机名(可选但推荐)
在 node1/node2/node3 分别执行对应主机名:
# node1 上
hostnamectl set-hostname node1
# node2 上
hostnamectl set-hostname node2
# node3 上
hostnamectl set-hostname node3
重新登录后 hostname
应显示正确。
4)验证
ping -c 2 node1
ping -c 2 node2
ping -c 2 node3
能通就说明映射生效。
配置 SSH 免密登录(key 方式)
- SSH服务是一种用于远程登录的安全认证协议
- 通过Finalshell远程连接到Linux,就是使用SSH服务
假设你想从 node1 免密到 node2、node3(也可以反向同理)。
1)在 node1 生成密钥(用哪个账号免密就在哪个账号执行)
# 不要设置密码短语,全部回车即可
ssh-keygen -t ed25519 -C "node1-key"
# 如果系统太老不支持 ed25519,用:
# ssh-keygen -t rsa -b 4096 -C "node1-key"
2)把公钥拷到 node2、node3
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@node2
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@node3
# 若是普通用户,替换 root 为你的用户名
如果没有 ssh-copy-id
,用手动方式:
# 在 node1 上
cat ~/.ssh/id_ed25519.pub
# 复制输出的整行,粘贴到 node2/node3 的 ~/.ssh/authorized_keys 里
# 并在 node2/node3 上确保权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
3)测试免密
ssh node2 # 应该直接登录而不再要密码
exit
ssh node3
exit
三、常见问题排查
权限问题(最常见)
在目标机(被登录的那台)确保:chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chown -R $(whoami):$(whoami) ~/.ssh
sshd 配置禁止了密码或公钥
查看/etc/ssh/sshd_config
:PubkeyAuthentication yes PasswordAuthentication yes # 你已能免密后可改为 no 提升安全 PermitRootLogin yes # 若用 root 登录才需要;生产建议禁用
修改后重启:
# CentOS/Rocky/AlmaLinux systemctl restart sshd # Ubuntu/Debian systemctl restart ssh
防火墙/SELinux
端口 22 要放行(或你修改的端口):
# firewalld firewall-cmd --add-service=ssh --permanent firewall-cmd --reload
SELinux 先确认状态:
getenforce
若为
Enforcing
且你做了自定义目录存放.ssh
,需正确上下文或暂时设为Permissive
进行排查(生产环境建议按规范修正上下文)。
known_hosts 冲突:IP/主机名复用导致警告,按提示到
~/.ssh/known_hosts
删除对应行或:ssh-keygen -R node2 ssh-keygen -R 192.168.88.132
端口非 22:连接时加
-p PORT
,或在~/.ssh/config
中写别名:cat >> ~/.ssh/config <<'EOF' Host node2 HostName 192.168.88.132 User root Port 22 Host node3 HostName 192.168.88.133 User root Port 22 EOF chmod 600 ~/.ssh/config
安装JDK环境(之前有写过)
scp命令
本地 -> 远程
scp [选项] local_path user@host:/remote/path
远程 -> 本地
scp [选项] user@host:/remote/path local_path
远程A -> 远程B(走本机中转)
scp -3 [选项] userA@hostA:/path userB@hostB:/path
选项 | 作用 | 典型用法 | 备注/注意 |
---|---|---|---|
-r |
递归复制目录 | scp -r ./conf root@h:/etc/app/ |
最常用;别忘了目标目录要有写权限 |
-P <port> |
指定 SSH 端口(大写 P) | scp -P 2222 file root@h:/opt/ |
常被写成小写 -p (那是“保留属性”) |
-i <key> |
指定私钥 | scp -i ~/.ssh/id_rsa pkg.tgz root@h:/opt/ |
等价于 -o IdentityFile=... |
-C |
压缩传输 | scp -C big.iso root@h:/data/ |
慢链路有用;会增加 CPU 消耗 |
-p |
保留时间戳/权限/ACL | scp -p app.sh root@h:/usr/local/bin/ |
与 rsync -a 类似的效果之一 |
-q |
静默模式 | scp -q file root@h:/tmp/ |
关掉进度条/提示 |
-o <k=v> |
传递任意 SSH 配置项 | scp -o StrictHostKeyChecking=no file root@h:/opt/ |
可设置 ConnectTimeout 、ProxyCommand 、ForwardAgent 等 |
-J <jump> |
跳板机(ProxyJump) | scp -J bastion@10.0.0.10 pkg.tgz root@10.0.0.21:/opt/ |
支持多跳:-J a,b,c |
-l <kbps> |
限速(Kbit/s) | scp -l 5000 file root@h:/data/ |
5000≈5Mb/s≈0.625MB/s |
-v |
调试输出(可叠加) | scp -vvv file root@h:/opt/ |
排查“连不上/卡住”很有用 |
-4 / -6 |
强制用 IPv4 / IPv6 | scp -4 file root@h:/opt/ |
解决 DNS 双栈解析导致的连接问题 |
-F <file> |
指定 ssh_config | scp -F ./ssh_config file hostA:/opt/ |
配合项目专用配置 |
-S <ssh_path> |
指定 ssh 程序 | scp -S /usr/local/bin/ssh file host:/ |
罕用;自定义 ssh 客户端 |
-3 |
远程A→远程B,经由本机中转 | scp -3 user1@A:/a.log user2@B:/tmp/ |
走两段链路,慢;但不需两端互通 |
-T |
关闭严格文件名检查 | scp -T host:'~/dir/*' . |
允许远端通配符展开;有风险(谨慎) |
-c <cipher> |
指定加密算法 | scp -c aes128-gcm@openssh.com ... |
极少用;一般让 ssh 自协商即可 |
-B |
批处理模式(禁止交互) | scp -B file host:/opt/ |
常与密钥/Agent 搭配,脚本中用 |
-O |
使用旧版 SCP 协议 | scp -O file host:/opt/ |
新版 OpenSSH 默认走 SFTP;兼容老服务器时用 |
- 远程到远程时若想不经本机中转,用
rsync -e ssh
的“pull/push”到一端执行,会更快;或在一端使用scp
拉/推另一端。 - 需要断点续传/只传差异时,选
rsync -avzP
更合适;scp
不支持续传。 - 路径含空格请用引号:
"path with space"
;远端路径也要加引号:host:"/tmp/my file.txt"
。
4.约定与准备
- 软件装到 /opt,数据放 /data。
- 使用 Apache 官方存档源(稳定、可复现)。
- 需要可访问外网。
- 版本:ZooKeeper 3.8.4、Kafka 3.6.1(KRaft)、Hadoop 3.3.6、HBase 2.4.17、Spark 3.5.1(hadoop3)、Flink 1.17.2(scala_2.12)。
通用基线(一次执行,后面所有组件通用)
做什么:装工具+JDK、创建目录、加环境变量(PATH)。
yum -y install epel-release wget curl tar xz unzip java-1.8.0-openjdk java-1.8.0-openjdk-devel lsof net-tools nc
mkdir -p /opt /data
cat >/etc/profile.d/bigdata.sh <<'ENV'
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export PATH=$JAVA_HOME/bin:$PATH
export ZK_HOME=/opt/zookeeper
export KAFKA_HOME=/opt/kafka
export HADOOP_HOME=/opt/hadoop
export HBASE_HOME=/opt/hbase
export SPARK_HOME=/opt/spark
export FLINK_HOME=/opt/flink
export PATH=$ZK_HOME/bin:$KAFKA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HBASE_HOME/bin:$SPARK_HOME/bin:$SPARK_HOME/sbin:$FLINK_HOME/bin:$PATH
ENV
source /etc/profile.d/bigdata.sh
小贴士:如果有防火墙,需要按端口清单放行:ZK(2181)、Kafka(9092)、Hadoop(9870/8088)、HBase(16010)、Spark(7077/8080)、Flink(8081)。
ZooKeeper(单机先跑通)
做什么:下载→配置→启动→验证。
cd /opt
wget -q https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -xzf apache-zookeeper-3.8.4-bin.tar.gz && mv apache-zookeeper-3.8.4-bin zookeeper
mkdir -p /data/zk
cat > /opt/zookeeper/conf/zoo.cfg <<'EOF'
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zk
clientPort=2181
EOF
/opt/zookeeper/bin/zkServer.sh start
echo ruok | nc 127.0.0.1 2181 # 返回 imok 即成功
变成三节点怎么做:在 zoo.cfg
末尾加
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
并在每台写入 /data/zk/myid
(分别是 1/2/3),然后分别启动。
Kafka(KRaft 模式,不依赖 ZK,最省心)
做什么:下载→改监听地址→初始化存储→启动→发消息测试。
cd /opt
wget -q https://archive.apache.org/dist/kafka/3.6.1/kafka_2.13-3.6.1.tgz
tar -xzf kafka_2.13-3.6.1.tgz && mv kafka_2.13-3.6.1 kafka
mkdir -p /data/kafka
IP=$(hostname -I | awk '{print $1}')
CFG=/opt/kafka/config/kraft/server.properties
cp -f $CFG $CFG.bak
# 关键配置:监听与对外通告地址、日志目录
sed -ri "s@^#?listeners=.*@listeners=PLAINTEXT://${IP}:9092@" $CFG
sed -ri "s@^#?advertised.listeners=.*@advertised.listeners=PLAINTEXT://${IP}:9092@" $CFG
sed -ri "s@^log.dirs=.*@log.dirs=/data/kafka/logs@" $CFG
# 初始化元数据(只第一次)
CID=$(/opt/kafka/bin/kafka-storage.sh random-uuid)
echo "$CID" >/data/kafka/cluster-id
/opt/kafka/bin/kafka-storage.sh format -t "$CID" -c $CFG
# 启动(后台)
nohup /opt/kafka/bin/kafka-server-start.sh $CFG >/var/log/kafka.out 2>&1 &
# 验证:建 topic,发/收消息
/opt/kafka/bin/kafka-topics.sh --bootstrap-server ${IP}:9092 --create --topic demo --partitions 1 --replication-factor 1
/opt/kafka/bin/kafka-console-producer.sh --broker-list ${IP}:9092 --topic demo &
/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server ${IP}:9092 --topic demo --from-beginning
变成三节点怎么做:三台都按上面装;server.properties
中设置唯一的 node.id
、controller.quorum.voters
(KRaft 集群参数),或直接用“依赖 ZK 的老模式”,在每台把 zookeeper.connect
指向你的 ZK 集群。
Hadoop(HDFS + YARN,单机伪分布式)
做什么:下载→设置 JAVA_HOME→写 4 个配置→格式化→启动→验证。
cd /opt
wget -q https://archive.apache.org/dist/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz
tar -xzf hadoop-3.3.6.tar.gz && mv hadoop-3.3.6 hadoop
echo "export JAVA_HOME=$JAVA_HOME" >> /opt/hadoop/etc/hadoop/hadoop-env.sh
mkdir -p /data/hadoop/nn /data/hadoop/dn
cat >/opt/hadoop/etc/hadoop/core-site.xml <<'EOF'
<configuration>
<property><name>fs.defaultFS</name><value>hdfs://localhost:9000</value></property>
</configuration>
EOF
cat >/opt/hadoop/etc/hadoop/hdfs-site.xml <<'EOF'
<configuration>
<property><name>dfs.replication</name><value>1</value></property>
<property><name>dfs.namenode.name.dir</name><value>file:/data/hadoop/nn</value></property>
<property><name>dfs.datanode.data.dir</name><value>file:/data/hadoop/dn</value></property>
</configuration>
EOF
cat >/opt/hadoop/etc/hadoop/yarn-site.xml <<'EOF'
<configuration>
<property><name>yarn.nodemanager.aux-services</name><value>mapreduce_shuffle</value></property>
</configuration>
EOF
cat >/opt/hadoop/etc/hadoop/mapred-site.xml <<'EOF'
<configuration>
<property><name>mapreduce.framework.name</name><value>yarn</value></property>
</configuration>
EOF
/opt/hadoop/bin/hdfs namenode -format -force
/opt/hadoop/sbin/hadoop-daemon.sh start namenode
/opt/hadoop/sbin/hadoop-daemon.sh start datanode
/opt/hadoop/sbin/yarn-daemon.sh start resourcemanager
/opt/hadoop/sbin/yarn-daemon.sh start nodemanager
# 验证:能不能在 HDFS 操作目录;能否打开 Web UI
/opt/hadoop/bin/hdfs dfs -mkdir -p /tmp && /opt/hadoop/bin/hdfs dfs -ls /
# NameNode UI: http://localhost:9870
# YARN UI: http://localhost:8088
变成三节点怎么做:把 fs.defaultFS
写成 hdfs://node1:9000
,在 node1 写 workers
列出三台主机;再用 start-dfs.sh
/start-yarn.sh
(需要 SSH 免密)。
HBase(先用 Standalone,最快上手)
做什么:下载→简单配置→启动→用 shell 验证。
cd /opt
wget -q https://archive.apache.org/dist/hbase/2.4.17/hbase-2.4.17-bin.tar.gz
tar -xzf hbase-2.4.17-bin.tar.gz && mv hbase-2.4.17 hbase
cat >/opt/hbase/conf/hbase-site.xml <<'EOF'
<configuration>
<property><name>hbase.cluster.distributed</name><value>false</value></property>
</configuration>
EOF
/opt/hbase/bin/start-hbase.sh
echo "status" | /opt/hbase/bin/hbase shell
# 试写一行
echo "create 't1','cf'; put 't1','r1','cf:c1','v'; scan 't1'" | /opt/hbase/bin/hbase shell
变成分布式怎么做:先跑好 HDFS + ZooKeeper,把 hbase-site.xml
改为:
ini复制编辑hbase.rootdir = hdfs://node1:9000/hbase
hbase.cluster.distributed = true
hbase.zookeeper.quorum = node1,node2,node3
然后 start-hbase.sh
。
Spark(Standalone)
做什么:下载→启动 master+worker→跑官方示例。
cd /opt
wget -q https://archive.apache.org/dist/spark/spark-3.5.1/spark-3.5.1-bin-hadoop3.tgz
tar -xzf spark-3.5.1-bin-hadoop3.tgz && mv spark-3.5.1-bin-hadoop3 spark
/opt/spark/sbin/start-master.sh
/opt/spark/sbin/start-worker.sh spark://localhost:7077
/opt/spark/bin/spark-submit --master spark://localhost:7077 \
--class org.apache.spark.examples.SparkPi \
/opt/spark/examples/jars/spark-examples_2.12-3.5.1.jar 100
# Master UI: http://localhost:8080
变成三节点怎么做:在 node1 的 /opt/spark/conf/slaves
写上 node2
、node3
,三台都装好后在 node1 执行 start-master.sh
+ start-slaves.sh
。
Flink(Standalone)
做什么:下载→配置 masters/workers→启动→跑示例。
cd /opt
wget -q https://archive.apache.org/dist/flink/flink-1.17.2/flink-1.17.2-bin-scala_2.12.tgz
tar -xzf flink-1.17.2-bin-scala_2.12.tgz && mv flink-1.17.2 flink
echo "localhost:8081" > /opt/flink/conf/masters
echo "localhost" > /opt/flink/conf/workers
/opt/flink/bin/start-cluster.sh
/opt/flink/bin/flink run /opt/flink/examples/batch/WordCount.jar \
--input /opt/flink/README.txt --output /tmp/wc.out
# Dashboard: http://localhost:8081
变成三节点怎么做:在 masters
写 node1:8081
,在 workers
写 node2
、node3
,三台都装好后在 node1 执行 start-cluster.sh
。
常见坑与秒级排查
- 端口不通:
ss -lntp | egrep '2181|9092|9870|8088|16010|7077|8080|8081'
看监听;放行防火墙。 - Kafka 外网/跨机连不上:
advertised.listeners
要写别人能访问到的 IP/域名。 - Hadoop 报 JAVA_HOME:确认已写入
hadoop-env.sh
。 - HBase 分布式连不上:确认 HDFS、ZK 正常,
hbase.rootdir
、quorum
写对。