五、ZooKeeper、Kafka、Hadoop、HBase、Spark、Flink集群化软件的部署

发布于:2025-08-16 ⋅ 阅读:(16) ⋅ 点赞:(0)

五、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)就可以。创建成功后放入刚刚新建的文件夹中。

  • 克隆出两台虚拟机:node2node3(左侧目录显示 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
    
  • 启动 node2node3,做相同配置:
    node2 主机名 node2,IP 192.168.88.132
    node3 主机名 node3,IP 192.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/ 可设置 ConnectTimeoutProxyCommandForwardAgent
-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.idcontroller.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,在 node1workers 列出三台主机;再用 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 写上 node2node3,三台都装好后在 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

变成三节点怎么做:在 mastersnode1:8081,在 workersnode2node3,三台都装好后在 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.rootdirquorum 写对。

网站公告

今日签到

点亮在社区的每一天
去签到