a way to deactivate global key/row cache on per-CF basis

patch by Pavel Yaskevich; reviewed by Sylvain Lebresne for CASSANDRA-3667
This commit is contained in:
Pavel Yaskevich 2012-01-02 22:30:16 +02:00
parent 329dd758e8
commit b9813ed388
11 changed files with 164 additions and 15 deletions

View File

@ -36,6 +36,7 @@
* optimize memtable iteration during range scan (CASSANDRA-3638)
* introduce 'crc_check_chance' in CompressionParameters to support
a checksum percentage checking chance similarly to read-repair (CASSANDRA-3611)
* a way to deactivate global key/row cache on per-CF basis (CASSANDRA-3667)
1.0.7

View File

@ -46,7 +46,7 @@ namespace rb CassandraThrift
# for every edit that doesn't result in a change to major/minor.
#
# See the Semantic Versioning Specification (SemVer) http://semver.org.
const string VERSION = "19.24.0"
const string VERSION = "19.25.0"
#
@ -414,6 +414,7 @@ struct CfDef {
30: optional map<string,string> compaction_strategy_options,
32: optional map<string,string> compression_options,
33: optional double bloom_filter_fp_chance,
34: optional string caching="keys_only",
}
/* describes a keyspace. */

View File

@ -9359,6 +9359,8 @@ public class Cassandra {
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
try {
// it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
__isset_bit_vector = new BitSet(1);
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
@ -17314,6 +17316,8 @@ public class Cassandra {
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
try {
// it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
__isset_bit_vector = new BitSet(1);
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);
@ -26117,8 +26121,6 @@ public class Cassandra {
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
try {
// it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
__isset_bit_vector = new BitSet(1);
read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
} catch (org.apache.thrift.TException te) {
throw new java.io.IOException(te);

View File

@ -66,6 +66,7 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
private static final org.apache.thrift.protocol.TField COMPACTION_STRATEGY_OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("compaction_strategy_options", org.apache.thrift.protocol.TType.MAP, (short)30);
private static final org.apache.thrift.protocol.TField COMPRESSION_OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("compression_options", org.apache.thrift.protocol.TType.MAP, (short)32);
private static final org.apache.thrift.protocol.TField BLOOM_FILTER_FP_CHANCE_FIELD_DESC = new org.apache.thrift.protocol.TField("bloom_filter_fp_chance", org.apache.thrift.protocol.TType.DOUBLE, (short)33);
private static final org.apache.thrift.protocol.TField CACHING_FIELD_DESC = new org.apache.thrift.protocol.TField("caching", org.apache.thrift.protocol.TType.STRING, (short)34);
public String keyspace;
public String name;
@ -88,6 +89,7 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
public Map<String,String> compaction_strategy_options;
public Map<String,String> compression_options;
public double bloom_filter_fp_chance;
public String caching;
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
@ -111,7 +113,8 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
COMPACTION_STRATEGY((short)29, "compaction_strategy"),
COMPACTION_STRATEGY_OPTIONS((short)30, "compaction_strategy_options"),
COMPRESSION_OPTIONS((short)32, "compression_options"),
BLOOM_FILTER_FP_CHANCE((short)33, "bloom_filter_fp_chance");
BLOOM_FILTER_FP_CHANCE((short)33, "bloom_filter_fp_chance"),
CACHING((short)34, "caching");
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
@ -168,6 +171,8 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
return COMPRESSION_OPTIONS;
case 33: // BLOOM_FILTER_FP_CHANCE
return BLOOM_FILTER_FP_CHANCE;
case 34: // CACHING
return CACHING;
default:
return null;
}
@ -268,6 +273,8 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
tmpMap.put(_Fields.BLOOM_FILTER_FP_CHANCE, new org.apache.thrift.meta_data.FieldMetaData("bloom_filter_fp_chance", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
tmpMap.put(_Fields.CACHING, new org.apache.thrift.meta_data.FieldMetaData("caching", org.apache.thrift.TFieldRequirementType.OPTIONAL,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
metaDataMap = Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(CfDef.class, metaDataMap);
}
@ -279,6 +286,8 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
this.read_repair_chance = 1;
this.caching = "keys_only";
}
public CfDef(
@ -372,6 +381,9 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
this.compression_options = __this__compression_options;
}
this.bloom_filter_fp_chance = other.bloom_filter_fp_chance;
if (other.isSetCaching()) {
this.caching = other.caching;
}
}
public CfDef deepCopy() {
@ -411,6 +423,8 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
this.compression_options = null;
setBloom_filter_fp_chanceIsSet(false);
this.bloom_filter_fp_chance = 0.0;
this.caching = "keys_only";
}
public String getKeyspace() {
@ -956,6 +970,30 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
__isset_bit_vector.set(__BLOOM_FILTER_FP_CHANCE_ISSET_ID, value);
}
public String getCaching() {
return this.caching;
}
public CfDef setCaching(String caching) {
this.caching = caching;
return this;
}
public void unsetCaching() {
this.caching = null;
}
/** Returns true if field caching is set (has been assigned a value) and false otherwise */
public boolean isSetCaching() {
return this.caching != null;
}
public void setCachingIsSet(boolean value) {
if (!value) {
this.caching = null;
}
}
public void setFieldValue(_Fields field, Object value) {
switch (field) {
case KEYSPACE:
@ -1126,6 +1164,14 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
}
break;
case CACHING:
if (value == null) {
unsetCaching();
} else {
setCaching((String)value);
}
break;
}
}
@ -1194,6 +1240,9 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
case BLOOM_FILTER_FP_CHANCE:
return new Double(getBloom_filter_fp_chance());
case CACHING:
return getCaching();
}
throw new IllegalStateException();
}
@ -1247,6 +1296,8 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
return isSetCompression_options();
case BLOOM_FILTER_FP_CHANCE:
return isSetBloom_filter_fp_chance();
case CACHING:
return isSetCaching();
}
throw new IllegalStateException();
}
@ -1453,6 +1504,15 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
return false;
}
boolean this_present_caching = true && this.isSetCaching();
boolean that_present_caching = true && that.isSetCaching();
if (this_present_caching || that_present_caching) {
if (!(this_present_caching && that_present_caching))
return false;
if (!this.caching.equals(that.caching))
return false;
}
return true;
}
@ -1565,6 +1625,11 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
if (present_bloom_filter_fp_chance)
builder.append(bloom_filter_fp_chance);
boolean present_caching = true && (isSetCaching());
builder.append(present_caching);
if (present_caching)
builder.append(caching);
return builder.toHashCode();
}
@ -1786,6 +1851,16 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
return lastComparison;
}
}
lastComparison = Boolean.valueOf(isSetCaching()).compareTo(typedOther.isSetCaching());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetCaching()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.caching, typedOther.caching);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@ -1993,6 +2068,13 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
}
break;
case 34: // CACHING
if (field.type == org.apache.thrift.protocol.TType.STRING) {
this.caching = iprot.readString();
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
}
@ -2158,6 +2240,13 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
oprot.writeDouble(this.bloom_filter_fp_chance);
oprot.writeFieldEnd();
}
if (this.caching != null) {
if (isSetCaching()) {
oprot.writeFieldBegin(CACHING_FIELD_DESC);
oprot.writeString(this.caching);
oprot.writeFieldEnd();
}
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
@ -2340,6 +2429,16 @@ public class CfDef implements org.apache.thrift.TBase<CfDef, CfDef._Fields>, jav
sb.append(this.bloom_filter_fp_chance);
first = false;
}
if (isSetCaching()) {
if (!first) sb.append(", ");
sb.append("caching:");
if (this.caching == null) {
sb.append("null");
} else {
sb.append(this.caching);
}
first = false;
}
sb.append(")");
return sb.toString();
}

View File

@ -44,6 +44,6 @@ import org.slf4j.LoggerFactory;
public class Constants {
public static final String VERSION = "19.24.0";
public static final String VERSION = "19.25.0";
}

View File

@ -66,6 +66,7 @@ protocol InterNode {
union { null, map<string> } compaction_strategy_options = null;
union { null, map<string> } compression_options = null;
union { null, double } bloom_filter_fp_chance = null;
string caching = "keys_only";
}
@aliases(["org.apache.cassandra.config.avro.KsDef"])

View File

@ -138,7 +138,8 @@ public class CliClient
COMPACTION_STRATEGY,
COMPACTION_STRATEGY_OPTIONS,
COMPRESSION_OPTIONS,
BLOOM_FILTER_FP_CHANCE
BLOOM_FILTER_FP_CHANCE,
CACHING
}
private static final String DEFAULT_PLACEMENT_STRATEGY = "org.apache.cassandra.locator.NetworkTopologyStrategy";
@ -1247,6 +1248,9 @@ public class CliClient
case BLOOM_FILTER_FP_CHANCE:
cfDef.setBloom_filter_fp_chance(Double.parseDouble(mValue));
break;
case CACHING:
cfDef.setCaching(mValue);
break;
default:
//must match one of the above or we'd throw an exception at the valueOf statement above.
assert(false);
@ -1634,6 +1638,7 @@ public class CliClient
writeAttr(sb, false, "max_compaction_threshold", cfDef.max_compaction_threshold);
writeAttr(sb, false, "replicate_on_write", cfDef.replicate_on_write);
writeAttr(sb, false, "compaction_strategy", cfDef.compaction_strategy);
writeAttr(sb, false, "caching", cfDef.caching);
if (!cfDef.compaction_strategy_options.isEmpty())
{
@ -1965,6 +1970,7 @@ public class CliClient
sessionState.out.printf(" Compaction min/max thresholds: %s/%s%n", cf_def.min_compaction_threshold, cf_def.max_compaction_threshold);
sessionState.out.printf(" Read repair chance: %s%n", cf_def.read_repair_chance);
sessionState.out.printf(" Replicate on write: %s%n", cf_def.replicate_on_write);
sessionState.out.printf(" Caching: %s%n", cf_def.caching);
// if we have connection to the cfMBean established
if (cfMBean != null)

View File

@ -23,6 +23,7 @@ import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
@ -86,6 +87,23 @@ public final class CFMetaData
}
}
public enum Caching
{
ALL, KEYS_ONLY, ROWS_ONLY, NONE;
public static Caching fromString(String cache) throws ConfigurationException
{
try
{
return valueOf(cache.toUpperCase());
}
catch (IllegalArgumentException e)
{
throw new ConfigurationException(String.format("%s not found, available types: %s.", cache, StringUtils.join(values(), ", ")));
}
}
}
//REQUIRED
public final Integer cfId; // internal id, never exposed to user
public final String ksName; // name of keyspace
@ -107,7 +125,8 @@ public final class CFMetaData
// thrift compatibility
private double mergeShardsChance; // default 0.1, chance [0.0, 1.0] of merging old shards during replication
private ByteBuffer keyAlias; // default NULL
private Double bloomFilterFpChance; // default NULL
private Double bloomFilterFpChance; // default NULL
private Caching caching; // default KEYS_ONLY (possible: all, key_only, row_only, none)
private Map<ByteBuffer, ColumnDefinition> column_metadata;
public Class<? extends AbstractCompactionStrategy> compactionStrategyClass;
@ -129,8 +148,8 @@ public final class CFMetaData
public CFMetaData compactionStrategyClass(Class<? extends AbstractCompactionStrategy> prop) {compactionStrategyClass = prop; return this;}
public CFMetaData compactionStrategyOptions(Map<String, String> prop) {compactionStrategyOptions = prop; return this;}
public CFMetaData compressionParameters(CompressionParameters prop) {compressionParameters = prop; return this;}
public CFMetaData bloomFilterFpChance(Double prop) {
bloomFilterFpChance = prop; return this;}
public CFMetaData bloomFilterFpChance(Double prop) {bloomFilterFpChance = prop; return this;}
public CFMetaData caching(Caching prop) {caching = prop; return this;}
public CFMetaData(String keyspace, String name, ColumnFamilyType type, AbstractType comp, AbstractType subcc)
{
@ -149,6 +168,7 @@ public final class CFMetaData
// System cfs have specific ids, and copies of old CFMDs need
// to copy over the old id.
cfId = id;
caching = Caching.KEYS_ONLY;
this.init();
}
@ -239,7 +259,8 @@ public final class CFMetaData
.compactionStrategyClass(oldCFMD.compactionStrategyClass)
.compactionStrategyOptions(oldCFMD.compactionStrategyOptions)
.compressionParameters(oldCFMD.compressionParameters)
.bloomFilterFpChance(oldCFMD.bloomFilterFpChance);
.bloomFilterFpChance(oldCFMD.bloomFilterFpChance)
.caching(oldCFMD.caching);
}
/**
@ -293,6 +314,7 @@ public final class CFMetaData
}
cf.compression_options = compressionParameters.asAvroOptions();
cf.bloom_filter_fp_chance = bloomFilterFpChance;
cf.caching = new Utf8(caching.toString());
return cf;
}
@ -447,6 +469,11 @@ public final class CFMetaData
return bloomFilterFpChance;
}
public Caching getCaching()
{
return caching;
}
public boolean equals(Object obj)
{
if (obj == this)
@ -481,6 +508,7 @@ public final class CFMetaData
.append(compactionStrategyOptions, rhs.compactionStrategyOptions)
.append(compressionParameters, rhs.compressionParameters)
.append(bloomFilterFpChance, rhs.bloomFilterFpChance)
.append(caching, rhs.caching)
.isEquals();
}
@ -508,6 +536,7 @@ public final class CFMetaData
.append(compactionStrategyOptions)
.append(compressionParameters)
.append(bloomFilterFpChance)
.append(caching)
.toHashCode();
}
@ -571,6 +600,8 @@ public final class CFMetaData
newCFMD.compactionStrategyOptions(new HashMap<String, String>(cf_def.compaction_strategy_options));
if (cf_def.isSetBloom_filter_fp_chance())
newCFMD.bloomFilterFpChance(cf_def.bloom_filter_fp_chance);
if (cf_def.isSetCaching())
newCFMD.caching(Caching.fromString(cf_def.caching));
CompressionParameters cp = CompressionParameters.create(cf_def.compression_options);
@ -626,6 +657,7 @@ public final class CFMetaData
keyAlias = cf_def.key_alias;
if (cf_def.bloom_filter_fp_chance != null)
bloomFilterFpChance = cf_def.bloom_filter_fp_chance;
caching = Caching.fromString(cf_def.caching.toString());
// adjust column definitions. figure out who is coming and going.
Set<ByteBuffer> toRemove = new HashSet<ByteBuffer>();
@ -767,6 +799,7 @@ public final class CFMetaData
def.setCompression_options(compressionParameters.asThriftOptions());
if (bloomFilterFpChance != null)
def.setBloom_filter_fp_chance(bloomFilterFpChance);
def.setCaching(caching.toString());
return def;
}
@ -904,6 +937,7 @@ public final class CFMetaData
.append("compactionStrategyOptions", compactionStrategyOptions)
.append("compressionOptions", compressionParameters.asThriftOptions())
.append("bloomFilterFpChance", bloomFilterFpChance)
.append("caching", caching)
.toString();
}
}

View File

@ -25,8 +25,6 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
import javax.management.*;
@ -1113,6 +1111,11 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
public ColumnFamily cacheRow(Integer cfId, DecoratedKey decoratedKey)
{
CFMetaData.Caching caching = metadata.getCaching();
if (caching == CFMetaData.Caching.NONE || caching == CFMetaData.Caching.KEYS_ONLY)
return null;
RowCacheKey key = new RowCacheKey(cfId, decoratedKey);
ColumnFamily cached;

View File

@ -608,7 +608,9 @@ public class SSTableReader extends SSTable
public void cacheKey(DecoratedKey key, Long info)
{
if (keyCache == null)
CFMetaData.Caching caching = metadata.getCaching();
if (keyCache == null || caching == CFMetaData.Caching.NONE || caching == CFMetaData.Caching.ROWS_ONLY)
return;
// avoid keeping a permanent reference to the original key buffer

View File

@ -239,8 +239,8 @@ public class SchemaLoader
schema.add(KSMetaData.testMetadata(ks_rcs,
simple,
opts_rf1,
standardCFMD(ks_rcs, "CFWithoutCache"),
standardCFMD(ks_rcs, "CachedCF")));
standardCFMD(ks_rcs, "CFWithoutCache").caching(CFMetaData.Caching.NONE),
standardCFMD(ks_rcs, "CachedCF").caching(CFMetaData.Caching.ALL)));
schema.add(KSMetaData.testMetadataNotDurable(ks_nocommit,
simple,