diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainerMetrics.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainerMetrics.java index 1375da8b97c7262116df49c40e4f5bfb64d570a2..145c62b72f93cc50385e56d88916c6c70e148e14 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainerMetrics.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainerMetrics.java @@ -98,6 +98,10 @@ protected final static Map usageMetrics = new HashMap<>(); + private Object cpuCoreUsagePercentLock = new Object(); + private Object milliVcoresUsedLock = new Object(); + private Object pMemMBsStatLock = new Object(); + ContainerMetrics( MetricsSystem ms, ContainerId containerId, long flushPeriodMs) { this.recordInfo = @@ -108,14 +112,6 @@ this.flushPeriodMs = flushPeriodMs; scheduleTimerTaskIfRequired(); - this.pMemMBsStat = registry.newStat( - PMEM_USAGE_METRIC_NAME, "Physical memory stats", "Usage", "MBs", true); - this.cpuCoreUsagePercent = registry.newStat( - PHY_CPU_USAGE_METRIC_NAME, "Physical Cpu core percent usage stats", - "Usage", "Percents", true); - this.milliVcoresUsed = registry.newStat( - VCORE_USAGE_METRIC_NAME, "1000 times Vcore usage", "Usage", - "MilliVcores", true); this.pMemLimitMbs = registry.newGauge( PMEM_LIMIT_METRIC_NAME, "Physical memory limit in MBs", 0); this.vMemLimitMbs = registry.newGauge( @@ -188,13 +184,47 @@ public synchronized void finished() { } public void recordMemoryUsage(int memoryMBs) { - this.pMemMBsStat.add(memoryMBs); + if (isAvailable(memoryMBs)) { + if (this.pMemMBsStat == null) { + synchronized (pMemMBsStatLock) { + if (this.pMemMBsStat == null) { + this.pMemMBsStat = registry.newStat( + PMEM_USAGE_METRIC_NAME, + "Physical memory stats", "Usage", "MBs", true); + } + } + } + this.pMemMBsStat.add(memoryMBs); + } } public void recordCpuUsage( int totalPhysicalCpuPercent, int milliVcoresUsed) { - this.cpuCoreUsagePercent.add(totalPhysicalCpuPercent); - this.milliVcoresUsed.add(milliVcoresUsed); + if (isAvailable(totalPhysicalCpuPercent)) { + if (this.cpuCoreUsagePercent == null) { + synchronized (cpuCoreUsagePercentLock) { + if (this.cpuCoreUsagePercent == null) { + this.cpuCoreUsagePercent = registry.newStat( + PHY_CPU_USAGE_METRIC_NAME, + "Physical Cpu core percent usage stats", + "Usage", "Percents", true); + } + } + } + this.cpuCoreUsagePercent.add(totalPhysicalCpuPercent); + } + if (isAvailable(milliVcoresUsed)) { + if (this.milliVcoresUsed == null) { + synchronized (milliVcoresUsedLock) { + if (this.cpuCoreUsagePercent == null) { + this.milliVcoresUsed = registry.newStat( + VCORE_USAGE_METRIC_NAME, "1000 times Vcore usage", "Usage", + "MilliVcores", true); + } + } + } + this.milliVcoresUsed.add(milliVcoresUsed); + } } public void recordProcessId(String processId) { @@ -207,6 +237,10 @@ public void recordResourceLimit(int vmemLimit, int pmemLimit, int cpuVcores) { this.cpuVcoreLimit.set(cpuVcores); } + private boolean isAvailable(int memoryMBs) { + return memoryMBs >= 0; + } + private synchronized void scheduleTimerTaskIfRequired() { if (flushPeriodMs > 0) { // Lazily initialize timer