Skip to content

Commit 76f3804

Browse files
committed
feature(perf): support latte in gradual grow throughput test
Gradual throughput test uses several substitution variables and 2 of them, called "$threads" and "$throttle", are not compatible "as-is" with the latte benchmarking tool. First, Latte has "--threads=N" and "--concurrency=M" parameters whereas cassandra-stress has only "--threads". So, latte's values must be multiplied to get CS's value. Second, latte uses "--rate=100" not "fixed=100/s" or "throttle=100s" like CS does. Knowing above, add appropriate parsing of the latte command to support existing substitution values. Example: Following CS command: cassandra-stress mixed cl=QUORUM duration=$duration -mode cql3 native \ -rate 'threads=$threads $throttle' \ -col 'size=FIXED(1024) n=FIXED(1)' -pop seq=15000001..20000000 Can be simulated by the following Latte command: latte run --function=write,read --tag=mixed --sampling=10s --duration=$duration \ $throttle --threads=7 --concurrency=$threads --consistency=QUORUM --start-cycle 15000001 --end-cycle 20000000 \ -P key_size=10 -P column_size=1024 -P column_count=1 -P row_count=20000000 data_dir/latte/latte_cs_alike.rn In case of Latte we specify "--threads" explicitly as (N-1) value where N is number of CPU cores on loader nodes.
1 parent b871eb6 commit 76f3804

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

performance_regression_gradual_grow_throughput.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import math
12
import pathlib
23
import time
34
from enum import Enum
@@ -10,6 +11,7 @@
1011
from sdcm.utils.common import skip_optional_stage
1112
from sdcm.sct_events import Severity
1213
from sdcm.sct_events.system import TestFrameworkEvent
14+
from sdcm.stress.latte_thread import find_latte_threads_num
1315
from sdcm.results_analyze import PredefinedStepsTestPerformanceAnalyzer
1416
from sdcm.utils.decorators import latency_calculator_decorator
1517
from sdcm.utils.latency import calculate_latency, analyze_hdr_percentiles
@@ -32,6 +34,21 @@ class Workload(NamedTuple):
3234
step_duration: str
3335

3436

37+
def is_latte_command(stress_cmd: str) -> bool:
38+
return "latte " in stress_cmd and " run " in stress_cmd
39+
40+
41+
def process_stress_threads_number(stress_cmd: str, num_threads: int) -> int:
42+
# NOTE: latte has 2 separate options - '--threads' and '--concurrency'.
43+
# CS's threads == latte threads multiple of 'concurrency'
44+
# Example: 620 CS threads = 7 latte threads with concurrency as '89' per each thread (623)
45+
if is_latte_command(stress_cmd):
46+
latte_threads_num = find_latte_threads_num(stress_cmd)
47+
return math.ceil(num_threads / latte_threads_num)
48+
49+
return num_threads
50+
51+
3552
class PerformanceRegressionPredefinedStepsTest(PerformanceRegressionTest): # pylint: disable=too-many-instance-attributes
3653
"""
3754
This class presents new performance test that run gradual increased throughput steps.
@@ -191,8 +208,9 @@ def run_step(self, stress_cmds, current_throttle, num_threads, step_duration):
191208
stress_queue = []
192209
for stress_cmd in stress_cmds:
193210
params = {"round_robin": True, "stats_aggregate_cmds": False}
211+
current_num_threads = process_stress_threads_number(stress_cmd, num_threads)
194212
stress_cmd_to_run = stress_cmd.replace(
195-
"$threads", f"{num_threads}").replace("$throttle", f"{current_throttle}")
213+
"$threads", f"{current_num_threads}").replace("$throttle", f"{current_throttle}")
196214
if step_duration is not None:
197215
stress_cmd_to_run = stress_cmd_to_run.replace("$duration", step_duration)
198216
params.update({'stress_cmd': stress_cmd_to_run})
@@ -225,7 +243,15 @@ def run_gradual_increase_load(self, workload: Workload, stress_num, num_loaders,
225243

226244
for throttle_step in workload.throttle_steps:
227245
self.log.info("Run cs command with rate: %s Kops", throttle_step)
228-
current_throttle = f"fixed={int(int(throttle_step) // (num_loaders * stress_num))}/s" if throttle_step != "unthrottled" else ""
246+
if throttle_step == "unthrottled":
247+
current_throttle = ""
248+
else:
249+
throttle_value = int(int(throttle_step) // (num_loaders * stress_num))
250+
if is_latte_command(workload.cs_cmd_tmpl[0]):
251+
current_throttle = f"--rate={throttle_value}"
252+
else:
253+
current_throttle = f"fixed={throttle_value}/s"
254+
229255
run_step = ((latency_calculator_decorator(legend=f"Gradual test step {throttle_step} op/s",
230256
cycle_name=throttle_step))(self.run_step))
231257
results, _ = run_step(stress_cmds=workload.cs_cmd_tmpl, current_throttle=current_throttle,
@@ -304,7 +330,8 @@ def warmup_cache(self, stress_cmd_templ, num_threads):
304330
stress_queue = []
305331
for stress_cmd in stress_cmd_templ:
306332
params = {"round_robin": True, "stats_aggregate_cmds": False}
307-
stress_cmd_to_run = stress_cmd.replace("$threads", str(num_threads))
333+
current_num_threads = process_stress_threads_number(stress_cmd, num_threads)
334+
stress_cmd_to_run = stress_cmd.replace("$threads", str(current_num_threads))
308335
params.update({'stress_cmd': stress_cmd_to_run})
309336
# Run all stress commands
310337
self.log.debug('RUNNING warm up stress cmd: %s', stress_cmd_to_run)

sdcm/stress/latte_thread.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
LATTE_FN_NAME_RE = '(?:-f|--function)[ =]([\w\s\d:,]+)|--functions[ =]([\w\s\d:,]+)'
3838
LATTE_TAG_RE = r'--tag(?:\s+|=)([\w-]+(?:,[\w-]+)*)\b'
39+
LATTE_THREADS_RE = r"(?:\s|^)(?:-t[= ]|--threads[= ]?)(\d+)(?:\s|$)"
3940
LOGGER = logging.getLogger(__name__)
4041

4142

@@ -66,6 +67,14 @@ def find_latte_tags(stress_cmd):
6667
return tags
6768

6869

70+
def find_latte_threads_num(stress_cmd):
71+
matches = re.findall(LATTE_THREADS_RE, stress_cmd)
72+
if matches:
73+
return int(matches[0])
74+
# NOTE: threads were not specified, assume latte's default as `1`
75+
return 1
76+
77+
6978
def get_latte_operation_type(stress_cmd):
7079
write_found, counter_write, read_found, counter_read = False, False, False, False
7180
for fn in find_latte_fn_names(stress_cmd):

0 commit comments

Comments
 (0)