add non-jamm path for cached statements patch by Michael Stepura; reviewed by jbellis for CASSANDRA-6293
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e7681913 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e7681913 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e7681913 Branch: refs/heads/cassandra-2.0 Commit: e76819135163836ce687cc26d4a085d73e6fbfd0 Parents: b461c3b Author: Jonathan Ellis <[email protected]> Authored: Mon Nov 4 09:47:59 2013 -0600 Committer: Jonathan Ellis <[email protected]> Committed: Mon Nov 4 09:47:59 2013 -0600 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/cql3/QueryProcessor.java | 49 +++++++++++++++----- src/java/org/apache/cassandra/db/Memtable.java | 6 +-- 3 files changed, 41 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/e7681913/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index e2fcbb8..fd93a5f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 1.2.12 + * add non-jamm path for cached statements (CASSANDRA-6293) * (Hadoop) Require CFRR batchSize to be at least 2 (CASSANDRA-6114) * Fix altering column types (CASSANDRA-6185) * cqlsh: fix CREATE/ALTER WITH completion (CASSANDRA-6196) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e7681913/src/java/org/apache/cassandra/cql3/QueryProcessor.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java index 71a57f4..2d43bdc 100644 --- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java @@ -47,34 +47,54 @@ public class QueryProcessor private static final Logger logger = LoggerFactory.getLogger(QueryProcessor.class); private static final MemoryMeter meter = new MemoryMeter(); private static final long MAX_CACHE_PREPARED_MEMORY = Runtime.getRuntime().maxMemory() / 256; + private static final int MAX_CACHE_PREPARED_COUNT = 10000; private static EntryWeigher<MD5Digest, CQLStatement> cqlMemoryUsageWeigher = new EntryWeigher<MD5Digest, CQLStatement>() { @Override public int weightOf(MD5Digest key, CQLStatement value) { - return Ints.checkedCast(meter.measureDeep(key) + meter.measureDeep(value)); + return Ints.checkedCast(measure(key) + measure(value)); } }; - private static final ConcurrentLinkedHashMap<MD5Digest, CQLStatement> preparedStatements = new ConcurrentLinkedHashMap.Builder<MD5Digest, CQLStatement>() - .maximumWeightedCapacity(MAX_CACHE_PREPARED_MEMORY) - .weigher(cqlMemoryUsageWeigher) - .build(); - private static EntryWeigher<Integer, CQLStatement> thriftMemoryUsageWeigher = new EntryWeigher<Integer, CQLStatement>() { @Override public int weightOf(Integer key, CQLStatement value) { - return Ints.checkedCast(meter.measureDeep(key) + meter.measureDeep(value)); + return Ints.checkedCast(measure(key) + measure(value)); } }; - private static final ConcurrentLinkedHashMap<Integer, CQLStatement> thriftPreparedStatements = new ConcurrentLinkedHashMap.Builder<Integer, CQLStatement>() - .maximumWeightedCapacity(MAX_CACHE_PREPARED_MEMORY) - .weigher(thriftMemoryUsageWeigher) - .build(); + private static final ConcurrentLinkedHashMap<MD5Digest, CQLStatement> preparedStatements; + private static final ConcurrentLinkedHashMap<Integer, CQLStatement> thriftPreparedStatements; + + static + { + if (MemoryMeter.isInitialized()) + { + preparedStatements = new ConcurrentLinkedHashMap.Builder<MD5Digest, CQLStatement>() + .maximumWeightedCapacity(MAX_CACHE_PREPARED_MEMORY) + .weigher(cqlMemoryUsageWeigher) + .build(); + thriftPreparedStatements = new ConcurrentLinkedHashMap.Builder<Integer, CQLStatement>() + .maximumWeightedCapacity(MAX_CACHE_PREPARED_MEMORY) + .weigher(thriftMemoryUsageWeigher) + .build(); + } + else + { + logger.error("Unable to initialize MemoryMeter (jamm not specified as javaagent). This means " + + "Cassandra will be unable to measure object sizes accurately and may consequently OOM."); + preparedStatements = new ConcurrentLinkedHashMap.Builder<MD5Digest, CQLStatement>() + .maximumWeightedCapacity(MAX_CACHE_PREPARED_COUNT) + .build(); + thriftPreparedStatements = new ConcurrentLinkedHashMap.Builder<Integer, CQLStatement>() + .maximumWeightedCapacity(MAX_CACHE_PREPARED_COUNT) + .build(); + } + } public static CQLStatement getPrepared(MD5Digest id) @@ -211,7 +231,7 @@ public class QueryProcessor // Concatenate the current keyspace so we don't mix prepared statements between keyspace (#5352). // (if the keyspace is null, queryString has to have a fully-qualified keyspace so it's fine. String toHash = keyspace == null ? queryString : keyspace + queryString; - long statementSize = meter.measureDeep(prepared.statement); + long statementSize = measure(prepared.statement); // don't execute the statement if it's bigger than the allowed threshold if (statementSize > MAX_CACHE_PREPARED_MEMORY) throw new InvalidRequestException(String.format("Prepared statement of size %d bytes is larger than allowed maximum of %d bytes.", @@ -305,4 +325,9 @@ public class QueryProcessor throw new SyntaxException("Invalid or malformed CQL query string: " + e.getMessage()); } } + + private static long measure(Object key) + { + return MemoryMeter.isInitialized() ? meter.measureDeep(key) : 1; + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e7681913/src/java/org/apache/cassandra/db/Memtable.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java index 1364030..11a49ed 100644 --- a/src/java/org/apache/cassandra/db/Memtable.java +++ b/src/java/org/apache/cassandra/db/Memtable.java @@ -173,9 +173,9 @@ public class Memtable if (!MemoryMeter.isInitialized()) { // hack for openjdk. we log a warning about this in the startup script too. - logger.warn("MemoryMeter uninitialized (jamm not specified as java agent); assuming liveRatio of {}. " - + " Usually this means cassandra-env.sh disabled jamm because you are using a buggy JRE; " - + " upgrade to the Sun JRE instead", cfs.liveRatio); + logger.error("MemoryMeter uninitialized (jamm not specified as java agent); assuming liveRatio of {}. " + + " Usually this means cassandra-env.sh disabled jamm because you are using a buggy JRE; " + + " upgrade to the Sun JRE instead", cfs.liveRatio); return; }
