Merge pull request #915 from nosqlbench/my-cql-astra-example

Security Fix by removing CompatibilityFixups
This commit is contained in:
MikeYaacoubStax
2023-01-12 17:50:18 -05:00
committed by GitHub
9 changed files with 202 additions and 211 deletions

View File

@@ -0,0 +1,77 @@
---
title: CQL Key-Value
weight: 1
---
## Description
The CQL Key-Value workload demonstrates the simplest possible schema with payload data. This is useful for measuring
system capacity most directly in terms of raw operations. As a reference point, provides some insight around types of
workloads that are constrained around messaging, threading, and tasking, rather than bulk throughput.
During preload, all keys are set with a value. During the main phase of the workload, random keys from the known
population are replaced with new values which never repeat. During the main phase, random partitions are selected for
upsert, with row values never repeating.
## Operations
### insert (rampup, main)
insert into baselines.keyvalue (key, value) values (?,?);
### read (main)
select * from baselines.keyvalue where key=?key;
## Data Set
### baselines.keyvalue insert (rampup)
- key - text, number as string, selected sequentially up to keycount
- value - text, number as string, selected sequentially up to valuecount
### baselines.keyvalue insert (main)
- key - text, number as string, selected uniformly within keycount
- value - text, number as string, selected uniformly within valuecount
### baselines.keyvalue read (main)
- key - text, number as string, selected uniformly within keycount
## Workload Parameters
This workload has no adjustable parameters when used in the baseline tests.
When used for additional testing, the following parameters should be supported:
- keycount - the number of unique keys
- valuecount - the number of unique values
## Key Performance Metrics
Client side metrics are a more accurate measure of the system behavior from a user's perspective. For microbench and
baseline tests, these are the only required metrics. When gathering metrics from multiple server nodes, they should be
kept in aggregate form, for min, max, and average for each time interval in monitoring. For example, the avg p99 latency
for reads should be kept, as well as the min p99 latency for reads. If possible metrics, should be kept in plot form,
with discrete histogram values per interval.
### Client-Side
- read ops/s
- write ops/s
- read latency histograms
- write latency histograms
- exception counts
### Server-Side
- pending compactions
- bytes compacted
- active data on disk
- total data on disk
# Notes on Interpretation
Once the average ratio of overwrites starts to balance with the rate of compaction, a steady state should be achieved.
At this point, pending compactions and bytes compacted should be mostly flat over time.

View File

@@ -0,0 +1,96 @@
description: A workload with only text keys and text values
scenarios:
default:
schema: run driver=cql tags==phase:schema threads==1 cycles==UNDEF
rampup: run driver=cql tags==phase:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
main: run driver=cql tags==phase:main cycles===TEMPLATE(main-cycles,10000000) threads=auto
astra:
schema: run driver=cql tags==phase:schema-astra threads==1 cycles==UNDEF
rampup: run driver=cql tags==phase:rampup cycles===TEMPLATE(rampup-cycles,10000000) threads=auto
main: run driver=cql tags==phase:main cycles===TEMPLATE(main-cycles,10000000) threads=auto
bindings:
seq_key: Mod(<<keycount:1000000000>>); ToString() -> String
seq_value: Hash(); Mod(<<valuecount:1000000000>>); ToString() -> String
rw_key: <<keydist:Uniform(0,1000000000)->int>>; ToString() -> String
rw_value: Hash(); <<valdist:Uniform(0,1000000000)->int>>; ToString() -> String
blocks:
- name: schema
tags:
phase: schema
params:
prepared: false
statements:
- create-table: |
create table if not exists <<keyspace:baselines>>.<<table:keyvalue>> (
key text,
value text,
PRIMARY KEY (key)
);
tags:
name: create-table
- name: schema-astra
tags:
phase: schema-astra
params:
prepared: false
statements:
- create-table: |
create table if not exists <<keyspace:baselines>>.<<table:keyvalue>> (
key text,
value text,
PRIMARY KEY (key)
);
tags:
name: create-table-astra
- name: rampup
tags:
phase: rampup
params:
cl: <<write_cl:LOCAL_QUORUM>>
statements:
- rampup-insert: |
insert into <<keyspace:baselines>>.<<table:keyvalue>>
(key, value)
values ({seq_key},{seq_value});
tags:
name: rampup-insert
- name: verify
tags:
phase: verify
type: read
params:
cl: <<read_cl:LOCAL_QUORUM>>
statements:
- verify-select: |
select * from <<keyspace:baselines>>.<<table:keyvalue>> where key={seq_key};
verify-fields: key->seq_key, value->seq_value
tags:
name: verify
- name: main-read
tags:
phase: main
type: read
params:
ratio: 5
cl: <<read_cl:LOCAL_QUORUM>>
statements:
- main-select: |
select * from <<keyspace:baselines>>.<<table:keyvalue>> where key={rw_key};
tags:
name: main-select
- name: main-write
tags:
phase: main
type: write
params:
ratio: 5
cl: <<write_cl:LOCAL_QUORUM>>
statements:
- main-insert: |
insert into <<keyspace:baselines>>.<<table:keyvalue>>
(key, value) values ({rw_key}, {rw_value});
tags:
name: main-insert

View File

@@ -1,128 +0,0 @@
/*
* Copyright (c) 2022-2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.core.bindings;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CompatibilityFixups {
private final static Logger logger = LogManager.getLogger(CompatibilityFixups.class);
// Not all of these are simple upper-case changes
private final static Map<String, String> funcs = new HashMap<String, String>() {{
put("log_normal", "LogNormal");
put("normal", "Normal");
put("levy", "Levy");
put("nakagami", "Nakagami");
put("exponential", "Exponential");
put("logistic", "Logistic");
put("laplace", "Laplace");
put("cauchy", "Cauchy");
put("f", "F");
put("t", "T");
put("weibull", "Weibull");
put("chi_squared", "ChiSquared");
put("gumbel", "Gumbel");
put("beta", "Beta");
put("pareto", "Pareto");
put("gamma", "Gamma");
put("uniform_real", "Uniform");
put("uniform_integer", "Uniform");
put("hypergeometric", "Hypergeometric");
put("geometric", "Geometric");
put("poisson", "Poisson");
put("zipf", "Zipf");
put("binomial", "Binomial");
put("pascal", "Pascal");
}};
private static final String MAPTO = "mapto_";
private static final String HASHTO = "hashto_";
private static final String COMPUTE = "compute_";
private static final String INTERPOLATE = "interpolate_";
private final static Pattern oldcurve = Pattern.compile("\\b(?<name>[\\w_]{1,512})(?<lparen>\\()(?<args>.*?)(?<rparen>\\))");
private final static CompatibilityFixups instance = new CompatibilityFixups();
public static String fixup(String spec) {
String fixed = instance.fix(spec);
if (!fixed.equals(spec)) {
logger.warn(spec + "' was preprocessed to '" + fixed + "'. Please change to the new one to avoid this warning.");
}
return fixed;
}
public String fix(String spec) {
if (spec == null) {
throw new RuntimeException("Unable to fixup a spec that is null");
}
// Fixup curve ctors. These are not HOF, so local matching will work fine. However, they could occur multiple
// times within an HOF, so multiple replace is necessary.
Matcher matcher = oldcurve.matcher(spec);
StringBuilder out = new StringBuilder(spec.length());
int start = 0;
while (matcher.find()) {
out.append(spec, start, matcher.start());
String replacement = fixCurveCall(matcher.group("name"), matcher.group("args"));
out.append(replacement);
start = matcher.end();
}
out.append(spec.substring(start));
return out.toString();
}
private String fixCurveCall(String name, String args) {
boolean map = false;
boolean compute = false;
if (name.contains(MAPTO)) {
name = name.replaceAll(MAPTO, "");
map = true;
}
if (name.contains(HASHTO)) {
name = name.replaceAll(HASHTO, "");
map = false;
}
if (name.contains(COMPUTE)) {
name = name.replaceAll(COMPUTE, "");
compute = true;
}
if (name.contains(INTERPOLATE)) {
name = name.replaceAll(INTERPOLATE, "");
compute = false;
}
String nameReplacement = funcs.get(name);
if (nameReplacement != null) {
name = nameReplacement;
args = map ? args + ",'map'" : args + ",'hash'";
args = compute ? args + ",'compute'" : args + ",'interpolate'";
}
return name + "(" + args + ")";
}
}

View File

@@ -97,7 +97,6 @@ public class VirtData {
* @return An optional function which will be empty if the function could not be resolved.
*/
public static <T> Optional<DataMapper<T>> getOptionalMapper(String flowSpec, Map<String,?> config) {
flowSpec = CompatibilityFixups.fixup(flowSpec);
VirtDataDSL.ParseResult parseResult = VirtDataDSL.parse(flowSpec);
if (parseResult.throwable != null) {
throw new RuntimeException("Error while parsing binding specification '" + flowSpec +"': "+ parseResult.throwable);
@@ -118,7 +117,6 @@ public class VirtData {
public static ResolverDiagnostics getMapperDiagnostics(String flowSpec, Map<String,Object> config) {
try {
flowSpec = CompatibilityFixups.fixup(flowSpec);
VirtDataDSL.ParseResult parseResult = VirtDataDSL.parse(flowSpec);
if (parseResult.throwable != null) {
throw new RuntimeException(parseResult.throwable);
@@ -156,7 +154,7 @@ public class VirtData {
final String originalflowSpec,
Class<?> clazz,
Map<String,Object> config) {
String flowSpec = CompatibilityFixups.fixup(originalflowSpec);
String flowSpec = originalflowSpec;
VirtDataDSL.ParseResult parseResult = VirtDataDSL.parse(flowSpec);
if (parseResult.throwable != null) {
throw new RuntimeException(parseResult.throwable);
@@ -207,7 +205,6 @@ public class VirtData {
}
public static <T> Optional<T> getOptionalFunction(String flowSpec, Class<? extends T> functionType, Map<String,Object> config) {
flowSpec = CompatibilityFixups.fixup(flowSpec);
Class<?> requiredInputType = FunctionTyper.getInputClass(functionType);
Class<?> requiredOutputType = FunctionTyper.getResultClass(functionType);

View File

@@ -1,51 +0,0 @@
/*
* Copyright (c) 2022 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.core;
import io.nosqlbench.virtdata.core.bindings.CompatibilityFixups;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class CompatibilityFixupsTest {
@Test
public void testInlineChange() {
assertThat(CompatibilityFixups.fixup("Hash(); uniform_integer(0,1000000000); ToString() -> String"))
.isEqualTo("Hash(); Uniform(0,1000000000,'hash','interpolate'); ToString() -> String");
}
@Test
public void testFixupModifiers() {
assertThat(CompatibilityFixups.fixup("compute_levy(ASDF)")).isEqualTo("Levy(ASDF,'hash','compute')");
assertThat(CompatibilityFixups.fixup("interpolate_levy(ASDF)")).isEqualTo("Levy(ASDF,'hash','interpolate')");
assertThat(CompatibilityFixups.fixup("mapto_levy(ASDF)")).isEqualTo("Levy(ASDF,'map','interpolate')");
assertThat(CompatibilityFixups.fixup("hashto_levy(ASDF)")).isEqualTo("Levy(ASDF,'hash','interpolate')");
}
@Test
public void testFixupNames() {
assertThat(CompatibilityFixups.fixup("gamma(foo)")).isEqualTo("Gamma(foo,'hash','interpolate')");
assertThat(CompatibilityFixups.fixup("mapto_uniform_integer(foo)")).isEqualTo("Uniform(foo,'map','interpolate')");
assertThat(CompatibilityFixups.fixup("hashto_uniform_real(foo)")).isEqualTo("Uniform(foo,'hash','interpolate')");
}
@Test
public void testParsingSanity() {
assertThat(CompatibilityFixups.fixup("long -> Add(5) -> long")).isEqualTo("long -> Add(5) -> long");
}
}

View File

@@ -37,10 +37,10 @@ public class RealDistributionsConcurrencyTests {
@Test
public void testConcurrentBinomialHashValues() {
testConcurrentRealHashDistValues(
"normal(10.0,2.0)/100 threads/1000 iterations",
"Normal(10.0,2.0)/100 threads/1000 iterations",
100,
1000,
"normal(10.0,2.0)");
"Normal(10.0,2.0)");
}
private void testConcurrentRealHashDistValues(

View File

@@ -44,14 +44,14 @@ public class IntegratedComposerLibraryTest {
@Test
public void testChainedTypeResolutionForLong() {
BindingsTemplate bt = new BindingsTemplate();
bt.addFieldBinding("longchain", "compose CycleRange(123456789) ; Div(3); Mod(7) -> long");
bt.addFieldBinding("longchain", "CycleRange(123456789) ; Div(3); Mod(7) -> long");
Bindings bindings = bt.resolveBindings();
}
@Test
public void testChainedTypeResolutionForWithInternalLong() {
BindingsTemplate bt = new BindingsTemplate();
bt.addFieldBinding("longchain", "compose HashRange(1234,6789) -> long; Mod(3) -> int;");
bt.addFieldBinding("longchain", "HashRange(1234,6789) -> long; Mod(3) -> int;");
Bindings bindings = bt.resolveBindings();
Object n1 = bindings.getAll(123)[0];
assertThat(n1).isOfAnyClassIn(Integer.class);
@@ -60,21 +60,21 @@ public class IntegratedComposerLibraryTest {
@Test
public void testChainedTypeResolutionForInt() {
BindingsTemplate bt = new BindingsTemplate();
bt.addFieldBinding("intchain", "compose ToInt() ; CycleRange(123456789) ; Div(3) ; Mod(7) -> int");
bt.addFieldBinding("intchain", "ToInt() ; CycleRange(123456789) ; Div(3) ; Mod(7) -> int");
Bindings bindings = bt.resolveBindings();
}
@Test
public void testStringConversion() {
BindingsTemplate bt = new BindingsTemplate();
bt.addFieldBinding("phone","compose HashRange(1000000000,9999999999L); ToString() -> String");
bt.addFieldBinding("phone","HashRange(1000000000,9999999999L); ToString() -> String");
Bindings bindings = bt.resolveBindings();
}
@Test
public void testPrefixSuffix() {
BindingsTemplate bt = new BindingsTemplate();
bt.addFieldBinding("solr_query","compose HashRange(1000000000,9999999999L); ToString(); Prefix('before'); Suffix('after') -> String");
bt.addFieldBinding("solr_query","HashRange(1000000000,9999999999L); ToString(); Prefix('before'); Suffix('after') -> String");
Bindings bindings = bt.resolveBindings();
}
@@ -83,7 +83,7 @@ public class IntegratedComposerLibraryTest {
@Disabled
public void testTypeCoercionWhenNeeded() {
BindingsTemplate bt = new BindingsTemplate();
bt.addFieldBinding("mod_to_string", "compose Mod(3) ; Suffix('0000000000') -> String");
bt.addFieldBinding("mod_to_string", "Mod(3) ; Suffix('0000000000') -> String");
Bindings bindings = bt.resolveBindings();
Object[] all = bindings.getAll(5);
assertThat(all).isNotNull();
@@ -105,7 +105,7 @@ public class IntegratedComposerLibraryTest {
@Test
public void testUUIDChain() {
Optional<DataMapper<Object>> dm =
VirtData.getOptionalMapper("compose Mod(1000); ToHashedUUID() -> java.util.UUID");
VirtData.getOptionalMapper("Mod(1000); ToHashedUUID() -> java.util.UUID");
assertThat(dm).isPresent();
Object o = dm.get().get(5L);
assertThat(o).isEqualTo(UUID.fromString("3df498b1-9568-4584-96fd-76f6081da01a"));
@@ -114,14 +114,14 @@ public class IntegratedComposerLibraryTest {
@Test
public void testNormalDoubleAdd() {
Optional<DataMapper<String>> dm =
VirtData.getOptionalMapper("compose Normal(0.0,5.0); Add(5.0) -> double");
VirtData.getOptionalMapper("Normal(0.0,5.0); Add(5.0) -> double");
assertThat(dm).isPresent();
}
@Test
public void testDistInCompose() {
Optional<DataMapper<String>> dm =
VirtData.getOptionalMapper("compose Hash(); Uniform(0,100); ToString() -> String");
VirtData.getOptionalMapper("Hash(); Uniform(0,100); ToString() -> String");
assertThat(dm).isPresent();
String s = dm.get().get(5L);
assertThat(s).isNotEmpty();
@@ -131,14 +131,14 @@ public class IntegratedComposerLibraryTest {
@Test
public void testComposeSingleFuncTypeCoercion() {
Optional<DataMapper<Object>> longMapper =
VirtData.getOptionalMapper("compose Uniform(1,10) -> long");
VirtData.getOptionalMapper("Uniform(1,10) -> long");
assertThat(longMapper).isPresent();
Object l = longMapper.get().get(23L);
assertThat(l).isNotNull();
assertThat(l.getClass()).isEqualTo(Long.class);
Optional<DataMapper<Object>> intMapper =
VirtData.getOptionalMapper("compose Uniform(1,123) -> int");
VirtData.getOptionalMapper("Uniform(1,123) -> int");
assertThat(intMapper).isPresent();
Object i = intMapper.get().get(23L);
assertThat(i).isNotNull();
@@ -166,13 +166,13 @@ public class IntegratedComposerLibraryTest {
final int intermediateCycle = 52;
final int finalCycle = 81;
Object intermediateValue = assertMapper("compose HashRange(0,100) -> int", 0);
Object intermediateValue = assertMapper("HashRange(0,100) -> int", 0);
assertThat(intermediateValue).isEqualTo(52);
Object finalValue = assertMapper("compose HashRange(0,100) -> int", intermediateCycle);
Object finalValue = assertMapper("HashRange(0,100) -> int", intermediateCycle);
assertThat(finalValue).isEqualTo(16);
Object finalChainedValue = assertMapper("compose HashRange(0,100); HashRange(0,100) -> int", initialCycle);
Object finalChainedValue = assertMapper("HashRange(0,100); HashRange(0,100) -> int", initialCycle);
assertThat(finalChainedValue).isEqualTo(16);
}
@@ -182,10 +182,10 @@ public class IntegratedComposerLibraryTest {
final int initialCycle = 0;
final int finalCycle = 160;
Object o1 = assertMapper("compose HashRange(0,1000); HashRange(0,1000) -> int", initialCycle);
Object o1 = assertMapper("HashRange(0,1000); HashRange(0,1000) -> int", initialCycle);
assertInteger(o1, finalCycle);
Object o2 = assertMapper("compose Identity(); HashRange(0,1000); HashRange(0,1000) -> int", initialCycle);
Object o2 = assertMapper("Identity(); HashRange(0,1000); HashRange(0,1000) -> int", initialCycle);
assertInteger(o2, finalCycle);
}

View File

@@ -47,7 +47,7 @@ public class IntegratedComposerLogicTest {
@Test
public void testSignatureMapping() {
Optional<DataMapper<Object>> dataMapper = VirtData.getOptionalMapper(
"compose HashRange(1000000000,9999999999L); ToString() -> String"
"HashRange(1000000000,9999999999L); ToString() -> String"
);
assertThat(dataMapper).isNotNull();
assertThat(dataMapper).isPresent();
@@ -58,7 +58,7 @@ public class IntegratedComposerLogicTest {
@Test
public void testIntegratedComposer() {
Optional<DataMapper<Object>> dataMapper = VirtData.getOptionalMapper(
"binomial(8,0.5); ToDate() -> java.util.Date"
"Binomial(8,0.5); ToDate() -> java.util.Date"
);
assertThat(dataMapper).isNotNull();
assertThat(dataMapper).isPresent();
@@ -89,7 +89,7 @@ public class IntegratedComposerLogicTest {
Optional<DataMapper<Object>> dataMapper = VirtData.getOptionalMapper(" ModuloLineToString('data/variable_words.txt') -> String");
assertThat(dataMapper).isPresent();
assertThat(dataMapper.get().get(1)).isEqualTo("completion_count");
dataMapper = VirtData.getOptionalMapper("compose ModuloLineToString('variable_words.txt') -> String");
dataMapper = VirtData.getOptionalMapper("ModuloLineToString('variable_words.txt') -> String");
assertThat(dataMapper).isPresent();
assertThat(dataMapper.get().get(1)).isEqualTo("completion_count");
}

View File

@@ -46,7 +46,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void timeuuidRangeExample() {
DataMapper<UUID> uuidgen = VirtData.getMapper(
"compose HashRange(0,60000); ToEpochTimeUUID('2017-01-01 23:59:59') -> java.util.UUID;",
"HashRange(0,60000); ToEpochTimeUUID('2017-01-01 23:59:59') -> java.util.UUID;",
UUID.class
);
UUID uuid1 = uuidgen.get(1L);
@@ -67,7 +67,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void timeuuidSkewExample() {
DataMapper<UUID> uuidgen = VirtData.getMapper(
"compose zipf(10,2); ToEpochTimeUUID('2017-01-01 23:59:59') -> java.util.UUID;",
"Zipf(10,2); ToEpochTimeUUID('2017-01-01 23:59:59') -> java.util.UUID;",
UUID.class
);
UUID uuid1 = uuidgen.get(1L);
@@ -82,7 +82,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void cyclingDateRangeExample() {
DataMapper<Date> dateMapper = VirtData.getMapper(
"compose Mod(10); ToDate() -> java.util.Date;",
"Mod(10); ToDate() -> java.util.Date;",
Date.class
);
Date date1 = dateMapper.get(3L);
@@ -98,7 +98,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void dateInRangeExample() {
DataMapper<Date> dateMapper = VirtData.getMapper(
"compose HashRange(0,10000000); ToDate() -> java.util.Date;",
"HashRange(0,10000000); ToDate() -> java.util.Date;",
Date.class
);
Date date = dateMapper.get(3L);
@@ -114,7 +114,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void dateTimeInRangeExample() {
DataMapper<DateTime> dateTimeMapper = VirtData.getMapper(
"compose HashRange(0,10000000); ToDateTime() -> org.joda.time.DateTime;",
"HashRange(0,10000000); ToDateTime() -> org.joda.time.DateTime;",
DateTime.class
);
DateTime dt = dateTimeMapper.get(6L);
@@ -138,7 +138,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void manualOffsetDateTimeExample() {
DataMapper<DateTime> dateTimeMapper = VirtData.getMapper(
"compose StartingEpochMillis('2015-01-01'); ToDateTime()-> org.joda.time.DateTime;",
"StartingEpochMillis('2015-01-01'); ToDateTime()-> org.joda.time.DateTime;",
DateTime.class
);
DateTime dt = dateTimeMapper.get(6L);
@@ -157,7 +157,7 @@ public class IntegratedTemporalExamplesTest {
@Test
public void manualOffsetAndSkewedDateTimeExample() {
DataMapper<DateTime> dateTimeMapper = VirtData.getMapper(
"compose zipf(10,2); StartingEpochMillis('2015-01-01'); ToDateTime()-> org.joda.time.DateTime;",
"Zipf(10,2); StartingEpochMillis('2015-01-01'); ToDateTime()-> org.joda.time.DateTime;",
DateTime.class
);
DateTime dt = dateTimeMapper.get(6L);