diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/AsyncDispatcher.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/AsyncDispatcher.java index 79ad464200d..5077b6e9aed 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/AsyncDispatcher.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/AsyncDispatcher.java @@ -26,6 +26,7 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; +import org.apache.hadoop.yarn.metrics.EventTypeMetrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; @@ -85,6 +86,9 @@ protected final Map, EventHandler> eventDispatchers; private boolean exitOnDispatchException = true; + private Map, + EventTypeMetrics> eventTypeMetricsMap; + /** * The thread name for dispatcher. */ @@ -98,6 +102,8 @@ public AsyncDispatcher(BlockingQueue eventQueue) { super("Dispatcher"); this.eventQueue = eventQueue; this.eventDispatchers = new HashMap, EventHandler>(); + this.eventTypeMetricsMap = new HashMap, + EventTypeMetrics>(); } /** @@ -135,7 +141,15 @@ public void run() { return; } if (event != null) { - dispatch(event); + if (eventTypeMetricsMap.get(event.getType().getClass()) != null) { + long startTime = System.nanoTime(); + dispatch(event); + eventTypeMetricsMap.get(event.getType().getClass()) + .incr(event.getType(), + (System.nanoTime() - startTime) / 1000); + } else { + dispatch(event); + } if (printTrigger) { //Log the latest dispatch event type // may cause the too many events queued @@ -364,4 +378,9 @@ protected boolean isDrained() { protected boolean isStopped() { return stopped; } + + public void addMetrics(EventTypeMetrics metrics, + Class eventClass) { + eventTypeMetricsMap.put(eventClass, metrics); + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/EventDispatcher.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/EventDispatcher.java index 0969e999718..e030b34ca3b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/EventDispatcher.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/event/EventDispatcher.java @@ -19,6 +19,7 @@ package org.apache.hadoop.yarn.event; import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; +import org.apache.hadoop.yarn.metrics.EventTypeMetrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; @@ -47,6 +48,7 @@ private final Thread eventProcessor; private volatile boolean stopped = false; private boolean shouldExitOnError = true; + private EventTypeMetrics metrics; private static final Logger LOG = LoggerFactory.getLogger(EventDispatcher.class); @@ -68,7 +70,14 @@ public void run() { } try { - handler.handle(event); + if (metrics != null) { + long startTime = System.nanoTime(); + handler.handle(event); + metrics.incr(event.getType(), + (System.nanoTime() - startTime) / 1000); + } else { + handler.handle(event); + } } catch (Throwable t) { // An error occurred, but we are shutting down anyway. // If it was an InterruptedException, the very act of @@ -136,4 +145,8 @@ public void handle(T event) { public void disableExitOnError() { shouldExitOnError = false; } + + public void setMetrics(EventTypeMetrics metrics) { + this.metrics = metrics; + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/DisableEventTypeMetrics.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/DisableEventTypeMetrics.java new file mode 100644 index 00000000000..123dd163880 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/DisableEventTypeMetrics.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.metrics; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.metrics2.MetricsCollector; +import org.apache.hadoop.metrics2.annotation.Metrics; + +@InterfaceAudience.Private +@Metrics(context="yarn") +public class DisableEventTypeMetrics implements EventTypeMetrics{ + @Override + public void incr(Enum type, long processingTimeUs) { + return; + } + @Override + public void getMetrics(MetricsCollector collector, boolean all) { + return; + } + + @Override + public void get(Enum type) { + + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/EventTypeMetrics.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/EventTypeMetrics.java new file mode 100644 index 00000000000..fb68e730166 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/EventTypeMetrics.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.metrics; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.metrics2.MetricsSource; +import org.apache.hadoop.metrics2.annotation.Metrics; + +@InterfaceAudience.Private +@Metrics(context="yarn") +public interface EventTypeMetrics> + extends MetricsSource { + + void incr(T type, long processingTimeUs); + + void get(T type); + +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/GenericEventTypeMetrics.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/GenericEventTypeMetrics.java new file mode 100644 index 00000000000..148b07b7fa7 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/metrics/GenericEventTypeMetrics.java @@ -0,0 +1,119 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.metrics; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.metrics2.MetricsCollector; +import org.apache.hadoop.metrics2.MetricsInfo; +import org.apache.hadoop.metrics2.MetricsSystem; +import org.apache.hadoop.metrics2.annotation.Metrics; +import org.apache.hadoop.metrics2.lib.MetricsRegistry; +import org.apache.hadoop.metrics2.lib.MutableGaugeLong; + +import java.util.EnumMap; + +@InterfaceAudience.Private +@Metrics(context="yarn") +public class GenericEventTypeMetrics> + implements EventTypeMetrics { + + private final EnumMap eventCountMetrics; + private final EnumMap processingTimeMetrics; + private final MetricsRegistry registry; + private final MetricsSystem ms; + private final MetricsInfo info; + private final Class enumClass; + + public GenericEventTypeMetrics(MetricsInfo info, MetricsSystem ms, + T[] enums, Class enumClass) { + + this.enumClass = enumClass; + this.eventCountMetrics = new EnumMap<>(this.enumClass); + this.processingTimeMetrics = new EnumMap<>(this.enumClass); + this.ms = ms; + this.info = info; + this.registry = new MetricsRegistry(this.info); + + //Initialze enum + for (T type : enums) { + String eventCountMetricsName = + type.toString().toLowerCase() + "_" + "event_count"; + String processingTimeMetricsName = + type.toString().toLowerCase() + "_" + "processing_time"; + eventCountMetrics.put(type, this.registry. + newGauge(eventCountMetricsName, eventCountMetricsName, 0L)); + processingTimeMetrics.put(type, this.registry. + newGauge(processingTimeMetricsName, processingTimeMetricsName, 0L)); + } + } + + @Override + public void incr(T type, long processingTimeUs) { + if (eventCountMetrics.get(type) != null) { + eventCountMetrics.get(type).incr(); + processingTimeMetrics.get(type).incr(processingTimeUs); + } + } + + @Override + public void get(T type) { + } + + @Override + public void getMetrics(MetricsCollector collector, boolean all) { + } + + public Class getEnumClass() { + return enumClass; + } + + /** Builder class for GenericEventTypeMetrics. */ + public static class EventTypeMetricsBuilder>{ + public EventTypeMetricsBuilder() { + } + + public EventTypeMetricsBuilder setEnumClass(Class enumClassValue) { + this.enumClass = enumClassValue; + return this; + } + + public EventTypeMetricsBuilder setEnums(final T[] enumsValue) { + this.enums = enumsValue; + return this; + } + + public EventTypeMetricsBuilder setInfo(MetricsInfo infoValue) { + this.info = infoValue; + return this; + } + + public EventTypeMetricsBuilder setMs(MetricsSystem msValue) { + this.ms = msValue; + return this; + } + + public GenericEventTypeMetrics build() { + return new GenericEventTypeMetrics(info, ms, enums, enumClass); + } + + private MetricsSystem ms; + private MetricsInfo info; + private Class enumClass; + private T[] enums; + } +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/GenericEventTypeMetricsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/GenericEventTypeMetricsManager.java new file mode 100644 index 00000000000..1b093b962f3 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/GenericEventTypeMetricsManager.java @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.server.resourcemanager; + +import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; +import org.apache.hadoop.yarn.metrics.GenericEventTypeMetrics; + +import static org.apache.hadoop.metrics2.lib.Interns.info; + +public class GenericEventTypeMetricsManager { + + private GenericEventTypeMetricsManager() { + // nothing to do + } + + // Construct a GenericEventTypeMetrics for dispatcher + public static > GenericEventTypeMetrics + create(String dispatcherName, Class eventTypeClass) { + return new GenericEventTypeMetrics.EventTypeMetricsBuilder() + .setMs(DefaultMetricsSystem.instance()) + .setInfo(info("GenericEventTypeMetrics for " + eventTypeClass.getName(), + "Metrics for " + dispatcherName)) + .setEnumClass(eventTypeClass) + .setEnums(eventTypeClass.getEnumConstants()) + .build(); + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java index c315b335415..197c208b184 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java @@ -21,6 +21,8 @@ import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import com.sun.jersey.spi.container.servlet.ServletContainer; +import org.apache.hadoop.yarn.event.*; +import org.apache.hadoop.yarn.metrics.GenericEventTypeMetrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.Marker; @@ -58,10 +60,6 @@ import org.apache.hadoop.yarn.conf.ConfigurationProviderFactory; import org.apache.hadoop.yarn.conf.HAUtil; import org.apache.hadoop.yarn.conf.YarnConfiguration; -import org.apache.hadoop.yarn.event.AsyncDispatcher; -import org.apache.hadoop.yarn.event.Dispatcher; -import org.apache.hadoop.yarn.event.EventDispatcher; -import org.apache.hadoop.yarn.event.EventHandler; import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.nodelabels.NodeAttributesManager; @@ -449,11 +447,23 @@ protected void setRMStateStore(RMStateStore rmStore) { } protected EventHandler createSchedulerEventDispatcher() { - return new EventDispatcher(this.scheduler, "SchedulerEventDispatcher"); + EventDispatcher dispatcher = new + EventDispatcher(this.scheduler, "SchedulerEventDispatcher"); + dispatcher. + setMetrics(GenericEventTypeMetricsManager. + create(dispatcher.getName(), SchedulerEventType.class)); + return dispatcher; } protected Dispatcher createDispatcher() { - return new AsyncDispatcher("RM Event dispatcher"); + AsyncDispatcher dispatcher = new AsyncDispatcher("RM Event dispatcher"); + GenericEventTypeMetrics genericEventTypeMetrics = + GenericEventTypeMetricsManager. + create(dispatcher.getName(), NodesListManagerEventType.class); + // We can add more + dispatcher.addMetrics(genericEventTypeMetrics, + genericEventTypeMetrics.getEnumClass()); + return dispatcher; } protected ResourceScheduler createScheduler() {