You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ma...@apache.org on 2015/08/10 09:20:10 UTC
cassandra git commit: Add new JMX methods to change local compaction
strategy
Repository: cassandra
Updated Branches:
refs/heads/cassandra-2.1 c8d163f73 -> 5aca7d79a
Add new JMX methods to change local compaction strategy
Patch by marcuse; reviewed by iamaleksey for CASSANDRA-9965
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5aca7d79
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5aca7d79
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5aca7d79
Branch: refs/heads/cassandra-2.1
Commit: 5aca7d79aaf88f9c34dcae52f24bb62a28add91e
Parents: c8d163f
Author: Marcus Eriksson <ma...@apache.org>
Authored: Tue Aug 4 20:31:25 2015 +0200
Committer: Marcus Eriksson <ma...@apache.org>
Committed: Mon Aug 10 09:02:47 2015 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
NEWS.txt | 3 +-
.../org/apache/cassandra/config/CFMetaData.java | 10 ++-
.../apache/cassandra/db/ColumnFamilyStore.java | 35 +++++++++
.../cassandra/db/ColumnFamilyStoreMBean.java | 21 +++++
.../compaction/AbstractCompactionStrategy.java | 2 +-
.../compaction/WrappingCompactionStrategy.java | 51 +++++++++---
.../db/compaction/CompactionsCQLTest.java | 82 +++++++++++++++++++-
8 files changed, 190 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7151883..462de44 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.1.9
+ * Add new JMX methods to change local compaction strategy (CASSANDRA-9965)
* Write hints for paxos commits (CASSANDRA-7342)
* (cqlsh) Fix timestamps before 1970 on Windows, always
use UTC for timestamp display (CASSANDRA-10000)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 0b64e31..f6e2665 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -24,7 +24,8 @@ Upgrading
- Commit log files are no longer recycled by default, due to negative
performance implications. This can be enabled again with the
commitlog_segment_recycling option in your cassandra.yaml
-
+ - JMX methods set/getCompactionStrategyClass have been deprecated, use
+ set/getLocalCompactionStrategy/set/getLocalCompactionStrategyJson instead
2.1.8
=====
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index 4bc5f1b..2c6a30c 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -1283,7 +1283,9 @@ public final class CFMetaData
return strategyClass;
}
- public AbstractCompactionStrategy createCompactionStrategyInstance(ColumnFamilyStore cfs)
+ public static AbstractCompactionStrategy createCompactionStrategyInstance(Class<? extends AbstractCompactionStrategy> compactionStrategyClass,
+ ColumnFamilyStore cfs,
+ Map<String, String> compactionStrategyOptions)
{
try
{
@@ -1297,6 +1299,12 @@ public final class CFMetaData
}
}
+ @Deprecated
+ public AbstractCompactionStrategy createCompactionStrategyInstance(ColumnFamilyStore cfs)
+ {
+ return createCompactionStrategyInstance(compactionStrategyClass, cfs, compactionStrategyOptions);
+ }
+
// converts CFM to thrift CfDef
public org.apache.cassandra.thrift.CfDef toThrift()
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
index 6777e7a..f8d796e 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
@@ -252,6 +252,41 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
};
}
+ public void setLocalCompactionStrategyJson(String options)
+ {
+ setLocalCompactionStrategy(FBUtilities.fromJsonMap(options));
+ }
+
+ public String getLocalCompactionStrategyJson()
+ {
+ return FBUtilities.json(getLocalCompactionStrategy());
+ }
+
+ public void setLocalCompactionStrategy(Map<String, String> options)
+ {
+ try
+ {
+ Map<String, String> optionsCopy = new HashMap<>(options);
+ Class<? extends AbstractCompactionStrategy> compactionStrategyClass = CFMetaData.createCompactionStrategy(optionsCopy.get("class"));
+ optionsCopy.remove("class");
+ CFMetaData.validateCompactionOptions(compactionStrategyClass, optionsCopy);
+ compactionStrategyWrapper.setNewLocalCompactionStrategy(compactionStrategyClass, optionsCopy);
+ }
+ catch (Throwable t)
+ {
+ logger.error("Could not set new local compaction strategy", t);
+ // dont propagate the ConfigurationException over jmx, user will only see a ClassNotFoundException
+ throw new IllegalArgumentException("Could not set new local compaction strategy: "+t.getMessage());
+ }
+ }
+
+ public Map<String, String> getLocalCompactionStrategy()
+ {
+ Map<String, String> options = new HashMap<>(compactionStrategyWrapper.options);
+ options.put("class", compactionStrategyWrapper.getName());
+ return options;
+ }
+
public void setCompactionStrategyClass(String compactionStrategyClass)
{
try
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
index 4df593b..e292be4 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
@@ -311,14 +311,35 @@ public interface ColumnFamilyStoreMBean
public void setMaximumCompactionThreshold(int threshold);
/**
+ * Sets the compaction strategy locally for this node
+ *
+ * Note that this will be set until an ALTER with compaction = {..} is executed or the node is restarted
+ *
+ * @param options compaction options with the same syntax as when doing ALTER ... WITH compaction = {..}
+ */
+ public void setLocalCompactionStrategyJson(String options);
+ public String getLocalCompactionStrategyJson();
+
+ /**
+ * Sets the compaction strategy locally for this node
+ *
+ * Note that this will be set until an ALTER with compaction = {..} is executed or the node is restarted
+ *
+ * @param options compaction options map
+ */
+ public void setLocalCompactionStrategy(Map<String, String> options);
+ public Map<String, String> getLocalCompactionStrategy();
+ /**
* Sets the compaction strategy by class name
* @param className the name of the compaction strategy class
*/
+ @Deprecated
public void setCompactionStrategyClass(String className);
/**
* Gets the compaction strategy class name
*/
+ @Deprecated
public String getCompactionStrategyClass();
/**
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/src/java/org/apache/cassandra/db/compaction/AbstractCompactionStrategy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/compaction/AbstractCompactionStrategy.java b/src/java/org/apache/cassandra/db/compaction/AbstractCompactionStrategy.java
index 73cda77..77ca404 100644
--- a/src/java/org/apache/cassandra/db/compaction/AbstractCompactionStrategy.java
+++ b/src/java/org/apache/cassandra/db/compaction/AbstractCompactionStrategy.java
@@ -60,7 +60,7 @@ public abstract class AbstractCompactionStrategy
protected static final String UNCHECKED_TOMBSTONE_COMPACTION_OPTION = "unchecked_tombstone_compaction";
protected static final String COMPACTION_ENABLED = "enabled";
- protected Map<String, String> options;
+ public Map<String, String> options;
protected final ColumnFamilyStore cfs;
protected float tombstoneThreshold;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/src/java/org/apache/cassandra/db/compaction/WrappingCompactionStrategy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/compaction/WrappingCompactionStrategy.java b/src/java/org/apache/cassandra/db/compaction/WrappingCompactionStrategy.java
index 0fed733..ae67599 100644
--- a/src/java/org/apache/cassandra/db/compaction/WrappingCompactionStrategy.java
+++ b/src/java/org/apache/cassandra/db/compaction/WrappingCompactionStrategy.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -47,6 +48,16 @@ public final class WrappingCompactionStrategy extends AbstractCompactionStrategy
private static final Logger logger = LoggerFactory.getLogger(WrappingCompactionStrategy.class);
private volatile AbstractCompactionStrategy repaired;
private volatile AbstractCompactionStrategy unrepaired;
+ /*
+ We keep a copy of the schema compaction options and class here to be able to decide if we
+ should update the compaction strategy in maybeReloadCompactionStrategy() due to an ALTER.
+
+ If a user changes the local compaction strategy and then later ALTERs a compaction option,
+ we will use the new compaction options.
+ */
+ private Map<String, String> schemaCompactionOptions;
+ private Class<?> schemaCompactionStrategyClass;
+
public WrappingCompactionStrategy(ColumnFamilyStore cfs)
{
super(cfs, cfs.metadata.compactionStrategyOptions);
@@ -146,10 +157,9 @@ public final class WrappingCompactionStrategy extends AbstractCompactionStrategy
public synchronized void maybeReloadCompactionStrategy(CFMetaData metadata)
{
- if (repaired != null && repaired.getClass().equals(metadata.compactionStrategyClass)
- && unrepaired != null && unrepaired.getClass().equals(metadata.compactionStrategyClass)
- && repaired.options.equals(metadata.compactionStrategyOptions)
- && unrepaired.options.equals(metadata.compactionStrategyOptions))
+ // compare the old schema configuration to the new one, ignore any locally set changes.
+ if (metadata.compactionStrategyClass.equals(schemaCompactionStrategyClass) &&
+ metadata.compactionStrategyOptions.equals(schemaCompactionOptions))
return;
reloadCompactionStrategy(metadata);
}
@@ -157,13 +167,10 @@ public final class WrappingCompactionStrategy extends AbstractCompactionStrategy
public synchronized void reloadCompactionStrategy(CFMetaData metadata)
{
boolean disabledWithJMX = !enabled && shouldBeEnabled();
- if (repaired != null)
- repaired.shutdown();
- if (unrepaired != null)
- unrepaired.shutdown();
- repaired = metadata.createCompactionStrategyInstance(cfs);
- unrepaired = metadata.createCompactionStrategyInstance(cfs);
- options = ImmutableMap.copyOf(metadata.compactionStrategyOptions);
+ setStrategy(metadata.compactionStrategyClass, metadata.compactionStrategyOptions);
+ schemaCompactionOptions = ImmutableMap.copyOf(metadata.compactionStrategyOptions);
+ schemaCompactionStrategyClass = repaired.getClass();
+
if (disabledWithJMX || !shouldBeEnabled())
disable();
else
@@ -393,4 +400,26 @@ public final class WrappingCompactionStrategy extends AbstractCompactionStrategy
{
return Arrays.asList(repaired, unrepaired);
}
+
+ public synchronized void setNewLocalCompactionStrategy(Class<? extends AbstractCompactionStrategy> compactionStrategyClass, Map<String, String> options)
+ {
+ logger.info("Switching local compaction strategy from {} to {} with options={}", repaired == null ? "null" : repaired.getClass(), compactionStrategyClass, options);
+ setStrategy(compactionStrategyClass, options);
+ if (shouldBeEnabled())
+ enable();
+ else
+ disable();
+ startup();
+ }
+
+ private void setStrategy(Class<? extends AbstractCompactionStrategy> compactionStrategyClass, Map<String, String> options)
+ {
+ if (repaired != null)
+ repaired.shutdown();
+ if (unrepaired != null)
+ unrepaired.shutdown();
+ repaired = CFMetaData.createCompactionStrategyInstance(compactionStrategyClass, cfs, options);
+ unrepaired = CFMetaData.createCompactionStrategyInstance(compactionStrategyClass, cfs, options);
+ this.options = ImmutableMap.copyOf(options);
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/5aca7d79/test/unit/org/apache/cassandra/db/compaction/CompactionsCQLTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/compaction/CompactionsCQLTest.java b/test/unit/org/apache/cassandra/db/compaction/CompactionsCQLTest.java
index 58fc062..2798689 100644
--- a/test/unit/org/apache/cassandra/db/compaction/CompactionsCQLTest.java
+++ b/test/unit/org/apache/cassandra/db/compaction/CompactionsCQLTest.java
@@ -17,12 +17,16 @@
*/
package org.apache.cassandra.db.compaction;
+import java.util.HashMap;
+import java.util.Map;
+
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.cql3.UntypedResultSet;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -141,12 +145,88 @@ public class CompactionsCQLTest extends CQLTester
assertTrue(minorWasTriggered(KEYSPACE, currentTable()));
}
+ @Test
+ public void testSetLocalCompactionStrategy() throws Throwable
+ {
+ createTable("CREATE TABLE %s (id text PRIMARY KEY)");
+ Map<String, String> localOptions = new HashMap<>();
+ localOptions.put("class", "DateTieredCompactionStrategy");
+ getCurrentColumnFamilyStore().setLocalCompactionStrategy(localOptions);
+ WrappingCompactionStrategy wrappingCompactionStrategy = (WrappingCompactionStrategy) getCurrentColumnFamilyStore().getCompactionStrategy();
+ assertTrue(verifyStrategies(wrappingCompactionStrategy, DateTieredCompactionStrategy.class));
+ // altering something non-compaction related
+ execute("ALTER TABLE %s WITH gc_grace_seconds = 1000");
+ // should keep the local compaction strat
+ assertTrue(verifyStrategies(wrappingCompactionStrategy, DateTieredCompactionStrategy.class));
+ // altering a compaction option
+ execute("ALTER TABLE %s WITH compaction = {'class':'SizeTieredCompactionStrategy', 'min_threshold':3}");
+ // will use the new option
+ assertTrue(verifyStrategies(wrappingCompactionStrategy, SizeTieredCompactionStrategy.class));
+ }
+
+
+ @Test
+ public void testSetLocalCompactionStrategyDisable() throws Throwable
+ {
+ createTable("CREATE TABLE %s (id text PRIMARY KEY)");
+ Map<String, String> localOptions = new HashMap<>();
+ localOptions.put("class", "DateTieredCompactionStrategy");
+ localOptions.put("enabled", "false");
+ getCurrentColumnFamilyStore().setLocalCompactionStrategy(localOptions);
+ assertFalse(getCurrentColumnFamilyStore().getCompactionStrategy().isEnabled());
+ localOptions.clear();
+ localOptions.put("class", "DateTieredCompactionStrategy");
+ // localOptions.put("enabled", "true"); - this is default!
+ getCurrentColumnFamilyStore().setLocalCompactionStrategy(localOptions);
+ assertTrue(getCurrentColumnFamilyStore().getCompactionStrategy().isEnabled());
+ }
+
+
+ @Test
+ public void testSetLocalCompactionStrategyEnable() throws Throwable
+ {
+ createTable("CREATE TABLE %s (id text PRIMARY KEY)");
+ Map<String, String> localOptions = new HashMap<>();
+ localOptions.put("class", "DateTieredCompactionStrategy");
+
+ getCurrentColumnFamilyStore().disableAutoCompaction();
+ assertFalse(getCurrentColumnFamilyStore().getCompactionStrategy().isEnabled());
+
+ getCurrentColumnFamilyStore().setLocalCompactionStrategy(localOptions);
+ assertTrue(getCurrentColumnFamilyStore().getCompactionStrategy().isEnabled());
+
+ }
+
+
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadLocalCompactionStrategyOptions()
+ {
+ createTable("CREATE TABLE %s (id text PRIMARY KEY)");
+ Map<String, String> localOptions = new HashMap<>();
+ localOptions.put("class","SizeTieredCompactionStrategy");
+ localOptions.put("sstable_size_in_mb","1234"); // not for STCS
+ getCurrentColumnFamilyStore().setLocalCompactionStrategy(localOptions);
+ }
+
+ public boolean verifyStrategies(WrappingCompactionStrategy wrappingStrategy, Class<? extends AbstractCompactionStrategy> expected)
+ {
+ boolean found = false;
+ for (AbstractCompactionStrategy actualStrategy : wrappingStrategy.getWrappedStrategies())
+ {
+ if (!actualStrategy.getClass().equals(expected))
+ return false;
+ found = true;
+ }
+ return found;
+ }
+
private ColumnFamilyStore getCurrentColumnFamilyStore()
{
return Keyspace.open(KEYSPACE).getColumnFamilyStore(currentTable());
}
- public boolean minorWasTriggered(String keyspace, String cf) throws Throwable
+ private boolean minorWasTriggered(String keyspace, String cf) throws Throwable
{
UntypedResultSet res = execute("SELECT * FROM system.compaction_history");
boolean minorWasTriggered = false;