[INFRA] EMR集群CWagent组件功能和运行原理分析

请注意本文部分内容经过AI辅助生成,虽然经过笔者检查但是并不保证内容的正确性,请自行判断准确性,本文对相关后果不承担责任

本文主要讲述 EMR 集群中的 CloudWatch Agent组件。CWAgent 是负责采集操作系统级别指标(CPU、内存、磁盘、网络等)并发送到 CloudWatch Metrics 的守护进程。它和 MetricsCollector 的职责完全不同:MC 采集的是 YARN/HDFS 应用指标用于 Managed Scaling 决策,而 CWAgent 采集的是 OS 系统指标用于监控告警。

这是理解 EMR 指标体系最关键的一点:

复制代码
路径 1: cloudwatch-sink → MC → EMR 控制面 (Managed Scaling 决策用)
        HDFS/YARN 应用指标,不出现在 CloudWatch 控制台

路径 2: CWAgent → CloudWatch Metrics (监控告警用)
        OS 系统指标 (CPU/内存/磁盘/网络),出现在 CloudWatch 控制台
        namespace=CWAgent

本文的测试环境是emr7.12版本,在创建集群时启用了cloudwatch agent组件,细节如下

CWAgent 的版本号是 CWAgent/1.300032.2-EMR.0,RPM 包是 emr-amazon-cloudwatch-agent-1.300032.2.amzn.0-1.amzn2023.x86_64。它是一个 Go 原生进程(不是 Java),内存占用约 45MB,比 Java 组件轻量得多。

它运行在 EMR 集群的每个节点上(Master 和 Worker 都运行),EMR 版本在标准 CWAgent 基础上增加了:

  • EMR 专用配置(自动注入 cluster.idinstance.id、node.type 维度)
  • OTLP gRPC 接收器(接收 Hadoop 组件通过 cloudwatch-sink 推送的指标)
  • TLS 加密的跨节点指标传输

关键特性:

特性 说明
所有节点运行 Master(node.type=master)和 Worker(node.type=core/task)
60 秒采集 系统指标每 60 秒采集一次
Go 原生进程 非 Java,内存占用约 45MB
双管道架构 Telegraf 采集器 + OpenTelemetry Collector 管道
OTLP 接收 监听 4317(本地) / 4318(TLS) 端口接收 Hadoop 组件指标
CloudWatch 输出 指标发送到 CloudWatch Metrics,namespace=CWAgent

进程信息

bash 复制代码
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent \
  -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml \
  -envconfig /opt/aws/amazon-cloudwatch-agent/etc/env-config.json \
  -otelconfig /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.yaml \
  -pidfile /opt/aws/amazon-cloudwatch-agent/var/amazon-cloudwatch-agent.pid

systemd 服务配置

ini 复制代码
[Unit]
Description=Amazon CloudWatch Agent
After=network.target

[Service]
Type=simple
ExecStart=/opt/aws/amazon-cloudwatch-agent/bin/start-amazon-cloudwatch-agent
KillMode=process
Restart=on-failure
RestartSec=60s

[Install]
WantedBy=multi-user.target

注意:与 MetricsCollector 不同,CWAgent 没有 MemoryMax/CPUQuota 限制。

采集的系统指标(34 个)

CPU 指标(11 个)

指标 说明
cpu_usage_active CPU 活跃使用率
cpu_usage_idle CPU 空闲率
cpu_usage_user 用户态 CPU
cpu_usage_system 内核态 CPU
cpu_usage_iowait I/O 等待
cpu_usage_steal 被虚拟化偷取的 CPU
cpu_usage_irq 硬中断
cpu_usage_softirq 软中断
cpu_usage_nice nice 进程
cpu_usage_guest 虚拟机 guest
cpu_usage_guest_nice 虚拟机 guest nice

采集粒度:percpu=true(每个 CPU 核心)+ totalcpu=true(汇总)

内存指标(10 个)

指标 说明
mem_active 活跃内存
mem_available 可用内存
mem_available_percent 可用内存百分比
mem_free 空闲内存
mem_inactive 非活跃内存
mem_total 总内存
mem_used 已用内存
mem_used_percent 已用内存百分比
mem_buffered 缓冲区内存
mem_cached 缓存内存

磁盘指标(4 个)

指标 说明
disk_free 磁盘可用空间
disk_total 磁盘总空间
disk_used 磁盘已用空间
disk_used_percent 磁盘使用率

采集粒度:resources=["*"](所有挂载点)

网络指标(4 个)

指标 说明
net_bytes_recv 接收字节数
net_bytes_sent 发送字节数
net_packets_recv 接收包数
net_packets_sent 发送包数

网络指标经过 cumulativetodelta 处理器转换为增量值。

Swap 指标(3 个)

指标 说明
swap_free Swap 可用
swap_used Swap 已用
swap_used_percent Swap 使用率

进程指标(2 个)

指标 说明
processes_running 运行中进程数
processes_total 总进程数

CloudWatch 维度

每个指标都附带以下维度,用于在 CloudWatch 中过滤和聚合:

维度 Master 值 Worker 值
cluster.id j-2Y8SIX4Q4K5ZJ j-2Y8SIX4Q4K5ZJ
instance.id i-07a7bdb3b2bd9b410 (各节点实例 ID)
node.type master core / task
service.name system system

聚合维度配置:[cluster.id, instance.id, node.type, service.name]

双管道(Pipeline)架构

CWAgent 内部有两条 OTel Pipeline:

metrics/host(直接输出)

复制代码
receivers: telegraf_disk, telegraf_mem, telegraf_processes, telegraf_swap, telegraf_cpu
processors: (无)
exporters: awscloudwatch

适用于绝对值指标(内存使用量、磁盘空间等),不需要任何转换,直接发送到 CloudWatch。

metrics/hostDeltaMetrics(增量转换)

复制代码
receivers: telegraf_net, otlp/metrics0, otlp/metrics1
processors: cumulativetodelta/hostDeltaMetrics
exporters: awscloudwatch

适用于累积值指标(网络字节数等),通过 cumulativetodelta 处理器转换为增量值后再发送。网络指标是累积值(从启动以来的总字节数),需要转换为每个采集周期的增量才有意义。

OTLP 接收器

CWAgent 同时作为 OpenTelemetry Collector 运行,监听两个 gRPC 端口:

端口 绑定地址 TLS 用途
4317 127.0.0.1 本地组件推送指标
4318 0.0.0.0 有 (mTLS) 跨节点指标接收

TLS 证书位置:

复制代码
/etc/emr-cluster-metrics/amazon-cloudwatch-agent/tls-artifacts/
├── ca-cert.pem    ← CA 证书
├── cert.pem       ← 服务端证书
├── key.pem        ← 私钥
└── extract-artifacts.sh

Master vs Worker 的端口差异:

  • Master:4317 (127.0.0.1) + 4318 (0.0.0.0 TLS)
  • Worker:仅 4317 (127.0.0.1),4318 未监听

cloudwatch-sink 组件

注意:cloudwatch-sink-2.22.0` 是一个 Hadoop Metrics2 Sink 插件,名字叫 "cloudwatch-sink" 但不推送到 CloudWatch ,而是推送到 MetricsCollector(端口 9501),由 MC 通过 WebSocket 上报到 EMR 控制面,用于 Managed Scaling 决策。这些指标不会出现在 CloudWatch 控制台

hadoop-metrics2.properties 配置

properties 复制代码
# 全局采样周期:300 秒(5 分钟)
*.period=300

# 指标白名单(仅这 11 个会被推送)
*.sink.cloudwatch.metricsList = TotalLoad,CapacityTotalGB,UnderReplicatedBlocks,
  CapacityRemainingGB,PendingDeletionBlocks,PendingReplicationBlocks,
  CorruptBlocks,CapacityUsedGB,NumLiveDataNodes,NumDeadDataNodes,MissingBlocks

# 8 个 Hadoop 组件启用 CloudWatchSink
namenode.sink.cloudwatch.class    = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
datanode.sink.cloudwatch.class    = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
resourcemanager.sink.cloudwatch.class = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
nodemanager.sink.cloudwatch.class = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
mrappmaster.sink.cloudwatch.class = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
jobhistoryserver.sink.cloudwatch.class = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
maptask.sink.cloudwatch.class     = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink
reducetask.sink.cloudwatch.class  = com.amazon.ws.emr.hadoop.metrics2.sink.cloudwatch.CloudWatchSink

白名单指标(11 个)

指标 说明 示例值
TotalLoad HDFS 总连接数 0
CapacityTotalGB HDFS 总容量 (GB) 116.0
CapacityUsedGB HDFS 已用容量 (GB) 0.0
CapacityRemainingGB HDFS 剩余容量 (GB) 116.0
NumLiveDataNodes 存活 DataNode 数 2
NumDeadDataNodes 死亡 DataNode 数 0
UnderReplicatedBlocks 副本不足的块数 0
PendingReplicationBlocks 待复制块数 0
PendingDeletionBlocks 待删除块数 0
CorruptBlocks 损坏块数 0
MissingBlocks 丢失块数 0

NameNode JMX 实际暴露了约66 个 FSNamesystem 指标,但只有以上 11 个在白名单中会被推送。

配置文件层次

CWAgent 的配置经过多层转换:

复制代码
emr-amazon-cloudwatch-agent.json          ← EMR 生成的源配置(JSON)
    │
    │ config-translator(启动时自动转换)
    │
    ├──► amazon-cloudwatch-agent.toml      ← Telegraf 格式(inputs/outputs)
    └──► amazon-cloudwatch-agent.yaml      ← OTel Collector 格式(receivers/exporters/pipelines)

修改配置时应编辑 emr-amazon-cloudwatch-agent.json,然后重启服务让 config-translator 重新生成 toml/yaml。

CloudWatch 输出配置

yaml 复制代码
exporters:
  awscloudwatch:
    namespace: CWAgent
    region: cn-north-1
    mode: EC2
    force_flush_interval: 1m0s
    max_datums_per_call: 1000
    max_values_per_datum: 150
    resource_to_telemetry_conversion:
      enabled: true
    rollup_dimensions:
      - [cluster.id, instance.id, node.type, service.name]

八、Master vs Worker 对比

项目 Master Worker (Core)
服务状态 active (running) active (running)
node.type master core
系统指标采集 ✅ 相同 ✅ 相同
OTLP 4317 (本地)
OTLP 4318 (TLS) --- (未监听)
cloudwatch-sink NameNode/RM/JHS DataNode/NM

目录结构

复制代码
/opt/aws/amazon-cloudwatch-agent/
├── bin/
│   ├── amazon-cloudwatch-agent              ← 主二进制(Go)
│   ├── amazon-cloudwatch-agent-ctl          ← 管理工具
│   ├── config-translator                    ← JSON→TOML/YAML 转换器
│   ├── start-amazon-cloudwatch-agent        ← 启动脚本
│   └── CWAGENT_VERSION                      ← 版本文件
├── etc/
│   ├── emr-amazon-cloudwatch-agent.json     ← EMR 专用 JSON 配置(源)
│   ├── amazon-cloudwatch-agent.d/
│   │   └── file_emr-amazon-cloudwatch-agent.json
│   ├── amazon-cloudwatch-agent.toml         ← 转换后的 Telegraf 配置
│   ├── amazon-cloudwatch-agent.yaml         ← OTel Collector 配置
│   ├── env-config.json                      ← 环境变量配置
│   └── common-config.toml                   ← 通用配置
├── var/
│   └── amazon-cloudwatch-agent.pid          ← PID 文件
└── logs/
    ├── amazon-cloudwatch-agent.log          ← 启动日志
    └── configuration-validation.log         ← 配置验证日志

/var/log/emr-cluster-metrics/amazon-cloudwatch-agent/
└── amazon-cloudwatch-agent.log              ← 运行时日志

/etc/emr-cluster-metrics/amazon-cloudwatch-agent/tls-artifacts/
├── ca-cert.pem, cert.pem, key.pem           ← OTLP TLS 证书

/usr/share/aws/emr/cloudwatch-sink/lib/
└── cloudwatch-sink-2.22.0.jar               ← Hadoop Metrics2 Sink 插件

运维指南

常用命令

bash 复制代码
# 服务管理
systemctl status amazon-cloudwatch-agent
sudo systemctl restart amazon-cloudwatch-agent

# 使用官方管理工具
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status

# 版本查看
cat /opt/aws/amazon-cloudwatch-agent/bin/CWAGENT_VERSION

# 日志查看
sudo tail -f /var/log/emr-cluster-metrics/amazon-cloudwatch-agent/amazon-cloudwatch-agent.log

# 配置查看
sudo cat /opt/aws/amazon-cloudwatch-agent/etc/emr-amazon-cloudwatch-agent.json | python3 -m json.tool

# 端口检查
sudo ss -tlnp | grep -E "4317|4318"

# Hadoop Metrics2 cloudwatch-sink 配置
grep cloudwatch /etc/hadoop/conf/hadoop-metrics2.properties
相关推荐
亚马逊云开发者8 小时前
MCP Server 终于能"记住"用户了:AgentCore 有状态会话实战
aws
zhojiew10 小时前
[INFRA] EMR集群MetricsCollector组件功能和运行原理分析
aws·emr·bigdata
zhojiew14 小时前
[INFRA] EMR集群Instance Controller组件功能和运行原理分析
aws·emr·bigdata
亚马逊云开发者1 天前
🔥 20 行代码搞定 AI Agent!查天气、算数学、读文档全包了
aws
亚马逊云开发者1 天前
被线上故障电话叫醒后,我花一下午搭了套零人工告警系统
aws
李白你好2 天前
云安全渗透测试框架 - 支持 AWS、Azure、GCP、阿里云、腾讯云、华为云的综合渗透测试工具和指南
阿里云·azure·aws
亚林瓜子2 天前
linux账号强制密码过期导致私钥文件登录异常问题——(current) UNIX password:
linux·运维·服务器·ssh·aws·ec2·chage
DexterLien3 天前
使用开源 Authentik 实现 AWS 单点登录
aws·sso·saml·authentik
亚马逊云开发者3 天前
OpenClaw 接入 Amazon Bedrock 模型选择完全指南:Nova/Claude/Llama 三大模型家族怎么选不花冤枉钱
aws·亚马逊云科技·amazon bedrock·模型选择·openclaw