You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2013/09/28 17:22:55 UTC
[1/3] git commit: Track and persist sstable read activity patch by
Tyler Hobbs; reviewed by jbellis for CASSANDRA-5515
Updated Branches:
refs/heads/cassandra-2.0 ee553f32d -> c8915cea4
refs/heads/trunk a1be1a913 -> 6d099b416
Track and persist sstable read activity
patch by Tyler Hobbs; reviewed by jbellis for CASSANDRA-5515
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c8915cea
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c8915cea
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c8915cea
Branch: refs/heads/cassandra-2.0
Commit: c8915cea4ba58174208c083b145fecaf93c7e69a
Parents: ee553f3
Author: Jonathan Ellis <jb...@apache.org>
Authored: Sat Sep 28 10:22:17 2013 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Sat Sep 28 10:22:17 2013 -0500
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../org/apache/cassandra/config/CFMetaData.java | 9 ++++
.../org/apache/cassandra/config/KSMetaData.java | 3 +-
.../cassandra/db/CollationController.java | 2 +
.../org/apache/cassandra/db/DataTracker.java | 1 +
.../org/apache/cassandra/db/SystemKeyspace.java | 55 +++++++++++++++++++-
.../io/sstable/SSTableDeletingTask.java | 4 ++
.../cassandra/io/sstable/SSTableReader.java | 45 +++++++++++++---
8 files changed, 111 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9e962ca..f62dcde 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.0.2
+ * Track and persist sstable read activity (CASSANDRA-5515)
* Fixes for speculative retry (CASSANDRA-5932)
* Improve memory usage of metadata min/max column names (CASSANDRA-6077)
* Fix thrift validation refusing row markers on CQL3 tables (CASSANDRA-6081)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/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 3a5309f..29df8c3 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -259,6 +259,15 @@ public final class CFMetaData
+ "PRIMARY KEY (row_key, cf_id)"
+ ") WITH COMMENT='in-progress paxos proposals'");
+ public static final CFMetaData SSTableActivityCF = compile("CREATE TABLE " + SystemKeyspace.SSTABLE_ACTIVITY_CF + " ("
+ + "keyspace_name text,"
+ + "columnfamily_name text,"
+ + "generation int,"
+ + "rate_15m double,"
+ + "rate_120m double,"
+ + "PRIMARY KEY ((keyspace_name, columnfamily_name, generation))"
+ + ") WITH COMMENT='historic sstable read rates'");
+
public enum Caching
{
ALL, KEYS_ONLY, ROWS_ONLY, NONE;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/config/KSMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/KSMetaData.java b/src/java/org/apache/cassandra/config/KSMetaData.java
index 198df8d..4b74dc6 100644
--- a/src/java/org/apache/cassandra/config/KSMetaData.java
+++ b/src/java/org/apache/cassandra/config/KSMetaData.java
@@ -90,7 +90,8 @@ public final class KSMetaData
CFMetaData.SchemaColumnFamiliesCf,
CFMetaData.SchemaColumnsCf,
CFMetaData.CompactionLogCf,
- CFMetaData.PaxosCf);
+ CFMetaData.PaxosCf,
+ CFMetaData.SSTableActivityCF);
return new KSMetaData(Keyspace.SYSTEM_KS, LocalStrategy.class, Collections.<String, String>emptyMap(), true, cfDefs);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/db/CollationController.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/CollationController.java b/src/java/org/apache/cassandra/db/CollationController.java
index 859135d..758d523 100644
--- a/src/java/org/apache/cassandra/db/CollationController.java
+++ b/src/java/org/apache/cassandra/db/CollationController.java
@@ -246,6 +246,7 @@ public class CollationController
continue;
}
+ sstable.incrementReadCount();
OnDiskAtomIterator iter = filter.getSSTableColumnIterator(sstable);
iterators.add(iter);
if (iter.getColumnFamily() != null)
@@ -268,6 +269,7 @@ public class CollationController
if (sstable.getMaxTimestamp() <= minTimestamp)
continue;
+ sstable.incrementReadCount();
OnDiskAtomIterator iter = filter.getSSTableColumnIterator(sstable);
if (iter.getColumnFamily() == null)
continue;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/db/DataTracker.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/DataTracker.java b/src/java/org/apache/cassandra/db/DataTracker.java
index f30ec1e..c2337ea 100644
--- a/src/java/org/apache/cassandra/db/DataTracker.java
+++ b/src/java/org/apache/cassandra/db/DataTracker.java
@@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.compaction.OperationType;
+import org.apache.cassandra.io.sstable.Descriptor;
import org.apache.cassandra.io.sstable.SSTableReader;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.metrics.StorageMetrics;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/db/SystemKeyspace.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/SystemKeyspace.java b/src/java/org/apache/cassandra/db/SystemKeyspace.java
index 0342dbb..1d5927a 100644
--- a/src/java/org/apache/cassandra/db/SystemKeyspace.java
+++ b/src/java/org/apache/cassandra/db/SystemKeyspace.java
@@ -28,6 +28,8 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
+
+import org.apache.cassandra.metrics.RestorableMeter;
import org.apache.cassandra.transport.Server;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -77,6 +79,7 @@ public class SystemKeyspace
public static final String SCHEMA_TRIGGERS_CF = "schema_triggers";
public static final String COMPACTION_LOG = "compactions_in_progress";
public static final String PAXOS_CF = "paxos";
+ public static final String SSTABLE_ACTIVITY_CF = "sstable_activity";
private static final String LOCAL_KEY = "local";
private static final ByteBuffer ALL_LOCAL_NODE_ID_KEY = ByteBufferUtil.bytes("Local");
@@ -865,4 +868,54 @@ public class SystemKeyspace
ByteBufferUtil.bytesToHex(commit.key),
commit.update.id()));
}
-}
+
+ /**
+ * Returns a RestorableMeter tracking the average read rate of a particular SSTable, restoring the last-seen rate
+ * from values in system.sstable_activity if present.
+ * @param keyspace the keyspace the sstable belongs to
+ * @param table the table the sstable belongs to
+ * @param generation the generation number for the sstable
+ */
+ public static RestorableMeter getSSTableReadMeter(String keyspace, String table, int generation)
+ {
+ String cql = "SELECT * FROM %s WHERE keyspace_name='%s' and columnfamily_name='%s' and generation=%d";
+ UntypedResultSet results = processInternal(String.format(cql,
+ SSTABLE_ACTIVITY_CF,
+ keyspace,
+ table,
+ generation));
+
+ if (results.isEmpty())
+ return new RestorableMeter();
+
+ UntypedResultSet.Row row = results.one();
+ double m15rate = row.getDouble("rate_15m");
+ double m120rate = row.getDouble("rate_120m");
+ return new RestorableMeter(m15rate, m120rate);
+ }
+
+ /**
+ * Writes the current read rates for a given SSTable to system.sstable_activity
+ */
+ public static void persistSSTableReadMeter(String keyspace, String table, int generation, RestorableMeter meter)
+ {
+ // Store values with a one-day TTL to handle corner cases where cleanup might not occur
+ String cql = "INSERT INTO %s (keyspace_name, columnfamily_name, generation, rate_15m, rate_120m) VALUES ('%s', '%s', %d, %f, %f) USING TTL 864000";
+ processInternal(String.format(cql,
+ SSTABLE_ACTIVITY_CF,
+ keyspace,
+ table,
+ generation,
+ meter.fifteenMinuteRate(),
+ meter.twoHourRate()));
+ }
+
+ /**
+ * Clears persisted read rates from system.sstable_activity for SSTables that have been deleted.
+ */
+ public static void clearSSTableReadMeter(String keyspace, String table, int generation)
+ {
+ String cql = "DELETE FROM %s WHERE keyspace_name='%s' AND columnfamily_name='%s' and generation=%d";
+ processInternal(String.format(cql, SSTABLE_ACTIVITY_CF, keyspace, table, generation));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java b/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
index a577999..fb7f036 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.db.DataTracker;
+import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
@@ -70,6 +71,9 @@ public class SSTableDeletingTask implements Runnable
if (tracker != null)
tracker.notifyDeleting(referent);
+ if (referent.readMeter != null)
+ SystemKeyspace.clearSSTableReadMeter(referent.getKeyspaceName(), referent.getColumnFamilyName(), referent.descriptor.generation);
+
// If we can't successfully delete the DATA component, set the task to be retried later: see above
File datafile = new File(desc.filenameFor(Component.DATA));
if (!datafile.delete())
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
index 4da579c..abd7c9f 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -39,11 +40,7 @@ import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.Schema;
-import org.apache.cassandra.db.DataRange;
-import org.apache.cassandra.db.DataTracker;
-import org.apache.cassandra.db.DecoratedKey;
-import org.apache.cassandra.db.RowIndexEntry;
-import org.apache.cassandra.db.RowPosition;
+import org.apache.cassandra.db.*;
import org.apache.cassandra.db.columniterator.OnDiskAtomIterator;
import org.apache.cassandra.db.commitlog.ReplayPosition;
import org.apache.cassandra.db.compaction.ICompactionScanner;
@@ -53,6 +50,7 @@ import org.apache.cassandra.io.compress.CompressedRandomAccessReader;
import org.apache.cassandra.io.compress.CompressedThrottledReader;
import org.apache.cassandra.io.compress.CompressionMetadata;
import org.apache.cassandra.io.util.*;
+import org.apache.cassandra.metrics.RestorableMeter;
import org.apache.cassandra.service.CacheService;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.tracing.Tracing;
@@ -68,6 +66,9 @@ public class SSTableReader extends SSTable implements Closeable
{
private static final Logger logger = LoggerFactory.getLogger(SSTableReader.class);
+ private static final ScheduledThreadPoolExecutor syncExecutor = new ScheduledThreadPoolExecutor(1);
+ private static final RateLimiter meterSyncThrottle = RateLimiter.create(100.0);
+
/**
* maxDataAge is a timestamp in local server time (e.g. System.currentTimeMilli) which represents an uppper bound
* to the newest piece of data stored in the sstable. In other words, this sstable does not contain items created
@@ -105,6 +106,8 @@ public class SSTableReader extends SSTable implements Closeable
private final AtomicLong keyCacheHit = new AtomicLong(0);
private final AtomicLong keyCacheRequest = new AtomicLong(0);
+ public final RestorableMeter readMeter;
+
public static long getApproximateKeyCount(Iterable<SSTableReader> sstables, CFMetaData metadata)
{
long count = 0;
@@ -311,7 +314,7 @@ public class SSTableReader extends SSTable implements Closeable
}
- private SSTableReader(Descriptor desc,
+ private SSTableReader(final Descriptor desc,
Set<Component> components,
CFMetaData metadata,
IPartitioner partitioner,
@@ -322,7 +325,25 @@ public class SSTableReader extends SSTable implements Closeable
this.sstableMetadata = sstableMetadata;
this.maxDataAge = maxDataAge;
- this.deletingTask = new SSTableDeletingTask(this);
+ deletingTask = new SSTableDeletingTask(this);
+
+ // Don't track read rates for tables in the system keyspace
+ if (Keyspace.SYSTEM_KS.equals(desc.ksname))
+ {
+ readMeter = null;
+ return;
+ }
+
+ readMeter = SystemKeyspace.getSSTableReadMeter(desc.ksname, desc.cfname, desc.generation);
+ // sync the average read rate to system.sstable_activity every five minutes, starting one minute from now
+ syncExecutor.scheduleAtFixedRate(new Runnable()
+ {
+ public void run()
+ {
+ meterSyncThrottle.acquire();
+ SystemKeyspace.persistSSTableReadMeter(desc.ksname, desc.cfname, desc.generation, readMeter);
+ }
+ }, 1, 5, TimeUnit.MINUTES);
}
private SSTableReader(Descriptor desc,
@@ -1432,6 +1453,16 @@ public class SSTableReader extends SSTable implements Closeable
}
}
+ /**
+ * Increment the total row read count and read rate for this SSTable. This should not be incremented for range
+ * slice queries, row cache hits, or non-query reads, like compaction.
+ */
+ public void incrementReadCount()
+ {
+ if (readMeter != null)
+ readMeter.mark();
+ }
+
protected class EmptyCompactionScanner implements ICompactionScanner
{
private final String filename;
[2/3] git commit: Track and persist sstable read activity patch by
Tyler Hobbs; reviewed by jbellis for CASSANDRA-5515
Posted by jb...@apache.org.
Track and persist sstable read activity
patch by Tyler Hobbs; reviewed by jbellis for CASSANDRA-5515
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c8915cea
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c8915cea
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c8915cea
Branch: refs/heads/trunk
Commit: c8915cea4ba58174208c083b145fecaf93c7e69a
Parents: ee553f3
Author: Jonathan Ellis <jb...@apache.org>
Authored: Sat Sep 28 10:22:17 2013 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Sat Sep 28 10:22:17 2013 -0500
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../org/apache/cassandra/config/CFMetaData.java | 9 ++++
.../org/apache/cassandra/config/KSMetaData.java | 3 +-
.../cassandra/db/CollationController.java | 2 +
.../org/apache/cassandra/db/DataTracker.java | 1 +
.../org/apache/cassandra/db/SystemKeyspace.java | 55 +++++++++++++++++++-
.../io/sstable/SSTableDeletingTask.java | 4 ++
.../cassandra/io/sstable/SSTableReader.java | 45 +++++++++++++---
8 files changed, 111 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9e962ca..f62dcde 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.0.2
+ * Track and persist sstable read activity (CASSANDRA-5515)
* Fixes for speculative retry (CASSANDRA-5932)
* Improve memory usage of metadata min/max column names (CASSANDRA-6077)
* Fix thrift validation refusing row markers on CQL3 tables (CASSANDRA-6081)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/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 3a5309f..29df8c3 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -259,6 +259,15 @@ public final class CFMetaData
+ "PRIMARY KEY (row_key, cf_id)"
+ ") WITH COMMENT='in-progress paxos proposals'");
+ public static final CFMetaData SSTableActivityCF = compile("CREATE TABLE " + SystemKeyspace.SSTABLE_ACTIVITY_CF + " ("
+ + "keyspace_name text,"
+ + "columnfamily_name text,"
+ + "generation int,"
+ + "rate_15m double,"
+ + "rate_120m double,"
+ + "PRIMARY KEY ((keyspace_name, columnfamily_name, generation))"
+ + ") WITH COMMENT='historic sstable read rates'");
+
public enum Caching
{
ALL, KEYS_ONLY, ROWS_ONLY, NONE;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/config/KSMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/KSMetaData.java b/src/java/org/apache/cassandra/config/KSMetaData.java
index 198df8d..4b74dc6 100644
--- a/src/java/org/apache/cassandra/config/KSMetaData.java
+++ b/src/java/org/apache/cassandra/config/KSMetaData.java
@@ -90,7 +90,8 @@ public final class KSMetaData
CFMetaData.SchemaColumnFamiliesCf,
CFMetaData.SchemaColumnsCf,
CFMetaData.CompactionLogCf,
- CFMetaData.PaxosCf);
+ CFMetaData.PaxosCf,
+ CFMetaData.SSTableActivityCF);
return new KSMetaData(Keyspace.SYSTEM_KS, LocalStrategy.class, Collections.<String, String>emptyMap(), true, cfDefs);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/db/CollationController.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/CollationController.java b/src/java/org/apache/cassandra/db/CollationController.java
index 859135d..758d523 100644
--- a/src/java/org/apache/cassandra/db/CollationController.java
+++ b/src/java/org/apache/cassandra/db/CollationController.java
@@ -246,6 +246,7 @@ public class CollationController
continue;
}
+ sstable.incrementReadCount();
OnDiskAtomIterator iter = filter.getSSTableColumnIterator(sstable);
iterators.add(iter);
if (iter.getColumnFamily() != null)
@@ -268,6 +269,7 @@ public class CollationController
if (sstable.getMaxTimestamp() <= minTimestamp)
continue;
+ sstable.incrementReadCount();
OnDiskAtomIterator iter = filter.getSSTableColumnIterator(sstable);
if (iter.getColumnFamily() == null)
continue;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/db/DataTracker.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/DataTracker.java b/src/java/org/apache/cassandra/db/DataTracker.java
index f30ec1e..c2337ea 100644
--- a/src/java/org/apache/cassandra/db/DataTracker.java
+++ b/src/java/org/apache/cassandra/db/DataTracker.java
@@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.compaction.OperationType;
+import org.apache.cassandra.io.sstable.Descriptor;
import org.apache.cassandra.io.sstable.SSTableReader;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.metrics.StorageMetrics;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/db/SystemKeyspace.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/SystemKeyspace.java b/src/java/org/apache/cassandra/db/SystemKeyspace.java
index 0342dbb..1d5927a 100644
--- a/src/java/org/apache/cassandra/db/SystemKeyspace.java
+++ b/src/java/org/apache/cassandra/db/SystemKeyspace.java
@@ -28,6 +28,8 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
+
+import org.apache.cassandra.metrics.RestorableMeter;
import org.apache.cassandra.transport.Server;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -77,6 +79,7 @@ public class SystemKeyspace
public static final String SCHEMA_TRIGGERS_CF = "schema_triggers";
public static final String COMPACTION_LOG = "compactions_in_progress";
public static final String PAXOS_CF = "paxos";
+ public static final String SSTABLE_ACTIVITY_CF = "sstable_activity";
private static final String LOCAL_KEY = "local";
private static final ByteBuffer ALL_LOCAL_NODE_ID_KEY = ByteBufferUtil.bytes("Local");
@@ -865,4 +868,54 @@ public class SystemKeyspace
ByteBufferUtil.bytesToHex(commit.key),
commit.update.id()));
}
-}
+
+ /**
+ * Returns a RestorableMeter tracking the average read rate of a particular SSTable, restoring the last-seen rate
+ * from values in system.sstable_activity if present.
+ * @param keyspace the keyspace the sstable belongs to
+ * @param table the table the sstable belongs to
+ * @param generation the generation number for the sstable
+ */
+ public static RestorableMeter getSSTableReadMeter(String keyspace, String table, int generation)
+ {
+ String cql = "SELECT * FROM %s WHERE keyspace_name='%s' and columnfamily_name='%s' and generation=%d";
+ UntypedResultSet results = processInternal(String.format(cql,
+ SSTABLE_ACTIVITY_CF,
+ keyspace,
+ table,
+ generation));
+
+ if (results.isEmpty())
+ return new RestorableMeter();
+
+ UntypedResultSet.Row row = results.one();
+ double m15rate = row.getDouble("rate_15m");
+ double m120rate = row.getDouble("rate_120m");
+ return new RestorableMeter(m15rate, m120rate);
+ }
+
+ /**
+ * Writes the current read rates for a given SSTable to system.sstable_activity
+ */
+ public static void persistSSTableReadMeter(String keyspace, String table, int generation, RestorableMeter meter)
+ {
+ // Store values with a one-day TTL to handle corner cases where cleanup might not occur
+ String cql = "INSERT INTO %s (keyspace_name, columnfamily_name, generation, rate_15m, rate_120m) VALUES ('%s', '%s', %d, %f, %f) USING TTL 864000";
+ processInternal(String.format(cql,
+ SSTABLE_ACTIVITY_CF,
+ keyspace,
+ table,
+ generation,
+ meter.fifteenMinuteRate(),
+ meter.twoHourRate()));
+ }
+
+ /**
+ * Clears persisted read rates from system.sstable_activity for SSTables that have been deleted.
+ */
+ public static void clearSSTableReadMeter(String keyspace, String table, int generation)
+ {
+ String cql = "DELETE FROM %s WHERE keyspace_name='%s' AND columnfamily_name='%s' and generation=%d";
+ processInternal(String.format(cql, SSTABLE_ACTIVITY_CF, keyspace, table, generation));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java b/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
index a577999..fb7f036 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableDeletingTask.java
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.db.DataTracker;
+import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
@@ -70,6 +71,9 @@ public class SSTableDeletingTask implements Runnable
if (tracker != null)
tracker.notifyDeleting(referent);
+ if (referent.readMeter != null)
+ SystemKeyspace.clearSSTableReadMeter(referent.getKeyspaceName(), referent.getColumnFamilyName(), referent.descriptor.generation);
+
// If we can't successfully delete the DATA component, set the task to be retried later: see above
File datafile = new File(desc.filenameFor(Component.DATA));
if (!datafile.delete())
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c8915cea/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
index 4da579c..abd7c9f 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -39,11 +40,7 @@ import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.Schema;
-import org.apache.cassandra.db.DataRange;
-import org.apache.cassandra.db.DataTracker;
-import org.apache.cassandra.db.DecoratedKey;
-import org.apache.cassandra.db.RowIndexEntry;
-import org.apache.cassandra.db.RowPosition;
+import org.apache.cassandra.db.*;
import org.apache.cassandra.db.columniterator.OnDiskAtomIterator;
import org.apache.cassandra.db.commitlog.ReplayPosition;
import org.apache.cassandra.db.compaction.ICompactionScanner;
@@ -53,6 +50,7 @@ import org.apache.cassandra.io.compress.CompressedRandomAccessReader;
import org.apache.cassandra.io.compress.CompressedThrottledReader;
import org.apache.cassandra.io.compress.CompressionMetadata;
import org.apache.cassandra.io.util.*;
+import org.apache.cassandra.metrics.RestorableMeter;
import org.apache.cassandra.service.CacheService;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.tracing.Tracing;
@@ -68,6 +66,9 @@ public class SSTableReader extends SSTable implements Closeable
{
private static final Logger logger = LoggerFactory.getLogger(SSTableReader.class);
+ private static final ScheduledThreadPoolExecutor syncExecutor = new ScheduledThreadPoolExecutor(1);
+ private static final RateLimiter meterSyncThrottle = RateLimiter.create(100.0);
+
/**
* maxDataAge is a timestamp in local server time (e.g. System.currentTimeMilli) which represents an uppper bound
* to the newest piece of data stored in the sstable. In other words, this sstable does not contain items created
@@ -105,6 +106,8 @@ public class SSTableReader extends SSTable implements Closeable
private final AtomicLong keyCacheHit = new AtomicLong(0);
private final AtomicLong keyCacheRequest = new AtomicLong(0);
+ public final RestorableMeter readMeter;
+
public static long getApproximateKeyCount(Iterable<SSTableReader> sstables, CFMetaData metadata)
{
long count = 0;
@@ -311,7 +314,7 @@ public class SSTableReader extends SSTable implements Closeable
}
- private SSTableReader(Descriptor desc,
+ private SSTableReader(final Descriptor desc,
Set<Component> components,
CFMetaData metadata,
IPartitioner partitioner,
@@ -322,7 +325,25 @@ public class SSTableReader extends SSTable implements Closeable
this.sstableMetadata = sstableMetadata;
this.maxDataAge = maxDataAge;
- this.deletingTask = new SSTableDeletingTask(this);
+ deletingTask = new SSTableDeletingTask(this);
+
+ // Don't track read rates for tables in the system keyspace
+ if (Keyspace.SYSTEM_KS.equals(desc.ksname))
+ {
+ readMeter = null;
+ return;
+ }
+
+ readMeter = SystemKeyspace.getSSTableReadMeter(desc.ksname, desc.cfname, desc.generation);
+ // sync the average read rate to system.sstable_activity every five minutes, starting one minute from now
+ syncExecutor.scheduleAtFixedRate(new Runnable()
+ {
+ public void run()
+ {
+ meterSyncThrottle.acquire();
+ SystemKeyspace.persistSSTableReadMeter(desc.ksname, desc.cfname, desc.generation, readMeter);
+ }
+ }, 1, 5, TimeUnit.MINUTES);
}
private SSTableReader(Descriptor desc,
@@ -1432,6 +1453,16 @@ public class SSTableReader extends SSTable implements Closeable
}
}
+ /**
+ * Increment the total row read count and read rate for this SSTable. This should not be incremented for range
+ * slice queries, row cache hits, or non-query reads, like compaction.
+ */
+ public void incrementReadCount()
+ {
+ if (readMeter != null)
+ readMeter.mark();
+ }
+
protected class EmptyCompactionScanner implements ICompactionScanner
{
private final String filename;
[3/3] git commit: Merge branch 'cassandra-2.0' into trunk
Posted by jb...@apache.org.
Merge branch 'cassandra-2.0' into trunk
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/6d099b41
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/6d099b41
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/6d099b41
Branch: refs/heads/trunk
Commit: 6d099b416e2070fb750af691067cafadfe89f781
Parents: a1be1a9 c8915ce
Author: Jonathan Ellis <jb...@apache.org>
Authored: Sat Sep 28 10:22:31 2013 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Sat Sep 28 10:22:31 2013 -0500
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../org/apache/cassandra/config/CFMetaData.java | 9 ++++
.../org/apache/cassandra/config/KSMetaData.java | 3 +-
.../cassandra/db/CollationController.java | 2 +
.../org/apache/cassandra/db/DataTracker.java | 1 +
.../org/apache/cassandra/db/SystemKeyspace.java | 53 ++++++++++++++++++++
.../io/sstable/SSTableDeletingTask.java | 4 ++
.../cassandra/io/sstable/SSTableReader.java | 45 ++++++++++++++---
8 files changed, 110 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6d099b41/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 3d163d7,f62dcde..cfa10f5
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,12 -1,5 +1,13 @@@
+2.1
+ * change logging from log4j to logback (CASSANDRA-5883)
+ * switch to LZ4 compression for internode communication (CASSANDRA-5887)
+ * Stop using Thrift-generated Index* classes internally (CASSANDRA-5971)
+ * Remove 1.2 network compatibility code (CASSANDRA-5960)
+ * Remove leveled json manifest migration code (CASSANDRA-5996)
+
+
2.0.2
+ * Track and persist sstable read activity (CASSANDRA-5515)
* Fixes for speculative retry (CASSANDRA-5932)
* Improve memory usage of metadata min/max column names (CASSANDRA-6077)
* Fix thrift validation refusing row markers on CQL3 tables (CASSANDRA-6081)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6d099b41/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6d099b41/src/java/org/apache/cassandra/db/SystemKeyspace.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/SystemKeyspace.java
index 3e608b3,1d5927a..f1754fb
--- a/src/java/org/apache/cassandra/db/SystemKeyspace.java
+++ b/src/java/org/apache/cassandra/db/SystemKeyspace.java
@@@ -838,4 -868,54 +841,54 @@@ public class SystemKeyspac
ByteBufferUtil.bytesToHex(commit.key),
commit.update.id()));
}
+
+ /**
+ * Returns a RestorableMeter tracking the average read rate of a particular SSTable, restoring the last-seen rate
+ * from values in system.sstable_activity if present.
+ * @param keyspace the keyspace the sstable belongs to
+ * @param table the table the sstable belongs to
+ * @param generation the generation number for the sstable
+ */
+ public static RestorableMeter getSSTableReadMeter(String keyspace, String table, int generation)
+ {
+ String cql = "SELECT * FROM %s WHERE keyspace_name='%s' and columnfamily_name='%s' and generation=%d";
+ UntypedResultSet results = processInternal(String.format(cql,
+ SSTABLE_ACTIVITY_CF,
+ keyspace,
+ table,
+ generation));
+
+ if (results.isEmpty())
+ return new RestorableMeter();
+
+ UntypedResultSet.Row row = results.one();
+ double m15rate = row.getDouble("rate_15m");
+ double m120rate = row.getDouble("rate_120m");
+ return new RestorableMeter(m15rate, m120rate);
+ }
+
+ /**
+ * Writes the current read rates for a given SSTable to system.sstable_activity
+ */
+ public static void persistSSTableReadMeter(String keyspace, String table, int generation, RestorableMeter meter)
+ {
+ // Store values with a one-day TTL to handle corner cases where cleanup might not occur
+ String cql = "INSERT INTO %s (keyspace_name, columnfamily_name, generation, rate_15m, rate_120m) VALUES ('%s', '%s', %d, %f, %f) USING TTL 864000";
+ processInternal(String.format(cql,
+ SSTABLE_ACTIVITY_CF,
+ keyspace,
+ table,
+ generation,
+ meter.fifteenMinuteRate(),
+ meter.twoHourRate()));
+ }
+
+ /**
+ * Clears persisted read rates from system.sstable_activity for SSTables that have been deleted.
+ */
+ public static void clearSSTableReadMeter(String keyspace, String table, int generation)
+ {
+ String cql = "DELETE FROM %s WHERE keyspace_name='%s' AND columnfamily_name='%s' and generation=%d";
+ processInternal(String.format(cql, SSTABLE_ACTIVITY_CF, keyspace, table, generation));
+ }
-}
+}