跳至内容

如何通过 CloudWatch 集成发布和监控 Amazon EMR 应用程序的状态?

4 分钟阅读
0

我想将 Amazon CloudWatch 与 Amazon EMR 集成,以便发布和监控我在集群上安装的应用程序的状态。我希望 CloudWatch 在应用程序出现故障时提醒我。

简短描述

当您将 CloudWatch 与 Amazon EMR 集成时,您可以跟踪您安装的应用程序(例如 HiveServer2 和 YARN ResourceManager)的关键状态。然后,您可以将状态发布到 CloudWatch 自定义指标,并配置服务不可用警报。要跟踪其他应用程序,您可以根据需要修改应用程序列表。

解决方法

先决条件:

  • Amazon EMR 版本 5.30.0 或更高版本
  • 具有 cloudwatch:PutMetricData 权限的 Amazon EMR 实例配置文件角色或 AWS Identity and Access Management (IAM) 用户角色

创建脚本来监控您的 Amazon EMR 应用程序

您可以创建脚本来监控您的 Amazon EMR 应用程序。以下名为 check_process.sh 的示例脚本监控主节点上的 YARN ResourceManager 和 HiveServer2。该脚本还监控核心和任务 Worker 节点上的 YARN NodeManager。要监控其他应用程序,可以在脚本的 # Monitor specific services 部分下修改应用程序。

要将以下脚本配置为包含其他应用程序,请参阅创建引导操作以通过 Amazon EMR 集群安装其他软件

脚本示例:

Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  

#!/bin/bash

# Set up logging
LOG_FILE="/var/log/hadoop/service-monitor-detailed.log"
LOG_STATUS_FILE="/var/log/hadoop/service-monitor-status.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CLUSTERID=$(jq -r ".jobFlowId" < /emr/instance-controller/lib/info/extraInstanceData.json)
INSTANCEID=$(ec2-metadata -i | cut -d " " -f 2)
HOSTIP=$(hostname -i)
NODETYPE=$(cat /mnt/var/lib/instance-controller/extraInstanceData.json | jq -r '.instanceRole' | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}')

# Function to log messages
log_message() {
    echo "$TIMESTAMP - $1" >> "$LOG_FILE"
    echo "$TIMESTAMP - $1"
}

log_status_message() {
    echo "$TIMESTAMP - $1" >> "$LOG_STATUS_FILE"
}

# Function to send metric to CloudWatch
send_to_cloudwatch() {
    local host_ip=$1
    local service_name=$2
    local status=$3

    aws cloudwatch put-metric-data \
        --namespace "EMR/ServiceStatus" \
        --metric-name "ServiceStatus" \
        --value "$status" \
        --unit "Count" \
        --dimensions ClusterId=$CLUSTERID,NodeServiceName=$service_name,InstanceId=$INSTANCEID,NodeType=$NODETYPE \
        --timestamp "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
        --region "${AWS_REGION:-us-east-1}" || {
            log_message "ERROR: Failed to send metric for service $service_name"
            return 1
        }

    log_message "Successfully sent metric for service: $service_name (Status: $status)"
}

# Create log file if it doesn't exist
touch "$LOG_FILE"
touch "$LOG_STATUS_FILE"

log_message "Starting service monitoring..."

# Monitor specific services
services=(
    "hive-server2"
    "hadoop-yarn-resourcemanager"
    "hadoop-yarn-nodemanager"
)
service_names=(
    "HiveServer2"
    "YARN-ResourceManager"
    "YARN-NodeManager"
)

for i in "${!services[@]}"; do

    # Check if service is disabled as not all services are running on all nodes
    if systemctl is-enabled "${services[$i]}" 2>/dev/null | grep -q "disabled"; then
        log_message "$CLUSTERID $INSTANCEID $HOSTIP $NODETYPE ${service_names[$i]}-Status DISABLED (ignored)"
        continue
    fi

    # Get service status
    status_output=$(systemctl status "${services[$i]}" 2>/dev/null)

    # Extract the process status
    process_status=$(echo "$status_output" | grep "Active:" | sed -E 's/Active: ([^ ]+) .*/\1/' | xargs)

    # Log message
    log_message "$CLUSTERID $INSTANCEID $HOSTIP $NODETYPE ${service_names[$i]}-Status $process_status"
    log_status_message "$CLUSTERID $INSTANCEID $HOSTIP $NODETYPE ${service_names[$i]}-Status $process_status"

    # Convert status to numeric value for CloudWatch
    status_value=0
    if [ "$process_status" != "active" ]; then
        status_value=1
        # Send to CloudWatch
        send_to_cloudwatch "$HOSTIP" "${service_names[$i]}" "$status_value"
    fi

done

log_message "Service monitoring completed."

exit 0

**重要事项:**在生产环境中运行脚本之前,最佳做法是在测试环境中测试脚本。

上述脚本将自定义指标发布到 CloudWatch。AWS 按小时按比例分摊所有自定义指标费用,并仅在脚本将指标发送到 CloudWatch 时才进行计量。有关详细信息,请参阅 Amazon CloudWatch 定价

在您的 Amazon EMR 集群上配置服务监控

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

要实现自动服务监控,请使用引导操作脚本。

完成以下步骤:

  1. 要准备脚本,请运行以下 cp AWS CLI 命令将脚本上传到您的 Amazon EMR 集群可以访问的 Amazon Simple Storage Service (Amazon S3) 存储桶:

    aws s3 cp check_process.sh s3://your-bucket/monitoring/check_process.sh
  2. 要将脚本复制到每个集群节点并使用 crontab 来调度脚本,请创建与以下示例类似的引导操作脚本:

    #!/bin/bash
    
    # Copy monitoring script from S3
    aws s3 cp s3://your-bucket/monitoring/check_process.sh /home/hadoop/
    chmod +x /home/hadoop/check_process.sh
    
    # Add to crontab
    (crontab -l 2>/dev/null; echo "*/5 * * * * /home/hadoop/check_process.sh") | crontab -  

    **注意:**修改 crontab 持续时间以满足您的要求。

  3. 将引导操作脚本添加到 Amazon EMR 集群配置文件中。
    **注意:**Amazon EMR EC2 实例必须具有访问脚本所需的最低权限

  4. 启动集群

启动集群后,在集群节点上运行以下命令以确认 Amazon EMR 正确复制了脚本:

ls -l /home/hadoop/check_process.sh

要确认您已正确配置 crontab,请在集群节点上运行以下命令:

 crontab -l

查看日志

该脚本在集群节点上生成详细的日志和状态日志。要验证脚本是否正常运行,请查看这两个日志。

详细日志

/var/log/hadoop/service-monitor-detailed.log 文件提供包含时间戳、集群 ID、实例 ID、主机 IP 地址、节点类型和服务状态的全面日志。

文件示例:

2025-05-06 23:07:01 - Starting service monitoring...
2025-05-06 23:07:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master HiveServer2-Status inactive
2025-05-06 23:07:01 - Successfully sent metric for service: HiveServer2 (Status: 1)
2025-05-06 23:07:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master YARN-ResourceManager-Status active
2025-05-06 23:07:01 - Service monitoring completed.

状态日志

/var/log/hadoop/service-monitor-status.log 文件包含服务状态记录,但不包含其他元数据。

文件示例:

2025-05-06 23:07:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master HiveServer2-Status inactive
2025-05-06 23:07:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master YARN-ResourceManager-Status active
2025-05-06 23:08:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master HiveServer2-Status inactive
2025-05-06 23:08:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master YARN-ResourceManager-Status failed
2025-05-06 23:09:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master HiveServer2-Status inactive
2025-05-06 23:09:01 - j-1O1234567890 i-0a6871234567890 111.xx.xx.92 Master YARN-ResourceManager-Status failed

使用 CloudWatch 监控应用程序指标

当应用程序出现故障时,该脚本会向 CloudWatch 发送指标。

要监控指标,请完成以下步骤:

  1. 打开 CloudWatch 控制台
  2. 在导航窗格中的 Metrics(指标)下,选择 All metrics(所有指标)。
  3. Metrics(指标)下,选择 EMR/ServiceStatus,然后选择 ServiceStatus 指标。
  4. 按可用维度筛选指标: ClusterId、InstanceId、NodeServiceName 和 NodeType。

相关信息

根据静态阈值创建 CloudWatch 警报

查看并重启 Amazon EMR 和应用程序进程(进程守护程序)

AWS 官方已更新 1 年前