modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java | 62 ++++-
modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java | 109 ++++++++++
modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml | 6
3 files changed, 161 insertions(+), 16 deletions(-)
New commits:
commit 389c78721f61b3704404cbdb6a2a03bff22785ef
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jun 1 22:52:20 2013 -0400
more refactoring to get the correct logic in KeyspaceService
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
index ea5f55f..81a9388 100644
--- a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
@@ -144,14 +144,17 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
return failedOperation;
}
- public OperationResult repairKeyspace() {
+ public OperationResult repairKeyspace(String... columnFamilies) {
KeyspaceService keyspaceService = new KeyspaceService(getEmsConnection());
String keyspace = context.getResourceKey();
+ if (columnFamilies == null) {
+ columnFamilies = new String[] {};
+ }
log.info("Executing repair on keyspace [" + keyspace + "]");
long start = System.currentTimeMillis();
- keyspaceService.repair(keyspace);
+ keyspaceService.repair(keyspace, columnFamilies);
long end = System.currentTimeMillis();
log.info("Finished repair on keyspace [" + keyspace + "] in " + (end - start) + " ms");
@@ -172,13 +175,17 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
return new OperationResult();
}
- public OperationResult compactKeyspace() {
+ public OperationResult compactKeyspace(String... columnFamilies) {
KeyspaceService keyspaceService = new KeyspaceService(getEmsConnection());
+
String keyspace = context.getResourceKey();
+ if (columnFamilies == null) {
+ columnFamilies = new String[] {};
+ }
log.info("Executing compaction on keyspace [" + keyspace + "]");
long start = System.currentTimeMillis();
- keyspaceService.compact(keyspace);
+ keyspaceService.compact(keyspace, columnFamilies);
long end = System.currentTimeMillis();
log.info("Finished compaction on keysapce [" + keyspace + "] in " + (end - start) + " ms");
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java
index 9bd0716..5dda8be 100644
--- a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java
@@ -44,26 +44,30 @@ public class KeyspaceService {
public static final String COMPACT_OPERATION = "forceTableCompaction";
+ public static final String SNAPSHOT_OPERATION = "takeSnapshot";
+
+ public static final String CF_SNAPSHOT_OPERATION = "takeColumnFamilySnapshot";
+
private EmsConnection emsConnection;
public KeyspaceService(EmsConnection emsConnection) {
this.emsConnection = emsConnection;
}
- public void repair(String keyspace) {
+ public void repair(String keyspace, String... columnFamilies) {
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(REPAIR_OPERATION, String.class, boolean.class,
boolean.class, String[].class);
- operation.invoke(keyspace, new String[] {});
+ operation.invoke(keyspace, true, true, columnFamilies);
}
- public void repairPrimaryRange(String keyspace) {
+ public void repairPrimaryRange(String keyspace, String... columnFamilies) {
EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(REPAIR_PRIMARY_RANGE, String.class, boolean.class, boolean.class,
String[].class);
- operation.invoke(keyspace);
+ operation.invoke(keyspace, true, true, columnFamilies);
}
public void cleanup(String keyspace) {
@@ -73,11 +77,18 @@ public class KeyspaceService {
operation.invoke(keyspace, new String[] {});
}
- public void compact(String keyspace) {
+ public void compact(String keyspace, String... columnFamilies) {
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
EmsOperation operation = emsBean.getOperation(COMPACT_OPERATION, String.class, String[].class);
- operation.invoke(keyspace, new String[] {});
+ operation.invoke(keyspace, columnFamilies);
+ }
+
+ public void takeSnapshot(String keyspace, String snapshotName) {
+ EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsOperation operation = emsBean.getOperation(SNAPSHOT_OPERATION, String.class, String[].class);
+
+ operation.invoke(snapshotName, new String[] {keyspace});
}
private EmsBean loadBean(String objectName) {
commit 4e086fd5d1f5698c9af43eab0ec00d9797655216
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jun 1 20:44:45 2013 -0400
inital commit for KeyspaceService
Extracting some of the logic in KeyspaceComponent into KeyspaceService because
it is needed in the storage plugin as well for kicking off tasks when nodes are
added to or removed from the cluster.
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
index f0369c8..ea5f55f 100644
--- a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
@@ -55,6 +55,7 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.plugins.cassandra.util.KeyspaceService;
import org.rhq.plugins.jmx.JMXComponent;
/**
@@ -65,12 +66,6 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
private final Log log = LogFactory.getLog(KeyspaceComponent.class);
- private static final String STORAGE_SERVICE_BEAN = "org.apache.cassandra.db:type=StorageService";
-
- private static final String COMPACT_OPERATION = "forceTableCompaction";
- private static final String REPAIR_OPERATION = "forceTableRepair";
- private static final String CLEANUP_OPERATION = "forceTableCleanup";
-
private ResourceContext<ResourceComponent<?>> context;
@Override
@@ -149,19 +144,14 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
return failedOperation;
}
- public OperationResult repairKeyspace(String... columnFamilies) {
- EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
- EmsOperation operation = emsBean.getOperation(REPAIR_OPERATION, String.class, boolean.class, boolean.class,
- String[].class);
+ public OperationResult repairKeyspace() {
+ KeyspaceService keyspaceService = new KeyspaceService(getEmsConnection());
String keyspace = context.getResourceKey();
- if (columnFamilies == null) {
- columnFamilies = new String[]{};
- }
log.info("Executing repair on keyspace [" + keyspace + "]");
long start = System.currentTimeMillis();
- operation.invoke(keyspace, true, true, columnFamilies);
+ keyspaceService.repair(keyspace);
long end = System.currentTimeMillis();
log.info("Finished repair on keyspace [" + keyspace + "] in " + (end - start) + " ms");
@@ -169,16 +159,12 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
}
public OperationResult cleanup() {
- EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
- EmsOperation operation = emsBean.getOperation(CLEANUP_OPERATION, String.class, String[].class);
-
+ KeyspaceService keyspaceService = new KeyspaceService(getEmsConnection());
String keyspace = context.getResourceKey();
- operation.invoke(keyspace, new String[]{});
-
log.info("Executing cleanup on keyspace [" + keyspace + "]");
long start = System.currentTimeMillis();
- operation.invoke(keyspace, new String[]{});
+ keyspaceService.cleanup(keyspace);
long end = System.currentTimeMillis();
log.info("Finished cleanup on keyspace [" + keyspace + "] in " + (end - start) + " ms");
@@ -186,20 +172,14 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
return new OperationResult();
}
- public OperationResult compactKeyspace(String... columnFamilies) {
- EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
- EmsOperation operation = emsBean.getOperation(COMPACT_OPERATION, String.class, String[].class);
-
+ public OperationResult compactKeyspace() {
+ KeyspaceService keyspaceService = new KeyspaceService(getEmsConnection());
String keyspace = context.getResourceKey();
- if (columnFamilies == null) {
- columnFamilies = new String[]{};
- }
log.info("Executing compaction on keyspace [" + keyspace + "]");
long start = System.currentTimeMillis();
- operation.invoke(keyspace, new String[]{});
+ keyspaceService.compact(keyspace);
long end = System.currentTimeMillis();
-
log.info("Finished compaction on keysapce [" + keyspace + "] in " + (end - start) + " ms");
return new OperationResult();
@@ -215,7 +195,7 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
log.info("Taking snapshot of keyspace [" + keyspace + "]");
log.info("Snapshot name set to [" + snapshotName + "]");
long start = System.currentTimeMillis();
- EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
if (columnFamilies == null || columnFamilies.length == 0) {
EmsOperation operation = emsBean.getOperation("takeSnapshot", String.class, String[].class);
operation.invoke(snapshotName, new String[]{keyspace});
@@ -238,7 +218,7 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
}
public PropertyList getKeySpaceDataFileLocations() {
- EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
EmsAttribute attribute = emsBean.getAttribute("AllDataFileLocations");
PropertyList list = new PropertyList("keyspaceFileLocations");
@@ -255,7 +235,7 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
}
public PropertySimple getCommitLogProperty() {
- EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
EmsAttribute attribute = emsBean.getAttribute("CommitLogLocation");
return new PropertySimple("CommitLogLocation", attribute.refresh());
}
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java
new file mode 100644
index 0000000..9bd0716
--- /dev/null
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/util/KeyspaceService.java
@@ -0,0 +1,98 @@
+/*
+ *
+ * * RHQ Management Platform
+ * * Copyright (C) 2005-2012 Red Hat, Inc.
+ * * All rights reserved.
+ * *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License, version 2, as
+ * * published by the Free Software Foundation, and/or the GNU Lesser
+ * * General Public License, version 2.1, also as published by the Free
+ * * Software Foundation.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License and the GNU Lesser General Public License
+ * * for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * and the GNU Lesser General Public License along with this program;
+ * * if not, write to the Free Software Foundation, Inc.,
+ * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+package org.rhq.plugins.cassandra.util;
+
+import org.mc4j.ems.connection.EmsConnection;
+import org.mc4j.ems.connection.bean.EmsBean;
+import org.mc4j.ems.connection.bean.operation.EmsOperation;
+
+/**
+ * @author John Sanda
+ */
+public class KeyspaceService {
+
+ public static final String STORAGE_SERVICE_BEAN = "org.apache.cassandra.db:type=StorageService";
+
+ public static final String REPAIR_OPERATION = "forceTableRepair";
+
+ public static final String REPAIR_PRIMARY_RANGE = "forceTableRepairPrimaryRange";
+
+ public static final String CLEANUP_OPERATION = "forceTableCleanup";
+
+ public static final String COMPACT_OPERATION = "forceTableCompaction";
+
+ private EmsConnection emsConnection;
+
+ public KeyspaceService(EmsConnection emsConnection) {
+ this.emsConnection = emsConnection;
+ }
+
+ public void repair(String keyspace) {
+ EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsOperation operation = emsBean.getOperation(REPAIR_OPERATION, String.class, boolean.class,
+ boolean.class, String[].class);
+
+ operation.invoke(keyspace, new String[] {});
+ }
+
+ public void repairPrimaryRange(String keyspace) {
+ EmsBean emsBean = loadBean(KeyspaceService.STORAGE_SERVICE_BEAN);
+ EmsOperation operation = emsBean.getOperation(REPAIR_PRIMARY_RANGE, String.class, boolean.class, boolean.class,
+ String[].class);
+
+ operation.invoke(keyspace);
+ }
+
+ public void cleanup(String keyspace) {
+ EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsOperation operation = emsBean.getOperation(CLEANUP_OPERATION, String.class, String[].class);
+
+ operation.invoke(keyspace, new String[] {});
+ }
+
+ public void compact(String keyspace) {
+ EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsOperation operation = emsBean.getOperation(COMPACT_OPERATION, String.class, String[].class);
+
+ operation.invoke(keyspace, new String[] {});
+ }
+
+ private EmsBean loadBean(String objectName) {
+ EmsBean bean = emsConnection.getBean(objectName);
+ if (bean == null) {
+ // In some cases, this resource component may have been discovered by some means other than querying its
+ // parent's EMSConnection (e.g. ApplicationDiscoveryComponent uses a filesystem to discover EARs and
+ // WARs that are not yet deployed). In such cases, getBean() will return null, since EMS won't have the
+ // bean in its cache. To cover such cases, make an attempt to query the underlying MBeanServer for the
+ // bean before giving up.
+ emsConnection.queryBeans(objectName);
+ bean = emsConnection.getBean(objectName);
+ }
+
+ return bean;
+ }
+
+}
commit f6d23afafed53f61598aa97c2c2df2760274b3bf
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jun 1 07:44:39 2013 -0400
adding cleanup operation and some logging
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
index 2f2591a..f0369c8 100644
--- a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/KeyspaceComponent.java
@@ -36,6 +36,8 @@ import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.querybuilder.QueryBuilder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.mc4j.ems.connection.EmsConnection;
import org.mc4j.ems.connection.bean.EmsBean;
import org.mc4j.ems.connection.bean.attribute.EmsAttribute;
@@ -61,10 +63,13 @@ import org.rhq.plugins.jmx.JMXComponent;
public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>>, ConfigurationFacet,
JMXComponent<ResourceComponent<?>>, OperationFacet {
+ private final Log log = LogFactory.getLog(KeyspaceComponent.class);
+
private static final String STORAGE_SERVICE_BEAN = "org.apache.cassandra.db:type=StorageService";
private static final String COMPACT_OPERATION = "forceTableCompaction";
private static final String REPAIR_OPERATION = "forceTableRepair";
+ private static final String CLEANUP_OPERATION = "forceTableCleanup";
private ResourceContext<ResourceComponent<?>> context;
@@ -134,6 +139,8 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
return compactKeyspace();
} else if (name.equals("takeSnapshot")) {
return takeSnapshot(parameters);
+ } else if (name.equals("cleanup")) {
+ return cleanup();
}
OperationResult failedOperation = new OperationResult();
@@ -149,9 +156,32 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
String keyspace = context.getResourceKey();
if (columnFamilies == null) {
- columnFamilies = new String[] {};
+ columnFamilies = new String[]{};
}
+
+ log.info("Executing repair on keyspace [" + keyspace + "]");
+ long start = System.currentTimeMillis();
operation.invoke(keyspace, true, true, columnFamilies);
+ long end = System.currentTimeMillis();
+ log.info("Finished repair on keyspace [" + keyspace + "] in " + (end - start) + " ms");
+
+ return new OperationResult();
+ }
+
+ public OperationResult cleanup() {
+ EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
+ EmsOperation operation = emsBean.getOperation(CLEANUP_OPERATION, String.class, String[].class);
+
+ String keyspace = context.getResourceKey();
+ operation.invoke(keyspace, new String[]{});
+
+
+ log.info("Executing cleanup on keyspace [" + keyspace + "]");
+ long start = System.currentTimeMillis();
+ operation.invoke(keyspace, new String[]{});
+ long end = System.currentTimeMillis();
+
+ log.info("Finished cleanup on keyspace [" + keyspace + "] in " + (end - start) + " ms");
return new OperationResult();
}
@@ -162,9 +192,15 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
String keyspace = context.getResourceKey();
if (columnFamilies == null) {
- columnFamilies = new String[] {};
+ columnFamilies = new String[]{};
}
- operation.invoke(keyspace, new String[] {});
+
+ log.info("Executing compaction on keyspace [" + keyspace + "]");
+ long start = System.currentTimeMillis();
+ operation.invoke(keyspace, new String[]{});
+ long end = System.currentTimeMillis();
+
+ log.info("Finished compaction on keysapce [" + keyspace + "] in " + (end - start) + " ms");
return new OperationResult();
}
@@ -176,19 +212,28 @@ public class KeyspaceComponent implements ResourceComponent<ResourceComponent<?>
snapshotName = System.currentTimeMillis() + "";
}
+ log.info("Taking snapshot of keyspace [" + keyspace + "]");
+ log.info("Snapshot name set to [" + snapshotName + "]");
+ long start = System.currentTimeMillis();
EmsBean emsBean = loadBean(STORAGE_SERVICE_BEAN);
if (columnFamilies == null || columnFamilies.length == 0) {
EmsOperation operation = emsBean.getOperation("takeSnapshot", String.class, String[].class);
- operation.invoke(snapshotName, new String[] { keyspace });
+ operation.invoke(snapshotName, new String[]{keyspace});
} else {
EmsOperation operation = emsBean.getOperation("takeColumnFamilySnapshot", String.class, String.class,
String.class);
for (String columnFamily : columnFamilies) {
+ if (log.isDebugEnabled()) {
+ log.debug("Taking snapshot of column family [" + columnFamily + "]");
+ }
operation.invoke(keyspace, columnFamily, snapshotName);
}
}
+ long end = System.currentTimeMillis();
+ log.info("Finished taking snapshot of keyspace [" + keyspace + "] in " + (end - start) + " ms");
+
return new OperationResult();
}
diff --git a/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml
index 752c72a..8dfc156 100644
--- a/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml
@@ -649,7 +649,11 @@
deletes, it is important to run regularly scheduled repairs to ensure that deleted data gets purged.
The frequency that this should be run should be less than the gc_grace_period for each column family.
This runs a repair on all column families in this keyspace." />
- <operation name="compact" displayName="Compact Keyspace"
+ <operation name="cleanup" displayName="Clean Keyspace"
+ description="Goes through each SSTable file on disk fore each column family and removes keys
+ (i.e., rows) that the node does not own. This should be performed as a routine maintenance task on
+ existing nodes when new nodes are added to the cluster."/>
+ <operation name="compact" displayName="Compact Keyspace"
description="Forces major compaction of the keyspace. Though major compaction can free disk space
used during runtime it temporarily doubles disk space usage and is I/O and CPU intensive. Once you
run a major compaction, automatic minor compactions are no longer triggered frequently forcing you to