This is an automated email from the ASF dual-hosted git repository. arshad pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ambari-metrics.git
The following commit(s) were added to refs/heads/master by this push: new a6324d8 [AMBARI-26135] Upgrade net.sf.ehcache to 3.10.0 (#132) a6324d8 is described below commit a6324d84c4464bb808244795c15fa998028a09fd Author: Sandeep Kumar <skuma...@visa.com> AuthorDate: Thu Oct 3 14:57:25 2024 +0530 [AMBARI-26135] Upgrade net.sf.ehcache to 3.10.0 (#132) Signed-off-by: Mohammad Arshad <ars...@apache.org> --- ambari-metrics-timelineservice/pom.xml | 34 ++++- .../core/timeline/TimelineMetricConfiguration.java | 13 +- .../source/cache/InternalMetricsCache.java | 155 +++++++-------------- .../source/cache/InternalMetricsCacheProvider.java | 2 +- .../cache/InternalMetricsCacheSizeOfEngine.java | 148 -------------------- 5 files changed, 84 insertions(+), 268 deletions(-) diff --git a/ambari-metrics-timelineservice/pom.xml b/ambari-metrics-timelineservice/pom.xml index 426afd3..1393492 100644 --- a/ambari-metrics-timelineservice/pom.xml +++ b/ambari-metrics-timelineservice/pom.xml @@ -511,11 +511,6 @@ <artifactId>hadoop-yarn-api</artifactId> <version>${hadoop.version}</version> </dependency> - <dependency> - <groupId>javax.xml.bind</groupId> - <artifactId>jaxb-api</artifactId> - <version>2.2.2</version> - </dependency> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> @@ -835,9 +830,34 @@ <version>2.1.0</version> </dependency> <dependency> - <groupId>net.sf.ehcache</groupId> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.3.1</version> + </dependency> + <dependency> + <groupId>com.sun.istack</groupId> + <artifactId>istack-commons-runtime</artifactId> + <version>4.0.0</version> + </dependency> + <dependency> + <groupId>com.sun.xml.fastinfoset</groupId> + <artifactId>FastInfoset</artifactId> + <version>1.2.16</version> + </dependency> + <dependency> + <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> - <version>2.10.0</version> + <version>3.10.0</version> + <exclusions> + <exclusion> + <groupId>org.glassfish.jaxb</groupId> + <artifactId>jaxb-runtime</artifactId> + </exclusion> + <exclusion> + <groupId>org.glassfish.jaxb</groupId> + <artifactId>jaxb-core</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/TimelineMetricConfiguration.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/TimelineMetricConfiguration.java index f8f4bb0..05f7b03 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/TimelineMetricConfiguration.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/TimelineMetricConfiguration.java @@ -317,8 +317,7 @@ public class TimelineMetricConfiguration { public static final String TIMELINE_METRICS_COLLECTOR_IGNITE_BACKUPS = "timeline.metrics.collector.ignite.nodes.backups"; - public static final String INTERNAL_CACHE_HEAP_PERCENT = - "timeline.metrics.internal.cache.%s.heap.percent"; + public static final String INTERNAL_CACHE_ENTRY_COUNT = "timeline.metrics.internal.cache.%s.entry.count"; public static final String EXTERNAL_SINK_INTERVAL = "timeline.metrics.external.sink.%s.%s.interval"; @@ -628,12 +627,12 @@ public class TimelineMetricConfiguration { return providerList; } - public String getInternalCacheHeapPercent(String instanceName) { - String heapPercent = metricsConf.get(String.format(INTERNAL_CACHE_HEAP_PERCENT, instanceName)); - if (StringUtils.isEmpty(heapPercent)) { - return "5%"; + public Integer getInternalCacheSize(String instanceName) { + String cacheEntryCount = metricsConf.get(String.format(INTERNAL_CACHE_ENTRY_COUNT, instanceName)); + if(StringUtils.isEmpty(cacheEntryCount)) { + return 500; } else { - return heapPercent.endsWith("%") ? heapPercent : heapPercent + "%"; + return Integer.parseInt(cacheEntryCount); } } diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCache.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCache.java index b26921f..afef409 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCache.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCache.java @@ -24,36 +24,39 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.EnumSet; +import java.util.Iterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.metrics2.sink.timeline.TimelineMetric; import org.apache.hadoop.metrics2.sink.timeline.TimelineMetrics; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheException; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.config.PersistenceConfiguration; -import net.sf.ehcache.config.SizeOfPolicyConfiguration; -import net.sf.ehcache.event.CacheEventListener; -import net.sf.ehcache.store.MemoryStoreEvictionPolicy; +import org.ehcache.Cache; +import org.ehcache.CacheManager; +import org.ehcache.config.CacheConfiguration; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.config.units.EntryUnit; +import org.ehcache.event.CacheEvent; +import org.ehcache.event.CacheEventListener; +import org.ehcache.event.EventType; +import org.ehcache.event.EventFiring; +import org.ehcache.event.EventOrdering; +import org.ehcache.expiry.Expirations; public class InternalMetricsCache { private static final Log LOG = LogFactory.getLog(InternalMetricsCache.class); private final String instanceName; - private final String maxHeapPercent; + private final Integer internalCacheEntryCount; private volatile boolean isCacheInitialized = false; - private Cache cache; - static final String TIMELINE_METRIC_CACHE_MANAGER_NAME = "internalMetricsCacheManager"; + private Cache<InternalMetricCacheKey, InternalMetricCacheValue> cache; private final Lock lock = new ReentrantLock(); private static final int LOCK_TIMEOUT_SECONDS = 2; - public InternalMetricsCache(String instanceName, String maxHeapPercent) { + public InternalMetricsCache(String instanceName, Integer internalCacheEntryCount) { this.instanceName = instanceName; - this.maxHeapPercent = maxHeapPercent; + this.internalCacheEntryCount = internalCacheEntryCount; initialize(); } @@ -63,71 +66,49 @@ public class InternalMetricsCache { throw new RuntimeException("Cannot initialize internal cache twice"); } - System.setProperty("net.sf.ehcache.skipUpdateCheck", "true"); - System.setProperty("net.sf.ehcache.sizeofengine." + TIMELINE_METRIC_CACHE_MANAGER_NAME, - "org.apache.ambari.metrics.core.timeline.source.cache.InternalMetricsCacheSizeOfEngine"); - - net.sf.ehcache.config.Configuration managerConfig = - new net.sf.ehcache.config.Configuration(); - managerConfig.setName(TIMELINE_METRIC_CACHE_MANAGER_NAME); - - // Set max heap available to the cache manager - managerConfig.setMaxBytesLocalHeap(maxHeapPercent); - - //Create a singleton CacheManager using defaults - CacheManager manager = CacheManager.create(managerConfig); - - LOG.info("Creating Metrics Cache with maxHeapPercent => " + maxHeapPercent); + CacheManager manager = CacheManagerBuilder.newCacheManagerBuilder() + .build(true); // Create a Cache specifying its configuration. - CacheConfiguration cacheConfiguration = new CacheConfiguration() - .name(instanceName) - .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU) - .sizeOfPolicy(new SizeOfPolicyConfiguration() // Set sizeOf policy to continue on max depth reached - avoid OOM - .maxDepth(10000) - .maxDepthExceededBehavior(SizeOfPolicyConfiguration.MaxDepthExceededBehavior.CONTINUE)) - .eternal(true) // infinite time until eviction - .persistence(new PersistenceConfiguration() - .strategy(PersistenceConfiguration.Strategy.NONE.name())); - - cache = new Cache(cacheConfiguration); - cache.getCacheEventNotificationService().registerListener(new InternalCacheEvictionListener()); + CacheConfiguration<InternalMetricCacheKey, InternalMetricCacheValue> cacheConfig = + CacheConfigurationBuilder.newCacheConfigurationBuilder( + InternalMetricCacheKey.class, InternalMetricCacheValue.class, + ResourcePoolsBuilder.newResourcePoolsBuilder().heap(internalCacheEntryCount, EntryUnit.ENTRIES) + ).withExpiry(Expirations.noExpiration()).build(); - LOG.info("Registering internal metrics cache with provider: name = " + - cache.getName() + ", guid: " + cache.getGuid()); + cache = manager.createCache(instanceName, cacheConfig); + cache.getRuntimeConfiguration().registerCacheEventListener(new InternalCacheEvictionListener(), EventOrdering.ORDERED, EventFiring.SYNCHRONOUS, EnumSet.of(EventType.EVICTED)); - manager.addCache(cache); + LOG.info("Registering internal metrics cache with provider: name = " + + instanceName); isCacheInitialized = true; } public InternalMetricCacheValue getInternalMetricCacheValue(InternalMetricCacheKey key) { - Element ele = cache.get(key); - if (ele != null) { - return (InternalMetricCacheValue) ele.getObjectValue(); - } - return null; + return cache.get(key); } public Collection<TimelineMetrics> evictAll() { TimelineMetrics metrics = new TimelineMetrics(); try { if (lock.tryLock(LOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { - try{ - List keys = cache.getKeys(); - for (Object obj : keys) { + try { + Iterator<Cache.Entry<InternalMetricCacheKey, InternalMetricCacheValue>> iterator = cache.iterator(); + while (iterator.hasNext()) { + Cache.Entry<InternalMetricCacheKey, InternalMetricCacheValue> entry = iterator.next(); TimelineMetric metric = new TimelineMetric(); - InternalMetricCacheKey key = (InternalMetricCacheKey) obj; + InternalMetricCacheKey key = entry.getKey(); metric.setMetricName(key.getMetricName()); metric.setAppId(key.getAppId()); metric.setInstanceId(key.getInstanceId()); metric.setHostName(key.getHostname()); metric.setStartTime(key.getStartTime()); - Element ele = cache.get(key); - metric.setMetricValues(((InternalMetricCacheValue) ele.getObjectValue()).getMetricValues()); + InternalMetricCacheValue value = cache.get(key); + metric.setMetricValues(value.getMetricValues()); metrics.getMetrics().add(metric); + iterator.remove(); } - cache.removeAll(); } finally { lock.unlock(); } @@ -157,14 +138,13 @@ public class InternalMetricsCache { timelineMetric.getStartTime() ); - Element ele = cache.get(key); - if (ele != null) { - InternalMetricCacheValue value = (InternalMetricCacheValue) ele.getObjectValue(); + InternalMetricCacheValue value = cache.get(key); + if (value != null) { value.addMetricValues(timelineMetric.getMetricValues()); } else { - InternalMetricCacheValue value = new InternalMetricCacheValue(); + value = new InternalMetricCacheValue(); value.setMetricValues(timelineMetric.getMetricValues()); - cache.put(new Element(key, value)); + cache.put(key, value); } } } @@ -181,49 +161,14 @@ public class InternalMetricsCache { } } - class InternalCacheEvictionListener implements CacheEventListener { - - @Override - public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException { - // expected - } - - @Override - public void notifyElementPut(Ehcache cache, Element element) throws CacheException { - // do nothing - } - + class InternalCacheEvictionListener implements CacheEventListener<InternalMetricCacheKey, InternalMetricCacheValue> { @Override - public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException { - // do nothing - } - - @Override - public void notifyElementExpired(Ehcache cache, Element element) { - // do nothing - } - - @Override - public void notifyElementEvicted(Ehcache cache, Element element) { - // Bad - Remote endpoint cannot keep up resulting in flooding - InternalMetricCacheKey key = (InternalMetricCacheKey) element.getObjectKey(); - LOG.warn("Evicting element from internal metrics cache, metric => " + key - .getMetricName() + ", startTime = " + new Date(key.getStartTime())); - } - - @Override - public void notifyRemoveAll(Ehcache cache) { - // expected - } - - @Override - public Object clone() throws CloneNotSupportedException { - return null; - } - - @Override - public void dispose() { - // do nothing + public void onEvent(CacheEvent<? extends InternalMetricCacheKey, ? extends InternalMetricCacheValue> event) { + if (event.getType() == EventType.EVICTED) { + InternalMetricCacheKey key = event.getKey(); + LOG.warn("Evicting element from internal metrics cache, metric => " + key + .getMetricName() + ", startTime = " + new Date(key.getStartTime())); + } } } } diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheProvider.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheProvider.java index 8ec9acd..1fc954c 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheProvider.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheProvider.java @@ -39,7 +39,7 @@ public class InternalMetricsCacheProvider { } else { TimelineMetricConfiguration conf = TimelineMetricConfiguration.getInstance(); InternalMetricsCache cache = new InternalMetricsCache(instanceName, - conf.getInternalCacheHeapPercent(instanceName)); + conf.getInternalCacheSize(instanceName)); metricsCacheMap.put(instanceName, cache); return cache; diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheSizeOfEngine.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheSizeOfEngine.java deleted file mode 100644 index cfa4f97..0000000 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/source/cache/InternalMetricsCacheSizeOfEngine.java +++ /dev/null @@ -1,148 +0,0 @@ -/** - * 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 - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * 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.ambari.metrics.core.timeline.source.cache; - -import net.sf.ehcache.Element; -import net.sf.ehcache.pool.Size; -import net.sf.ehcache.pool.SizeOfEngine; -import net.sf.ehcache.pool.impl.DefaultSizeOfEngine; -import net.sf.ehcache.pool.sizeof.ReflectionSizeOf; -import net.sf.ehcache.pool.sizeof.SizeOf; -import org.apache.hadoop.metrics2.sink.timeline.TimelineMetric; -import org.apache.hadoop.metrics2.sink.timeline.TimelineMetrics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.TreeMap; - -public class InternalMetricsCacheSizeOfEngine implements SizeOfEngine { - private final static Logger LOG = LoggerFactory.getLogger(InternalMetricsCacheSizeOfEngine.class); - - private static int DEFAULT_MAX_DEPTH = 1000; - private static boolean DEFAULT_ABORT_WHEN_MAX_DEPTH_EXCEEDED = false; - - // Base Engine - protected SizeOfEngine underlying = null; - - // Counter - protected SizeOf reflectionSizeOf = new ReflectionSizeOf(); - - // Optimizations - private volatile long timelineMetricPrimitivesApproximation = 0; - - // Map entry sizing - private long sizeOfMapEntry; - private long sizeOfMapEntryOverhead; - private long sizeOfElement; - - protected InternalMetricsCacheSizeOfEngine(SizeOfEngine underlying) { - this.underlying = underlying; - } - - public InternalMetricsCacheSizeOfEngine() { - this(new DefaultSizeOfEngine(DEFAULT_MAX_DEPTH, DEFAULT_ABORT_WHEN_MAX_DEPTH_EXCEEDED)); - - this.sizeOfMapEntry = reflectionSizeOf.sizeOf(new Long(1)) + - reflectionSizeOf.sizeOf(new Double(2.0)); - - this.sizeOfElement = reflectionSizeOf.sizeOf(new Element(new Object(), new Object())); - - //SizeOfMapEntryOverhead = SizeOfMapWithOneEntry - (SizeOfEmptyMap + SizeOfOneEntry) - TreeMap<Long, Double> map = new TreeMap<>(); - long emptyMapSize = reflectionSizeOf.sizeOf(map); - map.put(new Long(1), new Double(2.0)); - long sizeOfMapOneEntry = reflectionSizeOf.deepSizeOf(DEFAULT_MAX_DEPTH, DEFAULT_ABORT_WHEN_MAX_DEPTH_EXCEEDED, map).getCalculated(); - this.sizeOfMapEntryOverhead = sizeOfMapOneEntry - (emptyMapSize + this.sizeOfMapEntry); - - LOG.info("Creating custom sizeof engine for TimelineMetrics."); - } - - /** - * Return size of the metrics TreeMap in an optimized way. - * - */ - protected long getTimelineMetricsSize(TimelineMetrics metrics) { - long size = 8; // Object reference - - if (metrics != null) { - for (TimelineMetric metric : metrics.getMetrics()) { - - if (timelineMetricPrimitivesApproximation == 0) { - timelineMetricPrimitivesApproximation += reflectionSizeOf.sizeOf(metric.getMetricName()); - timelineMetricPrimitivesApproximation += reflectionSizeOf.sizeOf(metric.getAppId()); - timelineMetricPrimitivesApproximation += reflectionSizeOf.sizeOf(metric.getHostName()); - timelineMetricPrimitivesApproximation += reflectionSizeOf.sizeOf(metric.getInstanceId()); - timelineMetricPrimitivesApproximation += reflectionSizeOf.sizeOf(metric.getStartTime()); - timelineMetricPrimitivesApproximation += reflectionSizeOf.sizeOf(metric.getType()); - timelineMetricPrimitivesApproximation += 8; // Object overhead - - LOG.debug("timelineMetricPrimitivesApproximation bytes = " + timelineMetricPrimitivesApproximation); - } - size += timelineMetricPrimitivesApproximation; - size += getValueMapSize(metric.getMetricValues()); - } - LOG.debug("Total Size of metric values in cache: " + size); - } - return size; - } - - protected long getValueMapSize(Map<Long, Double> metricValues) { - long size = 0; - if (metricValues != null && !metricValues.isEmpty()) { - // Numeric wrapper: 12 bytes + 8 bytes Data type + 4 bytes alignment = 48 (Long, Double) - // Tree Map: 12 bytes for header + 20 bytes for 5 object fields : pointers + 1 byte for flag = 40 - LOG.debug("Size of metric value: " + (sizeOfMapEntry + sizeOfMapEntryOverhead) * metricValues.size()); - size += (sizeOfMapEntry + sizeOfMapEntryOverhead) * metricValues.size(); // Treemap size is O(1) - } - return size; - } - - @Override - public Size sizeOf(Object key, Object value, Object container) { - return new Size(sizeOfElement + getSizeOfEntry(key, value), false); - } - - @Override - public SizeOfEngine copyWith(int maxDepth, boolean abortWhenMaxDepthExceeded) { - LOG.debug("Copying tracing sizeof engine, maxdepth: {}, abort: {}", maxDepth, abortWhenMaxDepthExceeded); - - return underlying.copyWith(maxDepth, abortWhenMaxDepthExceeded); - } - - protected long getSizeOfEntry(Object key, Object value) { - try { - LOG.debug("BEGIN - Sizeof, key: {}, value: {}", key, value); - long size = 0; - if (key instanceof InternalMetricCacheKey) { - InternalMetricCacheKey metricCacheKey = (InternalMetricCacheKey) key; - size += reflectionSizeOf.sizeOf(metricCacheKey.getMetricName()); - size += reflectionSizeOf.sizeOf(metricCacheKey.getAppId()); - size += reflectionSizeOf.sizeOf(metricCacheKey.getInstanceId()); // null safe - size += reflectionSizeOf.sizeOf(metricCacheKey.getHostname()); - } - if (value instanceof InternalMetricCacheValue) { - size += getValueMapSize(((InternalMetricCacheValue) value).getMetricValues()); - } - // Mark size as not being exact - return size; - } finally { - LOG.debug("END - Sizeof, key: {}", key); - } - } -} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@ambari.apache.org For additional commands, e-mail: commits-h...@ambari.apache.org