Last active
May 20, 2025 13:30
-
-
Save kangvcar/a589f9e0e7484ffffd6f5439a9cf7641 to your computer and use it in GitHub Desktop.
Hadoop 3.3.6 集群部署脚本
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # =================================================================== | |
| # Hadoop分布式集群自动部署脚本 v2.2 | |
| # 适用系统: CentOS 7.9 | |
| # 功能: 自动部署任意节点数量的Hadoop分布式集群(HDFS+YARN) | |
| # =================================================================== | |
| # 设置颜色代码 | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[0;33m' | |
| BLUE='\033[0;34m' | |
| CYAN='\033[0;36m' | |
| BOLD='\033[1m' | |
| NC='\033[0m' # 无颜色 | |
| # 定义进度计数器 | |
| TOTAL_STEPS=12 | |
| CURRENT_STEP=0 | |
| # 显示脚本标题 | |
| clear | |
| echo -e "${BOLD}${BLUE}" | |
| echo "==============================================================" | |
| echo " Hadoop分布式集群自动部署脚本 v2.0 " | |
| echo "==============================================================" | |
| echo -e "${NC}" | |
| echo -e "${CYAN}✨ 功能说明:${NC}" | |
| echo " 此脚本用于自动部署Hadoop 3.3.6分布式集群,适用于CentOS 7.9系统。" | |
| echo " 支持任意数量的节点,由用户指定节点数量和角色。" | |
| echo " 脚本具有幂等性,可以多次执行而不会产生问题。" | |
| echo | |
| echo -e "${CYAN}📦 部署内容:${NC}" | |
| echo " 1. 配置主机名和hosts文件 - 确保集群节点可以通过主机名互相访问" | |
| echo " 2. 设置SSH免密登录 - 实现主节点对所有节点的无密码访问" | |
| echo " 3. 安装JDK 1.8环境 - Hadoop运行的基础环境" | |
| echo " 4. 安装Hadoop 3.3.6 - 包括完整的HDFS和YARN组件" | |
| echo " 5. 自动分配节点角色 - 根据用户指定配置分布式环境" | |
| echo " 6. 同步配置到所有节点 - 确保集群配置的一致性" | |
| echo " 7. 启动完整的分布式集群 - 包括HDFS、YARN和JobHistory服务" | |
| echo | |
| echo -e "${YELLOW}⚠️ 注意事项:${NC}" | |
| echo " • 确保所有服务器能够互相访问" | |
| echo " • 确保root用户有权限执行所有操作" | |
| echo " • 确保服务器可以访问外网下载软件包" | |
| echo " • 建议使用内网IP进行集群通信,以提高性能" | |
| echo " • 主节点(master)会自动成为NameNode和ResourceManager" | |
| echo " • 最后一个节点会自动成为SecondaryNameNode" | |
| echo " • 所有节点都会成为DataNode和NodeManager" | |
| echo | |
| echo -e "${BOLD}${GREEN}按Enter键开始部署...${NC}" | |
| read | |
| # 函数定义:显示步骤信息并更新进度 | |
| show_step() { | |
| CURRENT_STEP=$((CURRENT_STEP+1)) | |
| PROGRESS=$((CURRENT_STEP*100/TOTAL_STEPS)) | |
| echo -e "\n${BOLD}${BLUE}┌─────────────────────────────────────────────────────┐${NC}" | |
| echo -e "${BOLD}${BLUE}│ [进度: ${PROGRESS}%] 步骤 ${CURRENT_STEP}/${TOTAL_STEPS}: $1${NC}" | |
| echo -e "${BOLD}${BLUE}└─────────────────────────────────────────────────────┘${NC}" | |
| } | |
| # 函数定义:显示成功信息 | |
| show_success() { | |
| echo -e "${GREEN}[✓] $1${NC}" | |
| } | |
| # 函数定义:显示错误信息 | |
| show_error() { | |
| echo -e "${RED}[✗] $1${NC}" | |
| exit 1 | |
| } | |
| # 函数定义:显示警告信息 | |
| show_warning() { | |
| echo -e "${YELLOW}[!] $1${NC}" | |
| } | |
| # 函数定义:显示信息 | |
| show_info() { | |
| echo -e "${CYAN}[i] $1${NC}" | |
| } | |
| # 函数定义:检查命令是否成功 | |
| check_success() { | |
| if [ $? -ne 0 ]; then | |
| show_error "执行命令失败: $1" | |
| else | |
| show_success "$1" | |
| fi | |
| } | |
| # 函数定义:检查节点数量是否有效 | |
| validate_node_count() { | |
| if ! [[ "$1" =~ ^[0-9]+$ ]]; then | |
| show_error "节点数量必须是数字" | |
| fi | |
| if [ "$1" -lt 1 ]; then | |
| show_error "节点数量必须大于等于1" | |
| fi | |
| } | |
| # 函数定义:SSH无密码执行命令 | |
| remote_exec() { | |
| local host=$1 | |
| local cmd=$2 | |
| sshpass -p "${NODE_PASSWORDS[$host]}" ssh -o StrictHostKeyChecking=no root@${NODE_IPS[$host]} "$cmd" > /dev/null 2>&1 | |
| return $? | |
| } | |
| # 函数定义:SSH无密码复制文件 | |
| remote_copy() { | |
| local src=$1 | |
| local host=$2 | |
| local dest=$3 | |
| sshpass -p "${NODE_PASSWORDS[$host]}" scp -o StrictHostKeyChecking=no $src root@${NODE_IPS[$host]}:$dest > /dev/null 2>&1 | |
| return $? | |
| } | |
| # 输入节点数量和信息 | |
| show_step "配置集群节点信息" | |
| read -p "请输入集群节点数量(最少1个): " NODE_COUNT | |
| validate_node_count "$NODE_COUNT" | |
| # 初始化数组来存储节点信息 | |
| declare -A NODE_IPS | |
| declare -A NODE_PASSWORDS | |
| declare -a NODE_NAMES | |
| # 第一个节点始终是master | |
| NODE_NAMES[0]="master" | |
| # 为其余节点生成名称(slave1, slave2, ...) | |
| for ((i=1; i<NODE_COUNT; i++)); do | |
| NODE_NAMES[$i]="slave$i" | |
| done | |
| # 输入每个节点的IP和密码 | |
| echo -e "${CYAN}请为每个节点输入IP地址和root密码${NC}" | |
| echo -e "${YELLOW}注意: 这些信息仅用于自动化部署,不会被保存${NC}" | |
| echo | |
| # 遍历所有节点收集信息 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| read -p "请输入${node_name}节点内网IP地址: " ip | |
| if [ -z "$ip" ]; then | |
| show_error "${node_name}的IP地址不能为空" | |
| fi | |
| NODE_IPS[$node_name]=$ip | |
| done | |
| # 询问密码设置方式 | |
| read -p "所有节点使用相同密码吗?(y/n): " same_password | |
| if [[ "$same_password" == "y" || "$same_password" == "Y" ]]; then | |
| read -sp "请输入所有节点共用的root密码: " COMMON_PASSWORD | |
| echo "" | |
| # 为所有节点设置相同的密码 | |
| for ((j=0; j<NODE_COUNT; j++)); do | |
| node_name=${NODE_NAMES[$j]} | |
| NODE_PASSWORDS[$node_name]=$COMMON_PASSWORD | |
| done | |
| else | |
| # 为每个节点单独设置密码 | |
| for ((j=0; j<NODE_COUNT; j++)); do | |
| node_name=${NODE_NAMES[$j]} | |
| read -sp "请输入${node_name}节点的root密码: " password | |
| echo "" | |
| if [ -z "$password" ]; then | |
| show_error "${node_name}的密码不能为空" | |
| fi | |
| NODE_PASSWORDS[$node_name]=$password | |
| done | |
| fi | |
| # 如果使用共同密码,确保所有节点都设置了 | |
| if [ -n "${COMMON_PASSWORD}" ]; then | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| NODE_PASSWORDS[${NODE_NAMES[$i]}]=$COMMON_PASSWORD | |
| done | |
| fi | |
| # 显示集群规划信息 | |
| echo | |
| echo -e "${CYAN}集群规划信息:${NC}" | |
| echo -e "┌───────────────┬──────────┬───────────────────────────────────────────┐" | |
| echo -e "│ IP地址 │ 主机名 │ 节点角色 │" | |
| echo -e "├───────────────┼──────────┼───────────────────────────────────────────┤" | |
| # 设置角色信息 | |
| MASTER_ROLES="NameNode, DataNode, ResourceManager, NodeManager, JobHistoryServer" | |
| SECONDARY_ROLES="DataNode, NodeManager, SecondaryNameNode" | |
| WORKER_ROLES="DataNode, NodeManager" | |
| # 显示每个节点的角色 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| node_ip=${NODE_IPS[$node_name]} | |
| # 根据节点序号设置角色 | |
| if [ $i -eq 0 ]; then | |
| # 第一个节点是master | |
| roles=$MASTER_ROLES | |
| elif [ $i -eq $((NODE_COUNT-1)) ]; then | |
| # 最后一个节点是SecondaryNameNode | |
| roles=$SECONDARY_ROLES | |
| else | |
| # 其他节点是普通工作节点 | |
| roles=$WORKER_ROLES | |
| fi | |
| # 输出节点信息 | |
| printf "│ %-13s │ %-8s │ %-43s │\n" "$node_ip" "$node_name" "$roles" | |
| if [ $i -lt $((NODE_COUNT-1)) ]; then | |
| echo -e "├───────────────┼──────────┼───────────────────────────────────────────┤" | |
| fi | |
| done | |
| echo -e "└───────────────┴──────────┴───────────────────────────────────────────┘" | |
| echo | |
| # 检查是否已安装必要工具 | |
| show_step "检查和安装必要工具" | |
| show_info "检查所需的软件包是否已安装..." | |
| # 检查是否已安装curl | |
| if ! command -v curl &> /dev/null; then | |
| show_info "正在安装curl..." | |
| yum install -y curl > /dev/null 2>&1 | |
| check_success "安装curl工具" | |
| else | |
| show_success "curl工具已安装" | |
| fi | |
| # 检查是否已安装wget | |
| if ! command -v wget &> /dev/null; then | |
| show_info "正在安装wget..." | |
| yum install -y wget > /dev/null 2>&1 | |
| check_success "安装wget工具" | |
| else | |
| show_success "wget工具已安装" | |
| fi | |
| # 检查是否已安装sshpass | |
| if ! command -v sshpass &> /dev/null; then | |
| show_info "正在安装sshpass..." | |
| yum install -y sshpass > /dev/null 2>&1 | |
| check_success "安装sshpass工具" | |
| else | |
| show_success "sshpass工具已安装" | |
| fi | |
| # 检查是否已安装expect | |
| if ! command -v expect &> /dev/null; then | |
| show_info "正在安装expect..." | |
| yum install -y expect > /dev/null 2>&1 | |
| check_success "安装expect工具" | |
| else | |
| show_success "expect工具已安装" | |
| fi | |
| # 创建hosts文件内容 | |
| show_info "创建hosts文件..." | |
| > /tmp/hadoop_hosts # 清空文件 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| node_ip=${NODE_IPS[$node_name]} | |
| echo "$node_ip $node_name" >> /tmp/hadoop_hosts | |
| done | |
| # 检查hosts文件内容是否正确 | |
| show_info "检查hosts文件格式..." | |
| cat /tmp/hadoop_hosts | |
| check_success "hosts配置文件创建成功" | |
| # 准备所有节点 | |
| show_step "配置主机名和hosts文件" | |
| show_info "开始配置所有节点的主机名和hosts文件..." | |
| # 配置本地主机 | |
| local_hostname=$(hostname) | |
| local_node_name="" | |
| # 确定本机是集群中的哪个节点 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| node_ip=${NODE_IPS[$node_name]} | |
| # 检查本机IP是否与任一节点IP匹配 | |
| for local_ip in $(hostname -I); do | |
| if [ "$local_ip" == "$node_ip" ]; then | |
| local_node_name=$node_name | |
| break | |
| fi | |
| done | |
| if [ -n "$local_node_name" ]; then | |
| break | |
| fi | |
| done | |
| # 如果找不到匹配的节点,使用master作为本地节点 | |
| if [ -z "$local_node_name" ]; then | |
| local_node_name="master" | |
| show_warning "无法确定本机是集群中的哪个节点,将默认使用master" | |
| fi | |
| # 设置本机主机名 | |
| if [[ "$local_hostname" != "$local_node_name" ]]; then | |
| show_info "设置本机主机名为$local_node_name..." | |
| hostnamectl set-hostname $local_node_name > /dev/null 2>&1 | |
| check_success "设置本机主机名" | |
| else | |
| show_success "本机主机名已正确配置为$local_node_name" | |
| fi | |
| # 更新本地hosts文件 | |
| show_info "更新本地hosts文件..." | |
| # 备份当前hosts文件 | |
| cp /etc/hosts /etc/hosts.bak | |
| # 创建新的hosts文件,保留localhost配置 | |
| cat > /etc/hosts << EOF | |
| 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 | |
| ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 | |
| # Hadoop集群节点配置 | |
| $(cat /tmp/hadoop_hosts) | |
| EOF | |
| # 检查hosts文件内容 | |
| echo "本地hosts文件内容:" | |
| cat /etc/hosts | |
| check_success "更新本地hosts文件" | |
| # 配置所有远程节点 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| # 跳过本地节点 | |
| if [ "$node_name" == "$local_node_name" ]; then | |
| continue | |
| fi | |
| show_info "配置${node_name}节点(${NODE_IPS[$node_name]})..." | |
| # 设置主机名 | |
| remote_exec $node_name "hostnamectl set-hostname $node_name" | |
| check_success "设置$node_name主机名" | |
| # 更新hosts文件 - 直接复制master节点的hosts文件 | |
| show_info "同步hosts文件到${node_name}节点..." | |
| remote_copy /etc/hosts $node_name /etc/hosts | |
| check_success "更新$node_name hosts文件" | |
| done | |
| # 测试连通性 | |
| show_info "测试节点间的网络连通性..." | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| if [ "$node_name" != "$local_node_name" ]; then | |
| ping -c 1 $node_name > /dev/null 2>&1 | |
| check_success "$local_node_name到$node_name的连通性测试" | |
| fi | |
| done | |
| # 配置SSH免密登录 | |
| show_step "配置SSH免密登录" | |
| show_info "配置SSH免密登录可实现Hadoop自动化管理..." | |
| # 检查SSH密钥是否已存在 | |
| if [ ! -f ~/.ssh/id_rsa ]; then | |
| show_info "生成SSH密钥对..." | |
| ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa > /dev/null 2>&1 | |
| check_success "生成SSH密钥" | |
| else | |
| show_success "SSH密钥已存在,无需重新生成" | |
| fi | |
| # 创建SSH免密登录脚本 | |
| cat > /tmp/ssh_copy_id.exp << EOF | |
| #!/usr/bin/expect | |
| set timeout 30 | |
| set host [lindex \$argv 0] | |
| set password [lindex \$argv 1] | |
| spawn ssh-copy-id -o StrictHostKeyChecking=no root@\$host | |
| expect { | |
| "password:" { | |
| send "\$password\r" | |
| exp_continue | |
| } | |
| "Permission denied" { | |
| exit 1 | |
| } | |
| "Number of key(s) added" { | |
| exit 0 | |
| } | |
| "already exist on the remote system" { | |
| exit 0 | |
| } | |
| eof { | |
| exit 1 | |
| } | |
| } | |
| exit 0 | |
| EOF | |
| chmod +x /tmp/ssh_copy_id.exp | |
| # 分发SSH密钥到所有节点 | |
| show_info "分发SSH密钥到所有节点..." | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| /tmp/ssh_copy_id.exp $node_name ${NODE_PASSWORDS[$node_name]} > /dev/null 2>&1 | |
| check_success "分发SSH密钥到$node_name节点" | |
| done | |
| # 测试SSH免密登录 | |
| show_info "测试SSH免密登录配置..." | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| ssh -o StrictHostKeyChecking=no $node_name "echo SSH_SUCCESS" > /dev/null 2>&1 || show_error "SSH到$node_name失败" | |
| done | |
| show_success "SSH免密登录配置成功,所有节点可以无密码访问" | |
| # 安装JDK | |
| show_step "安装Java环境" | |
| show_info "Java是Hadoop运行的基础环境..." | |
| # 创建软件目录 | |
| if [ ! -d /opt/software ]; then | |
| mkdir -p /opt/software | |
| show_success "创建软件存放目录: /opt/software" | |
| fi | |
| # 切换到软件目录 | |
| cd /opt/software | |
| # 下载JDK(如果不存在) | |
| JDK_FILE="openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz" | |
| JDK_URL="https://download.java.net/openjdk/jdk8u41/ri/$JDK_FILE" | |
| if [ ! -f "$JDK_FILE" ]; then | |
| show_info "下载OpenJDK 8u41安装包..." | |
| echo -e "${YELLOW}下载可能需要几分钟时间,请耐心等待...${NC}" | |
| # 使用wget下载 | |
| wget --no-check-certificate --progress=dot:giga $JDK_URL 2>&1 | |
| if [ -f "$JDK_FILE" ]; then | |
| check_success "下载JDK安装包完成" | |
| else | |
| show_error "下载JDK安装包失败" | |
| fi | |
| else | |
| show_success "JDK安装包已存在,无需重新下载" | |
| fi | |
| # 如果Java未安装,则安装 | |
| if [ ! -d /opt/java8 ]; then | |
| show_info "解压并安装JDK..." | |
| tar -zxf $JDK_FILE -C /opt/ > /dev/null 2>&1 | |
| check_success "解压JDK到/opt目录" | |
| # 重命名JDK目录 | |
| if [ -d /opt/java-se-8u41-ri ]; then | |
| mv /opt/java-se-8u41-ri /opt/java8 | |
| check_success "重命名JDK目录为/opt/java8" | |
| else | |
| show_error "JDK解压目录不存在,请检查安装包是否正确" | |
| fi | |
| else | |
| show_success "Java已安装在/opt/java8目录" | |
| fi | |
| # 检查环境变量 | |
| if ! grep -q "JAVA_HOME=/opt/java8" /etc/profile; then | |
| show_info "配置Java环境变量..." | |
| cat >> /etc/profile << EOF | |
| # Java环境变量 | |
| export JAVA_HOME=/opt/java8 | |
| export PATH=\$PATH:\$JAVA_HOME/bin | |
| EOF | |
| check_success "配置Java环境变量到/etc/profile" | |
| # 使环境变量生效 | |
| source /etc/profile | |
| show_info "Java环境变量已生效" | |
| fi | |
| # 验证Java安装 | |
| java -version > /dev/null 2>&1 | |
| JAVA_VERSION=$(java -version 2>&1 | head -n 1) | |
| check_success "Java环境验证成功: $JAVA_VERSION" | |
| # 安装Hadoop | |
| show_step "安装Hadoop" | |
| show_info "Hadoop是一个分布式计算框架,核心组件包括HDFS和YARN..." | |
| # 下载Hadoop(如果不存在) | |
| HADOOP_VERSION="3.3.6" | |
| HADOOP_FILE="hadoop-$HADOOP_VERSION.tar.gz" | |
| HADOOP_URL="https://mirrors.huaweicloud.com/apache/hadoop/common/hadoop-$HADOOP_VERSION/$HADOOP_FILE" | |
| if [ ! -f "$HADOOP_FILE" ]; then | |
| show_info "下载Hadoop ${HADOOP_VERSION}安装包..." | |
| echo -e "${YELLOW}下载可能需要几分钟时间,请耐心等待...${NC}" | |
| # 使用curl下载 | |
| curl -O $HADOOP_URL | |
| if [ -f "$HADOOP_FILE" ]; then | |
| check_success "下载Hadoop安装包完成" | |
| else | |
| show_error "下载Hadoop安装包失败" | |
| fi | |
| else | |
| show_success "Hadoop安装包已存在,无需重新下载" | |
| fi | |
| # 如果Hadoop未安装,则安装 | |
| if [ ! -d /opt/hadoop ]; then | |
| show_info "解压并安装Hadoop..." | |
| tar -zxf $HADOOP_FILE -C /opt/ > /dev/null 2>&1 | |
| check_success "解压Hadoop到/opt目录" | |
| # 重命名Hadoop目录 | |
| if [ -d "/opt/hadoop-$HADOOP_VERSION" ]; then | |
| mv /opt/hadoop-$HADOOP_VERSION /opt/hadoop | |
| check_success "重命名Hadoop目录为/opt/hadoop" | |
| else | |
| show_error "Hadoop解压目录不存在,请检查安装包是否正确" | |
| fi | |
| else | |
| show_success "Hadoop已安装在/opt/hadoop目录" | |
| fi | |
| # 检查环境变量 | |
| if ! grep -q "HADOOP_HOME=/opt/hadoop" /etc/profile; then | |
| show_info "配置Hadoop环境变量..." | |
| cat >> /etc/profile << EOF | |
| # Hadoop环境变量 | |
| export HADOOP_HOME=/opt/hadoop | |
| export PATH=\$PATH:\$HADOOP_HOME/bin:\$HADOOP_HOME/sbin | |
| EOF | |
| check_success "配置Hadoop环境变量到/etc/profile" | |
| # 使环境变量生效 | |
| source /etc/profile | |
| show_info "Hadoop环境变量已生效" | |
| fi | |
| # 验证Hadoop安装 | |
| hadoop version > /dev/null 2>&1 | |
| HADOOP_VERSION_INFO=$(hadoop version | head -n 1) | |
| check_success "Hadoop环境验证成功: $HADOOP_VERSION_INFO" | |
| # 配置Hadoop | |
| show_step "配置Hadoop集群" | |
| show_info "正在配置Hadoop分布式环境,包括HDFS和YARN组件..." | |
| # 创建所需的目录 | |
| show_info "创建HDFS数据目录..." | |
| mkdir -p /opt/hadoop/hdfs/name | |
| mkdir -p /opt/hadoop/hdfs/data | |
| check_success "创建NameNode和DataNode数据目录" | |
| # 获取主节点(master)的IP | |
| MASTER_IP=${NODE_IPS["master"]} | |
| # 获取SecondaryNameNode节点的名称和IP | |
| SECONDARY_NODE_NAME=${NODE_NAMES[$((NODE_COUNT-1))]} | |
| SECONDARY_NODE_IP=${NODE_IPS[$SECONDARY_NODE_NAME]} | |
| # 配置core-site.xml | |
| show_info "配置core-site.xml(核心配置文件)..." | |
| cat > /opt/hadoop/etc/hadoop/core-site.xml << EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> | |
| <configuration> | |
| <!-- 指定HDFS文件系统主节点地址和端口 --> | |
| <property> | |
| <name>fs.defaultFS</name> | |
| <value>hdfs://master:8020</value> | |
| </property> | |
| <!-- 指定Hadoop临时文件存储目录 --> | |
| <property> | |
| <name>hadoop.tmp.dir</name> | |
| <value>/opt/hadoop/hdfs/tmp</value> | |
| </property> | |
| <!-- 允许root用户通过代理访问任何主机 --> | |
| <property> | |
| <name>hadoop.proxyuser.root.hosts</name> | |
| <value>*</value> | |
| </property> | |
| <!-- 允许root用户通过代理访问任何用户组 --> | |
| <property> | |
| <name>hadoop.proxyuser.root.groups</name> | |
| <value>*</value> | |
| </property> | |
| </configuration> | |
| EOF | |
| check_success "配置core-site.xml完成" | |
| # 配置hdfs-site.xml | |
| show_info "配置hdfs-site.xml(HDFS配置文件)..." | |
| cat > /opt/hadoop/etc/hadoop/hdfs-site.xml << EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> | |
| <configuration> | |
| <!-- 设置文件块副本数量, 通常设置为节点数量的一半,最少为1 --> | |
| <property> | |
| <name>dfs.replication</name> | |
| <value>$((NODE_COUNT/2 > 0 ? NODE_COUNT/2 : 1))</value> | |
| </property> | |
| <!-- 指定NameNode元数据存储目录 --> | |
| <property> | |
| <name>dfs.namenode.name.dir</name> | |
| <value>/opt/hadoop/hdfs/name</value> | |
| <final>true</final> | |
| </property> | |
| <!-- 指定DataNode数据存储目录 --> | |
| <property> | |
| <name>dfs.datanode.data.dir</name> | |
| <value>/opt/hadoop/hdfs/data</value> | |
| <final>true</final> | |
| </property> | |
| <!-- 设置NameNode Web界面的访问地址和端口 --> | |
| <property> | |
| <name>dfs.namenode.http-address</name> | |
| <value>master:9870</value> | |
| </property> | |
| <!-- 设置SecondaryNameNode Web界面的访问地址和端口 --> | |
| <property> | |
| <name>dfs.namenode.secondary.http-address</name> | |
| <value>${SECONDARY_NODE_NAME}:9868</value> | |
| </property> | |
| <!-- 关闭HDFS权限检查,简化开发环境使用 --> | |
| <property> | |
| <name>dfs.permissions</name> | |
| <value>false</value> | |
| </property> | |
| </configuration> | |
| EOF | |
| check_success "配置hdfs-site.xml完成" | |
| # 配置mapred-site.xml | |
| show_info "配置mapred-site.xml(MapReduce配置文件)..." | |
| cat > /opt/hadoop/etc/hadoop/mapred-site.xml << EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> | |
| <configuration> | |
| <!-- 指定MapReduce程序运行在YARN上 --> | |
| <property> | |
| <name>mapreduce.framework.name</name> | |
| <value>yarn</value> | |
| </property> | |
| <!-- 设置MapReduce JobHistory Server的RPC地址和端口 --> | |
| <property> | |
| <name>mapreduce.jobhistory.address</name> | |
| <value>master:10020</value> | |
| </property> | |
| <!-- 设置MapReduce JobHistory Server的Web界面地址和端口 --> | |
| <property> | |
| <name>mapreduce.jobhistory.webapp.address</name> | |
| <value>master:19888</value> | |
| </property> | |
| <!-- 设置MapReduce ApplicationMaster的环境变量 --> | |
| <property> | |
| <name>yarn.app.mapreduce.am.env</name> | |
| <value>HADOOP_MAPRED_HOME=\${HADOOP_HOME}</value> | |
| </property> | |
| <!-- 设置Map任务的环境变量 --> | |
| <property> | |
| <name>mapreduce.map.env</name> | |
| <value>HADOOP_MAPRED_HOME=\${HADOOP_HOME}</value> | |
| </property> | |
| <!-- 设置Reduce任务的环境变量 --> | |
| <property> | |
| <name>mapreduce.reduce.env</name> | |
| <value>HADOOP_MAPRED_HOME=\${HADOOP_HOME}</value> | |
| </property> | |
| </configuration> | |
| EOF | |
| check_success "配置mapred-site.xml完成" | |
| # 配置yarn-site.xml | |
| show_info "配置yarn-site.xml(YARN资源管理配置文件)..." | |
| cat > /opt/hadoop/etc/hadoop/yarn-site.xml << EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> | |
| <configuration> | |
| <!-- 指定ResourceManager所在节点的主机名 --> | |
| <property> | |
| <name>yarn.resourcemanager.hostname</name> | |
| <value>master</value> | |
| </property> | |
| <!-- 指定NodeManager上运行的附属服务,这里配置提供MapReduce的shuffle服务 --> | |
| <property> | |
| <name>yarn.nodemanager.aux-services</name> | |
| <value>mapreduce_shuffle</value> | |
| </property> | |
| <!-- ResourceManager的RPC通信地址和端口,客户端通过该地址提交作业 --> | |
| <property> | |
| <name>yarn.resourcemanager.address</name> | |
| <value>master:8032</value> | |
| </property> | |
| <!-- ResourceManager调度器地址和端口,ApplicationMaster通过该地址申请资源 --> | |
| <property> | |
| <name>yarn.resourcemanager.scheduler.address</name> | |
| <value>master:8030</value> | |
| </property> | |
| <!-- ResourceManager资源跟踪器地址和端口,NodeManager通过该地址注册并汇报状态 --> | |
| <property> | |
| <name>yarn.resourcemanager.resource-tracker.address</name> | |
| <value>master:8031</value> | |
| </property> | |
| <!-- ResourceManager Web界面的访问地址和端口,用于监控集群和应用程序状态 --> | |
| <property> | |
| <name>yarn.resourcemanager.webapp.address</name> | |
| <value>master:8088</value> | |
| </property> | |
| <!-- 开启日志聚集功能,将分散在各个节点的日志统一收集到HDFS --> | |
| <property> | |
| <name>yarn.log-aggregation-enable</name> | |
| <value>true</value> | |
| </property> | |
| <!-- 设置聚合日志在HDFS上的保留时间,单位为秒,这里设置为7天 --> | |
| <property> | |
| <name>yarn.log-aggregation.retain-seconds</name> | |
| <value>604800</value> | |
| </property> | |
| <!-- 指定聚合日志在HDFS上的存储目录 --> | |
| <property> | |
| <name>yarn.nodemanager.remote-app-log-dir</name> | |
| <value>/tmp/logs</value> | |
| </property> | |
| <!-- 启用ResourceManager状态恢复功能,确保ResourceManager重启后能够恢复之前的应用程序状态 --> | |
| <property> | |
| <name>yarn.resourcemanager.recovery.enabled</name> | |
| <value>true</value> | |
| </property> | |
| <!-- 指定ResourceManager状态存储的实现类,这里使用基于文件系统的状态存储 --> | |
| <property> | |
| <name>yarn.resourcemanager.store.class</name> | |
| <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore</value> | |
| </property> | |
| <!-- 指定ResourceManager状态信息在HDFS上的存储路径 --> | |
| <property> | |
| <name>yarn.resourcemanager.fs.state-store.uri</name> | |
| <value>hdfs://master:8020/rmstate</value> | |
| </property> | |
| <!-- 设置YARN历史日志服务器的地址,用于访问应用程序的日志 --> | |
| <property> | |
| <name>yarn.log.server.url</name> | |
| <value>http://master:19888/jobhistory/logs</value> | |
| </property> | |
| </configuration> | |
| EOF | |
| check_success "配置yarn-site.xml完成" | |
| # 配置hadoop-env.sh | |
| show_info "配置hadoop-env.sh(Hadoop环境变量)..." | |
| # 备份原始文件 | |
| cp /opt/hadoop/etc/hadoop/hadoop-env.sh /opt/hadoop/etc/hadoop/hadoop-env.sh.bak 2>/dev/null | |
| # 添加环境配置 | |
| cat >> /opt/hadoop/etc/hadoop/hadoop-env.sh << EOF | |
| # 设置Java安装目录 | |
| export JAVA_HOME=/opt/java8 | |
| # 设置Hadoop安装目录 | |
| export HADOOP_HOME=/opt/hadoop | |
| # 设置Hadoop服务运行用户 | |
| export HDFS_NAMENODE_USER=root | |
| export HDFS_DATANODE_USER=root | |
| export HDFS_SECONDARYNAMENODE_USER=root | |
| export YARN_RESOURCEMANAGER_USER=root | |
| export YARN_NODEMANAGER_USER=root | |
| EOF | |
| check_success "配置hadoop-env.sh完成" | |
| # 配置workers文件 | |
| show_info "配置workers文件(指定所有工作节点)..." | |
| # 清空workers文件 | |
| > /opt/hadoop/etc/hadoop/workers | |
| # 将所有节点添加到workers文件 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| echo "${NODE_NAMES[$i]}" >> /opt/hadoop/etc/hadoop/workers | |
| done | |
| check_success "配置workers文件完成,添加了${NODE_COUNT}个节点" | |
| # 修复XML配置文件中的标签问题 | |
| show_info "修复XML标签..." | |
| sed -i 's/<n>/<name>/g' /opt/hadoop/etc/hadoop/*.xml | |
| sed -i 's/<\/n>/<\/name>/g' /opt/hadoop/etc/hadoop/*.xml | |
| check_success "修复XML标签完成" | |
| # 将Java和Hadoop复制到从节点 | |
| show_step "同步环境到从节点" | |
| show_info "将Java和Hadoop环境同步到所有节点,确保集群环境一致..." | |
| # 遍历所有节点 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| # 跳过本地节点 | |
| if [ "$node_name" == "$local_node_name" ]; then | |
| continue | |
| fi | |
| # 同步Java环境 | |
| show_info "同步Java环境到${node_name}节点..." | |
| if ssh $node_name "[ ! -d /opt/java8 ]" 2>/dev/null; then | |
| show_info "开始传输Java环境到${node_name}..." | |
| ssh $node_name "mkdir -p /opt" 2>/dev/null | |
| echo -ne "${YELLOW}正在传输...${NC}" | |
| scp -r /opt/java8 $node_name:/opt/ > /dev/null 2>&1 | |
| echo -e "\r${GREEN}传输完成!${NC}" | |
| check_success "复制Java到${node_name}节点" | |
| else | |
| show_success "Java已在${node_name}节点上安装" | |
| fi | |
| # 同步Hadoop环境 | |
| show_info "同步Hadoop环境到${node_name}节点..." | |
| if ssh $node_name "[ ! -d /opt/hadoop ]" 2>/dev/null; then | |
| show_info "开始传输Hadoop环境到${node_name}..." | |
| ssh $node_name "mkdir -p /opt" 2>/dev/null | |
| echo -ne "${YELLOW}正在传输Hadoop(这可能需要几分钟)...${NC}" | |
| scp -r /opt/hadoop $node_name:/opt/ > /dev/null 2>&1 | |
| echo -e "\r${GREEN}传输完成! ${NC}" | |
| check_success "复制Hadoop到${node_name}节点" | |
| else | |
| # 仅同步配置文件 | |
| show_info "Hadoop已在${node_name}上安装,仅同步配置文件..." | |
| scp -r /opt/hadoop/etc/hadoop/* $node_name:/opt/hadoop/etc/hadoop/ > /dev/null 2>&1 | |
| check_success "同步Hadoop配置到${node_name}节点" | |
| fi | |
| # 同步环境变量 | |
| show_info "同步环境变量配置到${node_name}节点..." | |
| scp /etc/profile $node_name:/etc/ > /dev/null 2>&1 | |
| check_success "复制环境变量配置到${node_name}节点" | |
| # 在从节点上创建必要的目录 | |
| show_info "在${node_name}节点上创建必要的数据目录..." | |
| ssh $node_name "mkdir -p /opt/hadoop/hdfs/data" > /dev/null 2>&1 | |
| check_success "在${node_name}上创建DataNode数据目录" | |
| # 如果是SecondaryNameNode节点,创建相应目录 | |
| if [ "$node_name" == "$SECONDARY_NODE_NAME" ]; then | |
| ssh $node_name "mkdir -p /opt/hadoop/hdfs/secondary" > /dev/null 2>&1 | |
| check_success "在${node_name}上创建SecondaryNameNode目录" | |
| fi | |
| # 在从节点上更新环境变量 | |
| show_info "在${node_name}节点上更新环境变量..." | |
| ssh $node_name "source /etc/profile" > /dev/null 2>&1 | |
| check_success "在${node_name}上更新环境变量" | |
| # 修复XML标签 | |
| show_info "修复${node_name}节点上的XML配置文件..." | |
| ssh $node_name "sed -i 's/<n>/<name>/g' /opt/hadoop/etc/hadoop/*.xml" > /dev/null 2>&1 | |
| ssh $node_name "sed -i 's/<\/n>/<\/name>/g' /opt/hadoop/etc/hadoop/*.xml" > /dev/null 2>&1 | |
| check_success "修复${node_name}上的XML配置文件" | |
| done | |
| # 格式化HDFS | |
| show_step "格式化HDFS文件系统" | |
| show_info "初始化HDFS文件系统,这是首次启动HDFS之前的必要步骤..." | |
| # 检查是否是master节点 | |
| if [ "$local_node_name" == "master" ]; then | |
| if [ ! -d /opt/hadoop/hdfs/name/current ]; then | |
| show_info "初始化NameNode..." | |
| echo -e "${YELLOW}格式化HDFS,请稍候...${NC}" | |
| hdfs namenode -format > /dev/null 2>&1 | |
| if [ $? -eq 0 ]; then | |
| check_success "格式化NameNode成功" | |
| else | |
| show_error "格式化NameNode失败,请检查配置" | |
| fi | |
| else | |
| show_warning "NameNode已格式化,跳过此步骤" | |
| show_info "如需重新格式化,请先删除目录: /opt/hadoop/hdfs/name/current" | |
| fi | |
| else | |
| show_info "本机不是master节点,跳过格式化HDFS步骤" | |
| fi | |
| # 启动Hadoop集群 | |
| show_step "启动Hadoop分布式集群" | |
| show_info "逐步启动HDFS、YARN和JobHistory服务..." | |
| # 检查是否是master节点 | |
| if [ "$local_node_name" == "master" ]; then | |
| # 启动HDFS | |
| show_info "启动HDFS文件系统..." | |
| echo -e "${YELLOW}正在启动HDFS服务(NameNode、DataNode和SecondaryNameNode)...${NC}" | |
| start-dfs.sh > /dev/null 2>&1 | |
| if [ $? -eq 0 ]; then | |
| check_success "HDFS服务启动成功" | |
| else | |
| show_warning "HDFS服务启动可能存在问题,请检查日志" | |
| fi | |
| # 启动YARN | |
| show_info "启动YARN资源管理系统..." | |
| echo -e "${YELLOW}正在启动YARN服务(ResourceManager和NodeManager)...${NC}" | |
| start-yarn.sh > /dev/null 2>&1 | |
| if [ $? -eq 0 ]; then | |
| check_success "YARN服务启动成功" | |
| else | |
| show_warning "YARN服务启动可能存在问题,请检查日志" | |
| fi | |
| # 启动JobHistory服务器 | |
| show_info "启动MapReduce作业历史服务器..." | |
| echo -e "${YELLOW}正在启动JobHistory服务器...${NC}" | |
| mapred --daemon start historyserver > /dev/null 2>&1 | |
| if [ $? -eq 0 ]; then | |
| check_success "JobHistory服务器启动成功" | |
| else | |
| show_warning "JobHistory服务器启动可能存在问题,请检查日志" | |
| fi | |
| # 等待服务完全启动 | |
| show_info "等待服务完全启动(15秒)..." | |
| for i in {1..15}; do | |
| echo -ne "${YELLOW}倒计时: $((16-i)) 秒${NC}\r" | |
| sleep 1 | |
| done | |
| echo -e "${GREEN}等待完成! ${NC}" | |
| else | |
| show_info "本机不是master节点,无法启动集群服务" | |
| show_info "请在master节点(${NODE_IPS['master']})上执行此脚本完成集群启动" | |
| fi | |
| # 验证服务是否启动 | |
| show_step "验证集群服务状态" | |
| show_info "检查各节点上的Hadoop进程是否正常运行..." | |
| # 初始化节点进程变量 | |
| declare -A NODE_PROCESSES | |
| # 获取本地节点进程 | |
| jps_output=$(source /etc/profile && jps | grep -v Jps | awk '{print $2}') | |
| NODE_PROCESSES[$local_node_name]=$(echo "$jps_output" | sort | tr '\n' ', ' | sed 's/,$//') | |
| # 如果是master节点,获取所有远程节点的进程 | |
| if [ "$local_node_name" == "master" ]; then | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| # 跳过本地节点 | |
| if [ "$node_name" == "$local_node_name" ]; then | |
| continue | |
| fi | |
| # 在远程节点上执行jps,确保先执行source /etc/profile | |
| remote_jps=$(ssh $node_name "source /etc/profile && jps" 2>/dev/null | grep -v Jps | awk '{print $2}') | |
| NODE_PROCESSES[$node_name]=$(echo "$remote_jps" | sort | tr '\n' ', ' | sed 's/,$//') | |
| done | |
| fi | |
| # 显示进程信息 | |
| echo -e "${CYAN}进程状态信息:${NC}" | |
| echo -e "┌───────────────────────────────────────────────────────────────────┐" | |
| # 遍历所有节点,显示进程信息 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| node_ip=${NODE_IPS[$node_name]} | |
| # 设置期望的进程 | |
| expected_processes="" | |
| if [ "$node_name" == "master" ]; then | |
| expected_processes="NameNode, DataNode, ResourceManager, NodeManager, JobHistoryServer" | |
| elif [ "$node_name" == "$SECONDARY_NODE_NAME" ]; then | |
| expected_processes="DataNode, NodeManager, SecondaryNameNode" | |
| else | |
| expected_processes="DataNode, NodeManager" | |
| fi | |
| # 获取实际进程,如果未获取到则显示"未知" | |
| actual_processes=${NODE_PROCESSES[$node_name]:-"未知(需在$node_name节点上运行脚本)"} | |
| # 显示节点信息 | |
| echo -e "│ ${BOLD}${node_name}节点 (${node_ip})${NC}" | |
| echo -e "│ 期望进程: ${expected_processes}" | |
| echo -e "│ 实际进程: ${actual_processes}" | |
| if [ $i -lt $((NODE_COUNT-1)) ]; then | |
| echo -e "├───────────────────────────────────────────────────────────────────┤" | |
| fi | |
| done | |
| echo -e "└───────────────────────────────────────────────────────────────────┘" | |
| echo | |
| # 检查本节点的进程状态 | |
| if [ "$local_node_name" == "master" ]; then | |
| # 检查master节点关键进程 | |
| if echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "NameNode" && | |
| echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "ResourceManager" && | |
| echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "JobHistoryServer"; then | |
| show_success "Master节点核心服务运行正常" | |
| else | |
| show_warning "Master节点部分服务可能未正常启动,请检查日志" | |
| fi | |
| # 检查其他节点 | |
| for ((i=1; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| if [ -n "${NODE_PROCESSES[$node_name]}" ]; then | |
| if [ "$node_name" == "$SECONDARY_NODE_NAME" ]; then | |
| # 检查SecondaryNameNode节点 | |
| if echo "${NODE_PROCESSES[$node_name]}" | grep -q "DataNode" && | |
| echo "${NODE_PROCESSES[$node_name]}" | grep -q "NodeManager" && | |
| echo "${NODE_PROCESSES[$node_name]}" | grep -q "SecondaryNameNode"; then | |
| show_success "${node_name}节点核心服务运行正常" | |
| else | |
| show_warning "${node_name}节点部分服务可能未正常启动,请检查日志" | |
| fi | |
| else | |
| # 检查普通工作节点 | |
| if echo "${NODE_PROCESSES[$node_name]}" | grep -q "DataNode" && | |
| echo "${NODE_PROCESSES[$node_name]}" | grep -q "NodeManager"; then | |
| show_success "${node_name}节点核心服务运行正常" | |
| else | |
| show_warning "${node_name}节点部分服务可能未正常启动,请检查日志" | |
| fi | |
| fi | |
| else | |
| show_warning "无法获取${node_name}节点的进程信息,需要在该节点上运行脚本" | |
| fi | |
| done | |
| else | |
| # 如果不是master节点,只检查本节点 | |
| if [ "$local_node_name" == "$SECONDARY_NODE_NAME" ]; then | |
| # 检查SecondaryNameNode节点 | |
| if echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "DataNode" && | |
| echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "NodeManager" && | |
| echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "SecondaryNameNode"; then | |
| show_success "${local_node_name}节点核心服务运行正常" | |
| else | |
| show_warning "${local_node_name}节点部分服务可能未正常启动,请检查日志" | |
| fi | |
| else | |
| # 检查普通工作节点 | |
| if echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "DataNode" && | |
| echo "${NODE_PROCESSES[$local_node_name]}" | grep -q "NodeManager"; then | |
| show_success "${local_node_name}节点核心服务运行正常" | |
| else | |
| show_warning "${local_node_name}节点部分服务可能未正常启动,请检查日志" | |
| fi | |
| fi | |
| show_info "要查看完整集群状态,请在master节点上运行此脚本" | |
| fi | |
| # 尝试获取公网IP | |
| if [ "$local_node_name" == "master" ]; then | |
| show_info "获取当前服务器公网IP..." | |
| MASTER_PUBLIC_IP=$(curl -s ifconfig.me 2>/dev/null || echo "无法获取公网IP") | |
| if [[ "$MASTER_PUBLIC_IP" == "无法获取公网IP" ]]; then | |
| show_warning "无法获取公网IP,请确保已开放安全组端口" | |
| MASTER_PUBLIC_IP=${NODE_IPS["master"]} | |
| else | |
| show_success "获取公网IP成功: $MASTER_PUBLIC_IP" | |
| fi | |
| else | |
| MASTER_PUBLIC_IP=${NODE_IPS["master"]} | |
| fi | |
| # 部署完成,输出集群信息 | |
| show_step "部署完成,输出集群信息" | |
| if [ "$local_node_name" == "master" ]; then | |
| show_info "恭喜!Hadoop分布式集群已成功部署,以下是集群关键信息..." | |
| else | |
| show_info "Hadoop节点已成功部署,以下是节点信息..." | |
| fi | |
| echo -e "${BOLD}${GREEN}✅ Hadoop分布式集群部署信息${NC}" | |
| echo | |
| echo -e "${BOLD}${CYAN}🖥️ 集群节点信息:${NC}" | |
| echo -e "┌───────────────────────────────────────────────────────────────────┐" | |
| # 显示每个节点的信息 | |
| for ((i=0; i<NODE_COUNT; i++)); do | |
| node_name=${NODE_NAMES[$i]} | |
| node_ip=${NODE_IPS[$node_name]} | |
| # 设置角色信息 | |
| if [ "$node_name" == "master" ]; then | |
| roles="NameNode, DataNode, ResourceManager, NodeManager, JobHistoryServer" | |
| elif [ "$node_name" == "$SECONDARY_NODE_NAME" ]; then | |
| roles="DataNode, NodeManager, SecondaryNameNode" | |
| else | |
| roles="DataNode, NodeManager" | |
| fi | |
| # 获取进程信息 | |
| processes=${NODE_PROCESSES[$node_name]:-"未获取"} | |
| # 显示节点信息 | |
| echo -e "│ ${BOLD}${node_name}节点 (${node_ip})${NC}" | |
| echo -e "│ 角色: ${roles}" | |
| echo -e "│ 运行进程: ${processes}" | |
| if [ $i -lt $((NODE_COUNT-1)) ]; then | |
| echo -e "├───────────────────────────────────────────────────────────────────┤" | |
| fi | |
| done | |
| echo -e "└───────────────────────────────────────────────────────────────────┘" | |
| echo | |
| echo -e "${BOLD}${BLUE}🌐 Web管理界面:${NC}" | |
| echo -e "┌───────────────────────────────────────────────────────────────────┐" | |
| echo -e "│ HDFS管理界面: ${BOLD}http://$MASTER_PUBLIC_IP:9870/${NC} │" | |
| echo -e "│ YARN资源管理界面: ${BOLD}http://$MASTER_PUBLIC_IP:8088/${NC} │" | |
| echo -e "│ MapReduce历史服务器: ${BOLD}http://$MASTER_PUBLIC_IP:19888/${NC} │" | |
| echo -e "└───────────────────────────────────────────────────────────────────┘" | |
| echo | |
| echo -e "${BOLD}${YELLOW}📋 常用管理命令:${NC}" | |
| echo -e "┌───────────────────────────────────────────────────────────────────┐" | |
| echo -e "│ 启动集群: ${BOLD}start-all.sh${NC} │" | |
| echo -e "│ 停止集群: ${BOLD}stop-all.sh${NC} │" | |
| echo -e "│ 单独启动HDFS: ${BOLD}start-dfs.sh${NC} │" | |
| echo -e "│ 单独停止HDFS: ${BOLD}stop-dfs.sh${NC} │" | |
| echo -e "│ 单独启动YARN: ${BOLD}start-yarn.sh${NC} │" | |
| echo -e "│ 单独停止YARN: ${BOLD}stop-yarn.sh${NC} │" | |
| echo -e "│ 启动历史服务器: ${BOLD}mapred --daemon start historyserver${NC} │" | |
| echo -e "│ 停止历史服务器: ${BOLD}mapred --daemon stop historyserver${NC} │" | |
| echo -e "│ 查看节点进程: ${BOLD}jps${NC} │" | |
| echo -e "│ 查看HDFS状态: ${BOLD}hdfs dfsadmin -report${NC} │" | |
| echo -e "│ HDFS文件操作: ${BOLD}hdfs dfs -<命令> [参数]${NC} │" | |
| echo -e "│ - 查看文件列表: ${BOLD}hdfs dfs -ls /path${NC} │" | |
| echo -e "│ - 创建目录: ${BOLD}hdfs dfs -mkdir -p /path${NC} │" | |
| echo -e "│ - 上传文件: ${BOLD}hdfs dfs -put localfile /path${NC} │" | |
| echo -e "│ - 下载文件: ${BOLD}hdfs dfs -get /path/file localpath${NC} │" | |
| echo -e "│ - 删除文件: ${BOLD}hdfs dfs -rm /path/file${NC} │" | |
| echo -e "│ - 删除目录: ${BOLD}hdfs dfs -rm -r /path${NC} │" | |
| echo -e "│ │" | |
| echo -e "│ 提交MapReduce作业: ${BOLD}hadoop jar <jar包路径> <主类> [参数]${NC} │" | |
| echo -e "│ WordCount示例: ${BOLD}hadoop jar \$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount /input /output${NC} │" | |
| echo -e "└───────────────────────────────────────────────────────────────────┘" | |
| echo | |
| echo -e "${BOLD}${GREEN}🔍 集群维护提示:${NC}" | |
| echo -e "┌───────────────────────────────────────────────────────────────────┐" | |
| echo -e "│ 1. 日志位置: ${BOLD}/opt/hadoop/logs/${NC} │" | |
| echo -e "│ 2. 配置文件位置: ${BOLD}/opt/hadoop/etc/hadoop/${NC} │" | |
| echo -e "│ 3. HDFS数据位置: ${BOLD}/opt/hadoop/hdfs/data/${NC} │" | |
| echo -e "│ 4. NameNode元数据: ${BOLD}/opt/hadoop/hdfs/name/${NC} │" | |
| echo -e "│ 5. 重启集群流程: 先执行${BOLD}stop-all.sh${NC},然后执行${BOLD}start-all.sh${NC} │" | |
| echo -e "│ 6. 检查HDFS健康状态: ${BOLD}hdfs fsck /${NC} │" | |
| echo -e "└───────────────────────────────────────────────────────────────────┘" | |
| echo | |
| # 最后的提示 | |
| if [ "$local_node_name" != "master" ]; then | |
| echo -e "${YELLOW}注意:要完成集群部署,请在master节点(${NODE_IPS['master']})上运行此脚本${NC}" | |
| echo -e "${YELLOW} 集群的启动和停止操作只能在master节点上执行${NC}" | |
| echo | |
| fi | |
| echo -e "${BOLD}${BLUE}==============================================================" | |
| echo -e " Hadoop分布式集群自动部署脚本执行完毕 " | |
| echo -e "==============================================================${NC}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment