From 1f917dd54f0d1d7e80207d06e822b54684b6f197 Mon Sep 17 00:00:00 2001 From: James King Date: Mon, 7 Dec 2015 14:32:26 -0800 Subject: [PATCH 1/3] Adding the ability to give high tombstone ratio sstages compaction precdence --- .../TimeWindowCompactionStrategy.java | 108 +++++++++++++++++- .../TimeWindowCompactionStrategyOptions.java | 23 +++- 2 files changed, 127 insertions(+), 4 deletions(-) diff --git a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java index 5bf24bc..3c33bee 100644 --- a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java +++ b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import java.util.concurrent.TimeUnit; @@ -34,7 +35,11 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import org.apache.cassandra.dht.Range; +import org.apache.cassandra.dht.Token; +import org.apache.cassandra.io.sstable.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -112,6 +117,7 @@ private List getNextBackgroundSSTables(final int gcBefore) Set candidates = Sets.newHashSet(filterSuspectSSTables(uncompacting)); List compactionCandidates = new ArrayList(getNextNonExpiredSSTables(Sets.difference(candidates, expired), gcBefore)); + if (!expired.isEmpty()) { logger.debug("Including expired sstables: {}", expired); @@ -123,6 +129,17 @@ private List getNextBackgroundSSTables(final int gcBefore) private List getNextNonExpiredSSTables(Iterable nonExpiringSSTables, final int gcBefore) { + /* + * Not all SSTables have TTLs that drop around the same time. In some cases there are tables that have 99% of records that + * drop at the same time and 1% that will live significantly longer. These SSTables tend to get starved for compaction and end up + * sitting round taking up more space than the system can handle. This first check prioritizes files with very high tombstone ratios + * so that we don't eat up all the disk on a machine. + */ + SSTableReader sstablesWithMaxTombstoneRatio = getHigestMaxedOutTombstoneRatioSstable(nonExpiringSSTables, gcBefore); + + if (sstablesWithMaxTombstoneRatio != null) return Collections.singletonList(sstablesWithMaxTombstoneRatio); + + // Now check for the most interesting tables. List mostInteresting = getCompactionCandidates(nonExpiringSSTables); if (mostInteresting != null) @@ -141,7 +158,33 @@ private List getNextNonExpiredSSTables(Iterable no if (sstablesWithTombstones.isEmpty()) return Collections.emptyList(); - return Collections.singletonList(Collections.min(sstablesWithTombstones, new SSTableReader.SizeComparator())); + // Compact the tables with the highest tombstone ratios first. + return Collections.singletonList(Collections.max(sstablesWithTombstones, (o1, o2) -> + Double.compare(o1.getEstimatedDroppableTombstoneRatio(gcBefore), o2.getEstimatedDroppableTombstoneRatio(gcBefore)))); + } + + /*** + * @param nonExpiringSSTables + * @param gcBefore + * @return The SSTableReader with the highest tombstone ratio that is above the threashold + */ + private SSTableReader getHigestMaxedOutTombstoneRatioSstable(Iterable nonExpiringSSTables, final int gcBefore) + { + List sstablesWithMaxTombstoneRatio = Lists.newArrayList(); + + for (SSTableReader sstable : nonExpiringSSTables) + { + if (reachedMaxTombstonesRatio(sstable, gcBefore)) + sstablesWithMaxTombstoneRatio.add(sstable); + } + + if(sstablesWithMaxTombstoneRatio.size() > 0) + { + return Collections.max(sstablesWithMaxTombstoneRatio, (o1, o2) -> + Double.compare(o1.getEstimatedDroppableTombstoneRatio(gcBefore), o2.getEstimatedDroppableTombstoneRatio(gcBefore))); + } + + return null; } private List getCompactionCandidates(Iterable candidateSSTables) @@ -389,4 +432,65 @@ public String toString() cfs.getMinimumCompactionThreshold(), cfs.getMaximumCompactionThreshold()); } -} + + /** + * Check if given sstable is worth dropping tombstones at gcBefore. + * Check is skipped if tombstone_compaction_interval time does not elapse since sstable creation and returns false. + * + * @param sstable SSTable to check + * @param gcBefore time to drop tombstones + * @return true if given sstable's tombstones are expected to be removed + */ + protected boolean reachedMaxTombstonesRatio(SSTableReader sstable, int gcBefore) + { + if (disableTombstoneCompactions) + return false; + // since we use estimations to calculate, there is a chance that compaction will not drop tombstones actually. + // if that happens we will end up in infinite compaction loop, so first we check enough if enough time has + // elapsed since SSTable created. + if (System.currentTimeMillis() < sstable.getCreationTimeFor(Component.DATA) + tombstoneCompactionInterval * 1000) + return false; + + double droppableRatio = sstable.getEstimatedDroppableTombstoneRatio(gcBefore); + + if (droppableRatio <= options.tombstoneMaxRatio) + return false; + + //sstable range overlap check is disabled. See CASSANDRA-6563. + if (uncheckedTombstoneCompaction) + return true; + + Collection overlaps = cfs.getOverlappingSSTables(Collections.singleton(sstable)); + if (overlaps.isEmpty()) + { + // there is no overlap, tombstones are safely droppable + return true; + } + else if (CompactionController.getFullyExpiredSSTables(cfs, Collections.singleton(sstable), overlaps, gcBefore).size() > 0) + { + return true; + } + else + { + // what percentage of columns do we expect to compact outside of overlap? + if (sstable.getIndexSummarySize() < 2) + { + // we have too few samples to estimate correct percentage + return false; + } + // first, calculate estimated keys that do not overlap + long keys = sstable.estimatedKeys(); + Set> ranges = new HashSet>(overlaps.size()); + for (SSTableReader overlap : overlaps) + ranges.add(new Range(overlap.first.getToken(), overlap.last.getToken(), overlap.partitioner)); + long remainingKeys = keys - sstable.estimatedKeysForRanges(ranges); + // next, calculate what percentage of columns we have within those keys + long columns = sstable.getEstimatedColumnCount().mean() * remainingKeys; + double remainingColumnsRatio = ((double) columns) / (sstable.getEstimatedColumnCount().count() * sstable.getEstimatedColumnCount().mean()); + + // return if we still expect to have droppable tombstones in rest of columns + return remainingColumnsRatio * droppableRatio > tombstoneThreshold; + } + } + +} \ No newline at end of file diff --git a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java index c4b7ac5..1899b49 100644 --- a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java +++ b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java @@ -23,13 +23,12 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import org.apache.cassandra.db.compaction.*; import org.apache.cassandra.exceptions.ConfigurationException; - public final class TimeWindowCompactionStrategyOptions { protected static final TimeUnit DEFAULT_TIMESTAMP_RESOLUTION = TimeUnit.MICROSECONDS; protected static final TimeUnit DEFAULT_COMPACTION_WINDOW_UNIT = TimeUnit.DAYS; + protected static final float DEFAULT_TOMBSTONE_MAX_RATIO = 1.0f; protected static final int DEFAULT_COMPACTION_WINDOW_SIZE = 1; protected static final int DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS = 60 * 10; @@ -37,11 +36,13 @@ public final class TimeWindowCompactionStrategyOptions protected static final String COMPACTION_WINDOW_UNIT_KEY = "compaction_window_unit"; protected static final String COMPACTION_WINDOW_SIZE_KEY = "compaction_window_size"; protected static final String EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY = "expired_sstable_check_frequency_seconds"; + protected static final String TOMBSTONE_MAX_RATIO = "tombstone_max_ratio"; protected final int sstableWindowSize; protected final TimeUnit sstableWindowUnit; protected final TimeUnit timestampResolution; protected final long expiredSSTableCheckFrequency; + protected final float tombstoneMaxRatio; protected final static ImmutableList validTimestampTimeUnits = ImmutableList.of(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, TimeUnit.MICROSECONDS, TimeUnit.NANOSECONDS); protected final static ImmutableList validWindowTimeUnits = ImmutableList.of(TimeUnit.MINUTES, TimeUnit.HOURS, TimeUnit.DAYS); @@ -62,6 +63,9 @@ public TimeWindowCompactionStrategyOptions(Map options) optionValue = options.get(EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY); expiredSSTableCheckFrequency = TimeUnit.MILLISECONDS.convert(optionValue == null ? DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS : Long.parseLong(optionValue), TimeUnit.SECONDS); + optionValue = options.get(TOMBSTONE_MAX_RATIO); + tombstoneMaxRatio = optionValue == null ? DEFAULT_TOMBSTONE_MAX_RATIO : Float.parseFloat(optionValue); + stcsOptions = new SizeTieredCompactionStrategyOptions(options); } @@ -71,6 +75,7 @@ public TimeWindowCompactionStrategyOptions() timestampResolution = DEFAULT_TIMESTAMP_RESOLUTION; sstableWindowSize = DEFAULT_COMPACTION_WINDOW_SIZE; expiredSSTableCheckFrequency = TimeUnit.MILLISECONDS.convert(DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS, TimeUnit.SECONDS); + tombstoneMaxRatio = DEFAULT_TOMBSTONE_MAX_RATIO; stcsOptions = new SizeTieredCompactionStrategyOptions(); } @@ -130,11 +135,25 @@ public static Map validateOptions(Map options, M throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY), e); } + optionValue = options.get(TOMBSTONE_MAX_RATIO); + try + { + float tombstoneMaxRatio = optionValue == null ? DEFAULT_TOMBSTONE_MAX_RATIO : Float.parseFloat(optionValue); + if (tombstoneMaxRatio > 1.0) + { + throw new ConfigurationException(String.format("%s must not be greater than 1.0", DEFAULT_TOMBSTONE_MAX_RATIO, tombstoneMaxRatio)); + } + } + catch (NumberFormatException e) + { + throw new ConfigurationException(String.format("%s is not a parsable float for %s", optionValue, DEFAULT_COMPACTION_WINDOW_SIZE), e); + } uncheckedOptions.remove(COMPACTION_WINDOW_SIZE_KEY); uncheckedOptions.remove(COMPACTION_WINDOW_UNIT_KEY); uncheckedOptions.remove(TIMESTAMP_RESOLUTION_KEY); uncheckedOptions.remove(EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY); + uncheckedOptions.remove(TOMBSTONE_MAX_RATIO); uncheckedOptions = SizeTieredCompactionStrategyOptions.validateOptions(options, uncheckedOptions); From 935f8bf5319addca139ad8e2a93bd267e1537d55 Mon Sep 17 00:00:00 2001 From: James King Date: Mon, 7 Dec 2015 16:53:11 -0800 Subject: [PATCH 2/3] Removing the max tombstone ratio and rearranging the order of sstable checks --- .../TimeWindowCompactionStrategy.java | 119 +++--------------- .../TimeWindowCompactionStrategyOptions.java | 23 +--- 2 files changed, 17 insertions(+), 125 deletions(-) diff --git a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java index 3c33bee..25cc8aa 100644 --- a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java +++ b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java @@ -129,62 +129,34 @@ private List getNextBackgroundSSTables(final int gcBefore) private List getNextNonExpiredSSTables(Iterable nonExpiringSSTables, final int gcBefore) { - /* - * Not all SSTables have TTLs that drop around the same time. In some cases there are tables that have 99% of records that - * drop at the same time and 1% that will live significantly longer. These SSTables tend to get starved for compaction and end up - * sitting round taking up more space than the system can handle. This first check prioritizes files with very high tombstone ratios - * so that we don't eat up all the disk on a machine. - */ - SSTableReader sstablesWithMaxTombstoneRatio = getHigestMaxedOutTombstoneRatioSstable(nonExpiringSSTables, gcBefore); - - if (sstablesWithMaxTombstoneRatio != null) return Collections.singletonList(sstablesWithMaxTombstoneRatio); - - // Now check for the most interesting tables. - List mostInteresting = getCompactionCandidates(nonExpiringSSTables); - - if (mostInteresting != null) - { - return mostInteresting; - } - - // if there is no sstable to compact in standard way, try compacting single sstable whose droppable tombstone - // ratio is greater than threshold. + // First get the a list of tables that could drop tombstones. List sstablesWithTombstones = new ArrayList<>(); for (SSTableReader sstable : nonExpiringSSTables) { if (worthDroppingTombstones(sstable, gcBefore)) sstablesWithTombstones.add(sstable); } - if (sstablesWithTombstones.isEmpty()) - return Collections.emptyList(); - // Compact the tables with the highest tombstone ratios first. - return Collections.singletonList(Collections.max(sstablesWithTombstones, (o1, o2) -> - Double.compare(o1.getEstimatedDroppableTombstoneRatio(gcBefore), o2.getEstimatedDroppableTombstoneRatio(gcBefore)))); - } + // If there are files that could be compacted because they reached their tombstone ratio, then clean them up. + // NOTE: You should set a high tombstone ratio so you're not constantly compacting SSTables. + if(!sstablesWithTombstones.isEmpty()) + { + // Compact the tables with the highest tombstone ratios first. + return Collections.singletonList(Collections.max(sstablesWithTombstones, (o1, o2) -> + Double.compare(o1.getEstimatedDroppableTombstoneRatio(gcBefore), o2.getEstimatedDroppableTombstoneRatio(gcBefore)))); + } - /*** - * @param nonExpiringSSTables - * @param gcBefore - * @return The SSTableReader with the highest tombstone ratio that is above the threashold - */ - private SSTableReader getHigestMaxedOutTombstoneRatioSstable(Iterable nonExpiringSSTables, final int gcBefore) - { - List sstablesWithMaxTombstoneRatio = Lists.newArrayList(); + // Now check for the most interesting tables. + List mostInteresting = getCompactionCandidates(nonExpiringSSTables); - for (SSTableReader sstable : nonExpiringSSTables) + if (mostInteresting != null) { - if (reachedMaxTombstonesRatio(sstable, gcBefore)) - sstablesWithMaxTombstoneRatio.add(sstable); + return mostInteresting; } - - if(sstablesWithMaxTombstoneRatio.size() > 0) + else { - return Collections.max(sstablesWithMaxTombstoneRatio, (o1, o2) -> - Double.compare(o1.getEstimatedDroppableTombstoneRatio(gcBefore), o2.getEstimatedDroppableTombstoneRatio(gcBefore))); + return Collections.emptyList(); } - - return null; } private List getCompactionCandidates(Iterable candidateSSTables) @@ -432,65 +404,4 @@ public String toString() cfs.getMinimumCompactionThreshold(), cfs.getMaximumCompactionThreshold()); } - - /** - * Check if given sstable is worth dropping tombstones at gcBefore. - * Check is skipped if tombstone_compaction_interval time does not elapse since sstable creation and returns false. - * - * @param sstable SSTable to check - * @param gcBefore time to drop tombstones - * @return true if given sstable's tombstones are expected to be removed - */ - protected boolean reachedMaxTombstonesRatio(SSTableReader sstable, int gcBefore) - { - if (disableTombstoneCompactions) - return false; - // since we use estimations to calculate, there is a chance that compaction will not drop tombstones actually. - // if that happens we will end up in infinite compaction loop, so first we check enough if enough time has - // elapsed since SSTable created. - if (System.currentTimeMillis() < sstable.getCreationTimeFor(Component.DATA) + tombstoneCompactionInterval * 1000) - return false; - - double droppableRatio = sstable.getEstimatedDroppableTombstoneRatio(gcBefore); - - if (droppableRatio <= options.tombstoneMaxRatio) - return false; - - //sstable range overlap check is disabled. See CASSANDRA-6563. - if (uncheckedTombstoneCompaction) - return true; - - Collection overlaps = cfs.getOverlappingSSTables(Collections.singleton(sstable)); - if (overlaps.isEmpty()) - { - // there is no overlap, tombstones are safely droppable - return true; - } - else if (CompactionController.getFullyExpiredSSTables(cfs, Collections.singleton(sstable), overlaps, gcBefore).size() > 0) - { - return true; - } - else - { - // what percentage of columns do we expect to compact outside of overlap? - if (sstable.getIndexSummarySize() < 2) - { - // we have too few samples to estimate correct percentage - return false; - } - // first, calculate estimated keys that do not overlap - long keys = sstable.estimatedKeys(); - Set> ranges = new HashSet>(overlaps.size()); - for (SSTableReader overlap : overlaps) - ranges.add(new Range(overlap.first.getToken(), overlap.last.getToken(), overlap.partitioner)); - long remainingKeys = keys - sstable.estimatedKeysForRanges(ranges); - // next, calculate what percentage of columns we have within those keys - long columns = sstable.getEstimatedColumnCount().mean() * remainingKeys; - double remainingColumnsRatio = ((double) columns) / (sstable.getEstimatedColumnCount().count() * sstable.getEstimatedColumnCount().mean()); - - // return if we still expect to have droppable tombstones in rest of columns - return remainingColumnsRatio * droppableRatio > tombstoneThreshold; - } - } - } \ No newline at end of file diff --git a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java index 1899b49..c4b7ac5 100644 --- a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java +++ b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java @@ -23,12 +23,13 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.apache.cassandra.db.compaction.*; import org.apache.cassandra.exceptions.ConfigurationException; + public final class TimeWindowCompactionStrategyOptions { protected static final TimeUnit DEFAULT_TIMESTAMP_RESOLUTION = TimeUnit.MICROSECONDS; protected static final TimeUnit DEFAULT_COMPACTION_WINDOW_UNIT = TimeUnit.DAYS; - protected static final float DEFAULT_TOMBSTONE_MAX_RATIO = 1.0f; protected static final int DEFAULT_COMPACTION_WINDOW_SIZE = 1; protected static final int DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS = 60 * 10; @@ -36,13 +37,11 @@ public final class TimeWindowCompactionStrategyOptions protected static final String COMPACTION_WINDOW_UNIT_KEY = "compaction_window_unit"; protected static final String COMPACTION_WINDOW_SIZE_KEY = "compaction_window_size"; protected static final String EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY = "expired_sstable_check_frequency_seconds"; - protected static final String TOMBSTONE_MAX_RATIO = "tombstone_max_ratio"; protected final int sstableWindowSize; protected final TimeUnit sstableWindowUnit; protected final TimeUnit timestampResolution; protected final long expiredSSTableCheckFrequency; - protected final float tombstoneMaxRatio; protected final static ImmutableList validTimestampTimeUnits = ImmutableList.of(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, TimeUnit.MICROSECONDS, TimeUnit.NANOSECONDS); protected final static ImmutableList validWindowTimeUnits = ImmutableList.of(TimeUnit.MINUTES, TimeUnit.HOURS, TimeUnit.DAYS); @@ -63,9 +62,6 @@ public TimeWindowCompactionStrategyOptions(Map options) optionValue = options.get(EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY); expiredSSTableCheckFrequency = TimeUnit.MILLISECONDS.convert(optionValue == null ? DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS : Long.parseLong(optionValue), TimeUnit.SECONDS); - optionValue = options.get(TOMBSTONE_MAX_RATIO); - tombstoneMaxRatio = optionValue == null ? DEFAULT_TOMBSTONE_MAX_RATIO : Float.parseFloat(optionValue); - stcsOptions = new SizeTieredCompactionStrategyOptions(options); } @@ -75,7 +71,6 @@ public TimeWindowCompactionStrategyOptions() timestampResolution = DEFAULT_TIMESTAMP_RESOLUTION; sstableWindowSize = DEFAULT_COMPACTION_WINDOW_SIZE; expiredSSTableCheckFrequency = TimeUnit.MILLISECONDS.convert(DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS, TimeUnit.SECONDS); - tombstoneMaxRatio = DEFAULT_TOMBSTONE_MAX_RATIO; stcsOptions = new SizeTieredCompactionStrategyOptions(); } @@ -135,25 +130,11 @@ public static Map validateOptions(Map options, M throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY), e); } - optionValue = options.get(TOMBSTONE_MAX_RATIO); - try - { - float tombstoneMaxRatio = optionValue == null ? DEFAULT_TOMBSTONE_MAX_RATIO : Float.parseFloat(optionValue); - if (tombstoneMaxRatio > 1.0) - { - throw new ConfigurationException(String.format("%s must not be greater than 1.0", DEFAULT_TOMBSTONE_MAX_RATIO, tombstoneMaxRatio)); - } - } - catch (NumberFormatException e) - { - throw new ConfigurationException(String.format("%s is not a parsable float for %s", optionValue, DEFAULT_COMPACTION_WINDOW_SIZE), e); - } uncheckedOptions.remove(COMPACTION_WINDOW_SIZE_KEY); uncheckedOptions.remove(COMPACTION_WINDOW_UNIT_KEY); uncheckedOptions.remove(TIMESTAMP_RESOLUTION_KEY); uncheckedOptions.remove(EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY); - uncheckedOptions.remove(TOMBSTONE_MAX_RATIO); uncheckedOptions = SizeTieredCompactionStrategyOptions.validateOptions(options, uncheckedOptions); From faed6a411e86bbdfdeed18064da1d418887b7cd6 Mon Sep 17 00:00:00 2001 From: James King Date: Mon, 7 Dec 2015 16:57:39 -0800 Subject: [PATCH 3/3] Adding to comments --- .../cassandra/db/compaction/TimeWindowCompactionStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java index 25cc8aa..fb0a9b3 100644 --- a/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java +++ b/TimeWindowCompactionStrategy/src/main/java/com/jeffjirsa/cassandra/db/compaction/TimeWindowCompactionStrategy.java @@ -138,7 +138,7 @@ private List getNextNonExpiredSSTables(Iterable no } // If there are files that could be compacted because they reached their tombstone ratio, then clean them up. - // NOTE: You should set a high tombstone ratio so you're not constantly compacting SSTables. + // NOTE: You should set a the tombstone ratio and tombstone compaction interval high enough so you're not constantly compacting SSTables. if(!sstablesWithTombstones.isEmpty()) { // Compact the tables with the highest tombstone ratios first.