blob: 4b38e9e7709c8130eca6e909b3f3ccef08066514 [file] [log] [blame]
/*
* 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.ignite.internal.processors.cache;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.internal.processors.metric.MetricRegistry;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.spi.metric.LongMetric;
import org.apache.ignite.testframework.MvccFeatureChecker;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.cacheMetricsRegistryName;
/**
* This test checks that entries count metrics, calculated by method
* {@link org.apache.ignite.internal.processors.cache.CacheMetricsImpl#getEntriesStat()} (which uses one iteration
* over local partitions to get all set of metrics), have the same values as metrics, calculated by individual methods
* (which use iteration over local partition per each method call).
*/
public class CacheMetricsEntitiesCountTest extends GridCommonAbstractTest {
/** Grid count. */
private static final int GRID_CNT = 3;
/** Cache prefix. */
private static final String CACHE_PREFIX = "CACHE";
/** Entities cnt. */
private static final int ENTITIES_CNT = 100;
/** Onheap peek modes. */
private static final CachePeekMode[] ONHEAP_PEEK_MODES = new CachePeekMode[] {
CachePeekMode.ONHEAP, CachePeekMode.PRIMARY, CachePeekMode.BACKUP, CachePeekMode.NEAR};
/** Cache count. */
private static int cacheCnt = 4;
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
Collection<CacheConfiguration> ccfgs = new ArrayList<>(4);
ccfgs.add(new CacheConfiguration<>()
.setName(CACHE_PREFIX + 0)
.setStatisticsEnabled(true)
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
.setCacheMode(CacheMode.REPLICATED)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
ccfgs.add(new CacheConfiguration<>()
.setName(CACHE_PREFIX + 1)
.setStatisticsEnabled(true)
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
.setCacheMode(CacheMode.PARTITIONED)
.setBackups(1)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
ccfgs.add(new CacheConfiguration<>()
.setName(CACHE_PREFIX + 2)
.setStatisticsEnabled(true)
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
.setCacheMode(CacheMode.PARTITIONED)
.setBackups(1)
.setNearConfiguration(new NearCacheConfiguration<>())
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
ccfgs.add(new CacheConfiguration<>()
.setName(CACHE_PREFIX + 3)
.setStatisticsEnabled(true)
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
.setCacheMode(CacheMode.PARTITIONED)
.setBackups(1)
.setOnheapCacheEnabled(true)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
if (!MvccFeatureChecker.forcedMvcc() || MvccFeatureChecker.isSupported(MvccFeatureChecker.Feature.LOCAL_CACHE)) {
ccfgs.add(new CacheConfiguration<>()
.setName(CACHE_PREFIX + 4)
.setStatisticsEnabled(true)
.setCacheMode(CacheMode.LOCAL)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
}
cacheCnt = ccfgs.size();
cfg.setCacheConfiguration(U.toArray(ccfgs, new CacheConfiguration[cacheCnt]));
return cfg;
}
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
startGrids(GRID_CNT);
}
/**
* Test entities count, calculated by different implementations.
*/
@Test
public void testEnitiesCount() throws Exception {
awaitPartitionMapExchange();
for (int igniteIdx = 0; igniteIdx < GRID_CNT; igniteIdx++)
for (int cacheIdx = 0; cacheIdx < cacheCnt; cacheIdx++)
fillCache(igniteIdx, cacheIdx);
awaitMetricsUpdate(1);
int cacheSize = GRID_CNT * ENTITIES_CNT;
// CacheMode == REPLICATED.
checkCacheClusterMetrics(0,
cacheSize,
cacheSize * GRID_CNT,
cacheSize,
cacheSize * (GRID_CNT - 1),
0);
// CacheMode == PARTITIONED, Backups == 1.
checkCacheClusterMetrics(1,
cacheSize,
cacheSize * 2,
cacheSize,
cacheSize,
0);
// CacheMode == PARTITIONED, Backups == 1, NearCache.
checkCacheClusterMetrics(2,
cacheSize,
cacheSize * 2,
cacheSize,
cacheSize,
216 /* TODO */);
// CacheMode == PARTITIONED, Backups == 1, OnheapCache.
checkCacheClusterMetrics(3,
cacheSize,
cacheSize * 2,
cacheSize,
cacheSize,
cacheSize * 2);
// CacheMode == LOCAL
if (cacheCnt == 5)
checkCacheClusterMetrics(4,
cacheSize,
cacheSize,
cacheSize,
0,
0);
for (int igniteIdx = 0; igniteIdx < GRID_CNT; igniteIdx++)
for (int cacheIdx = 0; cacheIdx < cacheCnt; cacheIdx++)
checkCacheLocalMetrics(igniteIdx, cacheIdx);
}
/**
* @param igniteIdx Ignite index.
* @param cacheIdx Cache index.
*/
private void fillCache(int igniteIdx, int cacheIdx) {
log.info("Filling cache, igniteIdx=" + igniteIdx + ", cacheIdx=" + cacheIdx);
IgniteCache cache = grid(igniteIdx).cache(CACHE_PREFIX + cacheIdx);
for (int i = 0; i < ENTITIES_CNT; i++)
cache.put("key" + igniteIdx + "-" + i, i);
}
/**
* @param igniteIdx Ignite index.
* @param cacheIdx Cache index.
*/
private void checkCacheLocalMetrics(int igniteIdx, int cacheIdx) throws IgniteCheckedException {
IgniteInternalCache internalCache = grid(igniteIdx).cachex(CACHE_PREFIX + cacheIdx);
GridCacheContext cctx = internalCache.context();
GridCacheAdapter cache = cctx.cache();
CacheMetricsImpl metrics = cache.metrics0();
long offHeapEntriesCount = cache.offHeapEntriesCount();
long offHeapPrimaryEntriesCount = cctx.offheap().cacheEntriesCount(cctx.cacheId(),
true,
false,
cctx.affinity().affinityTopologyVersion());
long offHeapBackupEntriesCount = cctx.offheap().cacheEntriesCount(cctx.cacheId(),
false,
true,
cctx.affinity().affinityTopologyVersion());
long heapEntriesCount = cache.localSizeLong(ONHEAP_PEEK_MODES);
long cacheSize = cache.localSizeLong(new CachePeekMode[]{CachePeekMode.PRIMARY});
int size = cache.localSize(new CachePeekMode[]{CachePeekMode.PRIMARY});
boolean isEmpty = cache.isEmpty();
String cacheInfo = "igniteIdx=" + igniteIdx + ", cacheIdx=" + cacheIdx + " ";
log.info("Checking cache, " + cacheInfo);
assertEquals(cacheInfo + " offHeapEntriesCount",
offHeapEntriesCount, metrics.getOffHeapEntriesCount());
assertEquals(cacheInfo + " offHeapBackupEntriesCount",
offHeapBackupEntriesCount, metrics.getOffHeapBackupEntriesCount());
assertEquals(cacheInfo + " offHeapPrimaryEntriesCount",
offHeapPrimaryEntriesCount, metrics.getOffHeapPrimaryEntriesCount());
assertEquals(cacheInfo + " heapEntriesCount", heapEntriesCount, metrics.getHeapEntriesCount());
assertEquals(cacheInfo + " size", size, metrics.getSize());
assertEquals(cacheInfo + " keySize", size, metrics.getKeySize());
assertEquals(cacheInfo + " cacheSize", cacheSize, metrics.getCacheSize());
assertEquals(cacheInfo + " isEmpty", isEmpty, metrics.isEmpty());
MetricRegistry mreg = cctx.kernalContext().metric().registry(cacheMetricsRegistryName(cctx.name(),
cache.isNear()));
assertNotNull(mreg);
assertEquals(offHeapEntriesCount, ((LongMetric)mreg.findMetric("OffHeapEntriesCount")).value());
assertEquals(offHeapBackupEntriesCount, ((LongMetric)mreg.findMetric("OffHeapBackupEntriesCount")).value());
assertEquals(offHeapPrimaryEntriesCount, ((LongMetric)mreg.findMetric("OffHeapPrimaryEntriesCount")).value());
assertEquals(heapEntriesCount, ((LongMetric)mreg.findMetric("HeapEntriesCount")).value());
assertEquals(cacheSize, ((LongMetric)mreg.findMetric("CacheSize")).value());
}
/**
* @param cacheIdx Cache index.
*/
private void checkCacheClusterMetrics(int cacheIdx,
long cacheSize,
long offHeapEntriesCnt,
long offHeapPrimaryEntriesCnt,
long offHeapBackupEntriesCnt,
long heapEntriesCnt
) {
long cacheSizeSum = 0;
long offHeapEntriesCntSum = 0;
long offHeapPrimaryEntriesCntSum = 0;
long offHeapBackupEntriesCntSum = 0;
long heapEntriesCntSum = 0;
boolean isEmptySum = true;
for (int igniteIdx = 0; igniteIdx < GRID_CNT; igniteIdx++) {
IgniteCache cache = grid(igniteIdx).cache(CACHE_PREFIX + cacheIdx);
CacheMetrics metrics = cache.metrics();
String cacheInfo = "igniteIdx=" + igniteIdx + ", cacheIdx=" + cacheIdx + " ";
assertEquals(cacheInfo + " CacheSize", cacheSize, metrics.getCacheSize());
assertEquals(cacheInfo + " offHeapEntriesCnt", offHeapEntriesCnt,
metrics.getOffHeapEntriesCount());
assertEquals(cacheInfo + " offHeapBackupEntriesCnt", offHeapBackupEntriesCnt,
metrics.getOffHeapBackupEntriesCount());
assertEquals(cacheInfo + " offHeapPrimaryEntriesCnt", offHeapPrimaryEntriesCnt,
metrics.getOffHeapPrimaryEntriesCount());
if (!MvccFeatureChecker.forcedMvcc()) // Onheap cache is not supported in Mvcc mode.
assertEquals(cacheInfo + " heapEntriesCnt", heapEntriesCnt, metrics.getHeapEntriesCount());
assertEquals(cacheInfo + " size", cacheSize, metrics.getSize());
assertEquals(cacheInfo + " keySize", cacheSize, metrics.getKeySize());
assertEquals(cacheInfo + " isEmpty", cacheSize == 0, metrics.isEmpty());
metrics = cache.localMetrics();
cacheSizeSum += metrics.getCacheSize();
offHeapEntriesCntSum += metrics.getOffHeapEntriesCount();
offHeapPrimaryEntriesCntSum += metrics.getOffHeapPrimaryEntriesCount();
offHeapBackupEntriesCntSum += metrics.getOffHeapBackupEntriesCount();
heapEntriesCntSum += metrics.getHeapEntriesCount();
isEmptySum = isEmptySum && metrics.isEmpty();
}
String cacheInfo = "cacheIdx=" + cacheIdx + " check sum";
assertEquals(cacheInfo + " CacheSize", cacheSize, cacheSizeSum);
assertEquals(cacheInfo + " offHeapEntriesCnt", offHeapEntriesCnt, offHeapEntriesCntSum);
assertEquals(cacheInfo + " offHeapBackupEntriesCnt", offHeapBackupEntriesCnt, offHeapBackupEntriesCntSum);
assertEquals(cacheInfo + " offHeapPrimaryEntriesCnt", offHeapPrimaryEntriesCnt, offHeapPrimaryEntriesCntSum);
if (!MvccFeatureChecker.forcedMvcc()) // Onheap cache is not supported in Mvcc mode.
assertEquals(cacheInfo + " heapEntriesCnt", heapEntriesCnt, heapEntriesCntSum);
assertEquals(cacheInfo + " isEmpty", cacheSize == 0, isEmptySum);
}
}