Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2994,6 +2994,42 @@ public long[] getPerLevelSizeBytes()
return compactionStrategyManager.getPerLevelSizeBytes();
}

@Override
public double[] getPerLevelAvgTokenSpace()
{
return compactionStrategyManager.getPerLevelAvgTokenSpace();
}

@Override
public double[] getPerLevelMaxDensityThreshold()
{
return compactionStrategyManager.getPerLevelMaxDensityThreshold();
}

@Override
public double[] getPerLevelAvgSize()
{
return compactionStrategyManager.getPerLevelAvgSize();
}

@Override
public double[] getPerLevelAvgDensity()
{
return compactionStrategyManager.getPerLevelAvgDensity();
}

@Override
public double[] getPerLevelAvgDensityMaxDensityThresholdRatio()
{
return compactionStrategyManager.getPerLevelAvgDensityMaxDensityThresholdRatio();
}

@Override
public double[] getPerLevelMaxDensityMaxDensityThresholdRatio()
{
return compactionStrategyManager.getPerLevelMaxDensityMaxDensityThresholdRatio();
}

@Override
public boolean isLeveledCompaction()
{
Expand Down
42 changes: 42 additions & 0 deletions src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,48 @@ public List<String> importNewSSTables(Set<String> srcPaths,
*/
public long[] getPerLevelSizeBytes();

/**
* @return average of sstable covered token spaces in each level.
* null unless unified compaction strategy is used.
* array index corresponds to level(int[0] is for level 0, ...).
*/
public double[] getPerLevelAvgTokenSpace();

/**
* @return the maximum density each level is allowed to hold.
* null unless unified compaction strategy is used.
* array index corresponds to level(int[0] is for level 0, ...).
*/
public double[] getPerLevelMaxDensityThreshold();

/**
* @return the average size of sstables in each level.
* null unless unified compaction strategy is used.
* array index corresponds to level(int[0] is for level 0, ...).
*/
public double[] getPerLevelAvgSize();

/**
* @return the average density of sstables in each level.
* null unless unified compaction strategy is used.
* array index corresponds to level(int[0] is for level 0, ...).
*/
public double[] getPerLevelAvgDensity();

/**
* @return the ratio of avg density to the maximum density threshold of that level
* in each level. null unless unified compaction strategy is used.
* array index corresponds to level(int[0] is for level 0, ...).
*/
public double[] getPerLevelAvgDensityMaxDensityThresholdRatio();

/**
* @return the ratio of maximum density to the maximum density threshold of that level
* in each level. null unless unified compaction strategy is used.
* array index corresponds to level(int[0] is for level 0, ...).
*/
public double[] getPerLevelMaxDensityMaxDensityThresholdRatio();

/**
* @return true if the table is using LeveledCompactionStrategy. false otherwise.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -80,6 +81,8 @@
import org.apache.cassandra.schema.CompactionParams;
import org.apache.cassandra.service.ActiveRepairService;
import org.apache.cassandra.utils.TimeUUID;
import org.apache.cassandra.utils.TriFunction;
import org.apache.cassandra.db.compaction.UnifiedCompactionStrategy.Level;

import static org.apache.cassandra.db.compaction.AbstractStrategyHolder.GroupedSSTableContainer;

Expand Down Expand Up @@ -690,6 +693,94 @@ public long[] getPerLevelSizeBytes()
}
}

public double[] getPerLevelAvgTokenSpace()
{
return avgUCSHelper((ucs, sstable) ->
sstable.tokenSpaceCoverage());
}

public double[] getPerLevelMaxDensityThreshold()
{
return perLevelUCSHelper((level, sstable, acc) -> Math.max(acc, level.max));
}

public double[] getPerLevelAvgSize()
{
return avgUCSHelper((ucs, sstable) -> (double) sstable.onDiskLength());
}

public double[] getPerLevelAvgDensity()
{
return avgUCSHelper(UnifiedCompactionStrategy::getDensity);
}

public double[] getPerLevelAvgDensityMaxDensityThresholdRatio()
{
readLock.lock();
try
{
if (repaired.first() instanceof UnifiedCompactionStrategy)
{
double[] avgDensityPerLevel = getPerLevelAvgDensity();
double[] maxDensityThresholdPerLevel = getPerLevelMaxDensityThreshold();

double[] res = new double[avgDensityPerLevel.length];

for (int i = 0; i < avgDensityPerLevel.length; i++)
{
res[i] = avgDensityPerLevel[i] / maxDensityThresholdPerLevel[i];
}

return res;
}
return null;
}
finally
{
readLock.unlock();
}
}

public double[] getPerLevelMaxDensityMaxDensityThresholdRatio()
{
readLock.lock();
try
{
if (repaired.first() instanceof UnifiedCompactionStrategy)
{

double[] maxDensityThresholdPerLevel = getPerLevelMaxDensityThreshold();
double[] maxDensityPerLevel = new double[maxDensityThresholdPerLevel.length];
double[] res = new double[maxDensityThresholdPerLevel.length];

for (AbstractCompactionStrategy strategy : getAllStrategies())
{
UnifiedCompactionStrategy ucsStrategy = (UnifiedCompactionStrategy) strategy;
List<Level> levels = ucsStrategy.getLevelsSnapshot();
for (int i = 0; i < levels.size(); i++)
{
for (SSTableReader sstable : levels.get(i).getSSTables())
{
maxDensityPerLevel[i] = Math.max(maxDensityPerLevel[i], ucsStrategy.getDensity(sstable));
}
}
}

for (int i = 0; i < maxDensityThresholdPerLevel.length; i++)
{
res[i] = maxDensityPerLevel[i] / maxDensityThresholdPerLevel[i];
}

return res;
}
return null;
}
finally
{
readLock.unlock();
}
}

public boolean isLeveledCompaction()
{
readLock.lock();
Expand All @@ -702,6 +793,85 @@ public boolean isLeveledCompaction()
}
}

double[] avgUCSHelper(BiFunction<UnifiedCompactionStrategy, SSTableReader, Double> fn)
{
readLock.lock();
try
{
if (repaired.first() instanceof UnifiedCompactionStrategy)
{
int numberOfLevels = 0;

double[] sum = new double[UnifiedCompactionStrategy.MAX_LEVELS];
int[] count = new int[UnifiedCompactionStrategy.MAX_LEVELS];

for (AbstractCompactionStrategy strategy : getAllStrategies())
{
UnifiedCompactionStrategy ucsStrategy = (UnifiedCompactionStrategy) strategy;
List<Level> levels = ucsStrategy.getLevelsSnapshot();
numberOfLevels = Math.max(numberOfLevels, levels.size());
for (int i = 0; i < levels.size(); i++)
{
for (SSTableReader sstable : levels.get(i).getSSTables())
{
sum[i] += fn.apply(ucsStrategy, sstable);
count[i] += 1;
}
}
}

double[] res = new double[numberOfLevels];
for (int i = 0; i < numberOfLevels; i++)
res[i] = count[i] == 0 ? 0 : sum[i] / count[i];

return res;
}
return null;
}
finally
{
readLock.unlock();
}
}

double[] perLevelUCSHelper(TriFunction<Level, SSTableReader, Double, Double> fn)
{
readLock.lock();
try
{
if (repaired.first() instanceof UnifiedCompactionStrategy)
{
int numberOfLevels = 0;

double[] tmp = new double[UnifiedCompactionStrategy.MAX_LEVELS];

for (AbstractCompactionStrategy strategy : getAllStrategies())
{
UnifiedCompactionStrategy ucsStrategy = (UnifiedCompactionStrategy) strategy;
List<Level> levels = ucsStrategy.getLevelsSnapshot();
numberOfLevels = Math.max(numberOfLevels, levels.size());
for (int i = 0; i < levels.size(); i++)
{
for (SSTableReader sstable : levels.get(i).getSSTables())
{
tmp[i] = fn.apply(levels.get(i), sstable, tmp[i]);
}
}
}

double[] res = new double[numberOfLevels];
System.arraycopy(tmp, 0, res, 0, numberOfLevels);

return res;
}
return null;
}
finally
{
readLock.unlock();
}
}

public int[] getSSTableCountPerTWCSBucket()
{
readLock.lock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,25 @@ List<Level> getLevels()
return getLevels(getSSTables(), UnifiedCompactionStrategy::isSuitableForCompaction);
}

/**
* @return a list of the levels in the compaction hierarchy, that also includes SSTables that
* are currently undergoing compaction. This is used only for table stats so we can have a consistent
* snapshot of the levels.
*/
@VisibleForTesting
List<Level> getLevelsSnapshot()
{
Set<SSTableReader> sstables = getSSTables();
List<SSTableReader> suitable = new ArrayList<>(sstables.size());
for (SSTableReader rdr : sstables)
{
if (isSuitableForCompaction(rdr))
suitable.add(rdr);
}

return formLevels(suitable);
}

/**
* Groups the sstables passed in into levels. This is used by the strategy to determine
* new compactions, and by external tools to analyze the strategy decisions.
Expand All @@ -546,6 +565,11 @@ public List<Level> getLevels(Collection<SSTableReader> sstables,
return formLevels(suitable);
}

public double getDensity(SSTableReader sstable)
{
return shardManager.density(sstable);
}

private List<Level> formLevels(List<SSTableReader> suitable)
{
maybeUpdateShardManager();
Expand All @@ -557,7 +581,7 @@ private List<Level> formLevels(List<SSTableReader> suitable)
Level level = new Level(controller, index, 0, maxDensity);
for (SSTableReader candidate : suitable)
{
final double density = shardManager.density(candidate);
final double density = getDensity(candidate);
if (density < level.max)
{
level.add(candidate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class StatsTable
public String tableName;
public boolean isIndex;
public boolean isLeveledSstable = false;
public boolean isUCSSstable = false;
public Object sstableCount;
public Object oldSSTableCount;
public Long maxSSTableSize;
Expand Down Expand Up @@ -72,6 +73,12 @@ public class StatsTable
public long maximumTombstonesPerSliceLastFiveMinutes;
public List<String> sstablesInEachLevel = new ArrayList<>();
public List<String> sstableBytesInEachLevel = new ArrayList<>();
public List<String> sstableAvgTokenSpaceInEachLevel = new ArrayList<>();
public List<String> sstableMaxDensityThresholdInEachLevel = new ArrayList<>();
public List<String> sstableAvgSizeInEachLevel = new ArrayList<>();
public List<String> sstableAvgDensityInEachLevel = new ArrayList<>();
public List<String> sstableAvgDensityMaxDensityThresholdRatioInEachLevel = new ArrayList<>();
public List<String> sstableMaxDensityMaxDensityThresholdRatioInEachLevel = new ArrayList<>();
public int[] sstableCountPerTWCSBucket = null;
public Boolean isInCorrectLocation = null; // null: option not active
public double droppableTombstoneRatio;
Expand Down
Loading