redis-benchmarks-specification 0.2.24__py3-none-any.whl → 0.2.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of redis-benchmarks-specification might be problematic. Click here for more details.
- redis_benchmarks_specification/__builder__/builder.py +1 -1
- redis_benchmarks_specification/__cli__/cli.py +3 -5
- redis_benchmarks_specification/__common__/timeseries.py +0 -33
- redis_benchmarks_specification/__self_contained_coordinator__/args.py +0 -6
- redis_benchmarks_specification/__self_contained_coordinator__/docker.py +1 -10
- redis_benchmarks_specification/__self_contained_coordinator__/prepopulation.py +0 -9
- redis_benchmarks_specification/__self_contained_coordinator__/runners.py +0 -11
- redis_benchmarks_specification/__self_contained_coordinator__/self_contained_coordinator.py +45 -226
- redis_benchmarks_specification/__spec__/cli.py +2 -2
- redis_benchmarks_specification/setups/topologies/topologies.yml +9 -9
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-setget200c-1KiB-pipeline-10.yml +0 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-multiple-hll-pfcount-100B-values.yml +34 -0
- redis_benchmarks_specification/test-suites/memtier_benchmark-multiple-hll-pfmerge-100B-values.yml +34 -0
- redis_benchmarks_specification/test-suites/memtier_benchmark-playbook-leaderboard-top-10.yml +68 -0
- redis_benchmarks_specification/test-suites/memtier_benchmark-playbook-leaderboard-top-100.yml +68 -0
- redis_benchmarks_specification/test-suites/memtier_benchmark-playbook-leaderboard-top-1000.yml +68 -0
- {redis_benchmarks_specification-0.2.24.dist-info → redis_benchmarks_specification-0.2.25.dist-info}/METADATA +5 -2
- {redis_benchmarks_specification-0.2.24.dist-info → redis_benchmarks_specification-0.2.25.dist-info}/RECORD +21 -18
- {redis_benchmarks_specification-0.2.24.dist-info → redis_benchmarks_specification-0.2.25.dist-info}/WHEEL +1 -1
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-setget200c-1KiB-pipeline-1.yml +0 -41
- redis_benchmarks_specification/test-suites/memtier_benchmark-playbook-leaderboard.yml +0 -92
- {redis_benchmarks_specification-0.2.24.dist-info → redis_benchmarks_specification-0.2.25.dist-info}/entry_points.txt +0 -0
- {redis_benchmarks_specification-0.2.24.dist-info → redis_benchmarks_specification-0.2.25.dist-info/licenses}/LICENSE +0 -0
|
@@ -538,7 +538,7 @@ def builder_process_stream(
|
|
|
538
538
|
server_name = testDetails[b"server_name"].decode()
|
|
539
539
|
|
|
540
540
|
# Check if artifacts already exist before building
|
|
541
|
-
prefix = f"github_org={github_org}/github_repo={github_repo}/git_branch={str(git_branch)}/git_version={str(git_version)}/git_hash={str(git_hash)}"
|
|
541
|
+
prefix = f"build_spec={build_spec}/github_org={github_org}/github_repo={github_repo}/git_branch={str(git_branch)}/git_version={str(git_version)}/git_hash={str(git_hash)}"
|
|
542
542
|
|
|
543
543
|
# Create a comprehensive build signature that includes all build-affecting parameters
|
|
544
544
|
import hashlib
|
|
@@ -126,9 +126,7 @@ def trigger_tests_dockerhub_cli_command_logic(args, project_name, project_versio
|
|
|
126
126
|
|
|
127
127
|
if result is True:
|
|
128
128
|
# Use architecture-specific stream
|
|
129
|
-
|
|
130
|
-
arch = args.arch if args.arch is not None else "amd64"
|
|
131
|
-
arch_specific_stream = get_arch_specific_stream_name(arch)
|
|
129
|
+
arch_specific_stream = get_arch_specific_stream_name(args.arch)
|
|
132
130
|
logging.info(
|
|
133
131
|
f"CLI adding work to architecture-specific stream: {arch_specific_stream}"
|
|
134
132
|
)
|
|
@@ -220,7 +218,7 @@ def get_commits_by_tags(args, repo):
|
|
|
220
218
|
version.Version(tag.name)
|
|
221
219
|
match_obj = re.search(tags_regex_string, tag.name)
|
|
222
220
|
if match_obj is None:
|
|
223
|
-
logging.
|
|
221
|
+
logging.info(
|
|
224
222
|
"Skipping {} given it does not match regex {}".format(
|
|
225
223
|
tag.name, tags_regexp
|
|
226
224
|
)
|
|
@@ -389,7 +387,7 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
|
|
|
389
387
|
commit_datetime = cdict["commit_datetime"]
|
|
390
388
|
match_obj = re.search(hash_regexp_string, commit_hash)
|
|
391
389
|
if match_obj is None:
|
|
392
|
-
logging.
|
|
390
|
+
logging.info(
|
|
393
391
|
"Skipping {} given it does not match regex {}".format(
|
|
394
392
|
commit_hash, hash_regexp_string
|
|
395
393
|
)
|
|
@@ -136,17 +136,6 @@ def extract_results_table(
|
|
|
136
136
|
# Always use context path for precision_summary metrics to show actual precision levels
|
|
137
137
|
if "precision_summary" in metric_jsonpath and "*" in metric_jsonpath:
|
|
138
138
|
use_metric_context_path = True
|
|
139
|
-
|
|
140
|
-
# Debug logging for JSON path resolution
|
|
141
|
-
if "ALL STATS" in metric_jsonpath or "ALL_STATS" in metric_jsonpath:
|
|
142
|
-
logging.info(
|
|
143
|
-
f"DEBUG: Found {len(find_res)} results for JSONPath '{metric_jsonpath}'"
|
|
144
|
-
)
|
|
145
|
-
for i, result in enumerate(find_res):
|
|
146
|
-
logging.info(
|
|
147
|
-
f" Result {i}: path='{result.path}', value={result.value}, context='{result.context.path}'"
|
|
148
|
-
)
|
|
149
|
-
|
|
150
139
|
for metric in find_res:
|
|
151
140
|
metric_name = str(metric.path)
|
|
152
141
|
metric_value = float(metric.value)
|
|
@@ -211,19 +200,6 @@ def extract_results_table(
|
|
|
211
200
|
logging.warning(
|
|
212
201
|
"Unable to find metric path {} in result dict".format(jsonpath)
|
|
213
202
|
)
|
|
214
|
-
# Debug logging for missing metrics - show available keys
|
|
215
|
-
if "ALL STATS" in str(jsonpath) or "ALL_STATS" in str(jsonpath):
|
|
216
|
-
logging.info(
|
|
217
|
-
f"DEBUG: Available top-level keys in results_dict: {list(results_dict.keys())}"
|
|
218
|
-
)
|
|
219
|
-
if "ALL STATS" in results_dict:
|
|
220
|
-
logging.info(
|
|
221
|
-
f"DEBUG: Keys in 'ALL STATS': {list(results_dict['ALL STATS'].keys())}"
|
|
222
|
-
)
|
|
223
|
-
if "ALL_STATS" in results_dict:
|
|
224
|
-
logging.info(
|
|
225
|
-
f"DEBUG: Keys in 'ALL_STATS': {list(results_dict['ALL_STATS'].keys())}"
|
|
226
|
-
)
|
|
227
203
|
return results_matrix
|
|
228
204
|
|
|
229
205
|
|
|
@@ -431,15 +407,6 @@ def common_timeseries_extraction(
|
|
|
431
407
|
test_case_targets_dict = cleaned_metric[4]
|
|
432
408
|
use_metric_context_path = cleaned_metric[5]
|
|
433
409
|
|
|
434
|
-
# Debug logging for metric extraction
|
|
435
|
-
logging.info(
|
|
436
|
-
f"Extracted metric - JSONPath: '{metric_jsonpath}', Name: '{metric_name}', Value: {metric_value}"
|
|
437
|
-
)
|
|
438
|
-
if "ALL_STATS.Totals.Ops/sec" in metric_name or "ALL STATS" in metric_jsonpath:
|
|
439
|
-
logging.warning(
|
|
440
|
-
f"DEBUG ALL_STATS metric - JSONPath: '{metric_jsonpath}', Name: '{metric_name}', Value: {metric_value}, Context: '{metric_context_path}')"
|
|
441
|
-
)
|
|
442
|
-
|
|
443
410
|
target_table_keyname, target_table_dict = from_metric_kv_to_timeserie(
|
|
444
411
|
break_by_key,
|
|
445
412
|
break_by_str,
|
|
@@ -207,10 +207,4 @@ def create_self_contained_coordinator_args(project_name):
|
|
|
207
207
|
action="store_true",
|
|
208
208
|
help="Skip automatically clearing pending messages and resetting consumer group position on startup. By default, pending messages are cleared and consumer group is reset to latest position to skip old work and recover from crashes.",
|
|
209
209
|
)
|
|
210
|
-
parser.add_argument(
|
|
211
|
-
"--enable-cpu-distribution",
|
|
212
|
-
default=False,
|
|
213
|
-
action="store_true",
|
|
214
|
-
help="Enable CPU distribution optimization using Docker cpuset_cpus and nano_cpus parameters. This forces better CPU core distribution for Redis and client containers. Disabled by default.",
|
|
215
|
-
)
|
|
216
210
|
return parser
|
|
@@ -85,19 +85,11 @@ def spin_docker_standalone_redis(
|
|
|
85
85
|
db_cpuset_cpus, current_cpu_pos = generate_cpuset_cpus(
|
|
86
86
|
ceil_db_cpu_limit, current_cpu_pos
|
|
87
87
|
)
|
|
88
|
-
# Calculate nano_cpus for better CPU distribution
|
|
89
|
-
redis_cpu_count = len(db_cpuset_cpus.split(","))
|
|
90
|
-
redis_nano_cpus = int(redis_cpu_count * 1e9) # 1 CPU = 1e9 nano_cpus
|
|
91
|
-
|
|
92
88
|
logging.info(
|
|
93
89
|
"Running redis-server on docker image {} (cpuset={}) with the following args: {}".format(
|
|
94
90
|
run_image, db_cpuset_cpus, command_str
|
|
95
91
|
)
|
|
96
92
|
)
|
|
97
|
-
logging.info(
|
|
98
|
-
f"Redis container will use {redis_cpu_count} CPUs (nano_cpus={redis_nano_cpus}) on cores {db_cpuset_cpus}"
|
|
99
|
-
)
|
|
100
|
-
|
|
101
93
|
container = docker_client.containers.run(
|
|
102
94
|
image=run_image,
|
|
103
95
|
volumes={
|
|
@@ -110,8 +102,7 @@ def spin_docker_standalone_redis(
|
|
|
110
102
|
network_mode="host",
|
|
111
103
|
detach=True,
|
|
112
104
|
cpuset_cpus=db_cpuset_cpus,
|
|
113
|
-
|
|
114
|
-
# pid_mode="host",
|
|
105
|
+
pid_mode="host",
|
|
115
106
|
)
|
|
116
107
|
redis_containers.append(container)
|
|
117
108
|
return current_cpu_pos
|
|
@@ -67,14 +67,6 @@ def data_prepopulation_step(
|
|
|
67
67
|
# run the benchmark
|
|
68
68
|
preload_start_time = datetime.datetime.now()
|
|
69
69
|
|
|
70
|
-
# Calculate nano_cpus for better CPU distribution
|
|
71
|
-
preload_cpu_count = len(client_cpuset_cpus.split(","))
|
|
72
|
-
preload_nano_cpus = int(preload_cpu_count * 1e9) # 1 CPU = 1e9 nano_cpus
|
|
73
|
-
|
|
74
|
-
logging.info(
|
|
75
|
-
f"Preload container will use {preload_cpu_count} CPUs (nano_cpus={preload_nano_cpus}) on cores {client_cpuset_cpus}"
|
|
76
|
-
)
|
|
77
|
-
|
|
78
70
|
client_container_stdout = docker_client.containers.run(
|
|
79
71
|
image=preload_image,
|
|
80
72
|
volumes={
|
|
@@ -90,7 +82,6 @@ def data_prepopulation_step(
|
|
|
90
82
|
network_mode="host",
|
|
91
83
|
detach=False,
|
|
92
84
|
cpuset_cpus=client_cpuset_cpus,
|
|
93
|
-
nano_cpus=preload_nano_cpus, # Force CPU distribution
|
|
94
85
|
)
|
|
95
86
|
|
|
96
87
|
preload_end_time = datetime.datetime.now()
|
|
@@ -540,16 +540,6 @@ def process_self_contained_coordinator_stream(
|
|
|
540
540
|
# run the benchmark
|
|
541
541
|
benchmark_start_time = datetime.datetime.now()
|
|
542
542
|
|
|
543
|
-
# Calculate nano_cpus for better CPU distribution
|
|
544
|
-
client_cpu_count = len(client_cpuset_cpus.split(","))
|
|
545
|
-
client_nano_cpus = int(
|
|
546
|
-
client_cpu_count * 1e9
|
|
547
|
-
) # 1 CPU = 1e9 nano_cpus
|
|
548
|
-
|
|
549
|
-
logging.info(
|
|
550
|
-
f"Client container will use {client_cpu_count} CPUs (nano_cpus={client_nano_cpus}) on cores {client_cpuset_cpus}"
|
|
551
|
-
)
|
|
552
|
-
|
|
553
543
|
client_container_stdout = docker_client.containers.run(
|
|
554
544
|
image=client_container_image,
|
|
555
545
|
volumes={
|
|
@@ -565,7 +555,6 @@ def process_self_contained_coordinator_stream(
|
|
|
565
555
|
network_mode="host",
|
|
566
556
|
detach=False,
|
|
567
557
|
cpuset_cpus=client_cpuset_cpus,
|
|
568
|
-
nano_cpus=client_nano_cpus, # Force CPU distribution
|
|
569
558
|
)
|
|
570
559
|
|
|
571
560
|
benchmark_end_time = datetime.datetime.now()
|
|
@@ -772,7 +772,6 @@ def main():
|
|
|
772
772
|
priority_upper_limit,
|
|
773
773
|
default_baseline_branch,
|
|
774
774
|
default_metrics_str,
|
|
775
|
-
args=args,
|
|
776
775
|
)
|
|
777
776
|
|
|
778
777
|
|
|
@@ -809,7 +808,6 @@ def self_contained_coordinator_blocking_read(
|
|
|
809
808
|
default_metrics_str="ALL_STATS.Totals.Ops/sec",
|
|
810
809
|
docker_keep_env=False,
|
|
811
810
|
restore_build_artifacts_default=True,
|
|
812
|
-
args=None,
|
|
813
811
|
):
|
|
814
812
|
num_process_streams = 0
|
|
815
813
|
num_process_test_suites = 0
|
|
@@ -1407,10 +1405,6 @@ def process_self_contained_coordinator_stream(
|
|
|
1407
1405
|
redis_containers,
|
|
1408
1406
|
run_image,
|
|
1409
1407
|
temporary_dir,
|
|
1410
|
-
auto_remove=False,
|
|
1411
|
-
enable_cpu_distribution=(
|
|
1412
|
-
getattr(args, 'enable_cpu_distribution', False) if args else False
|
|
1413
|
-
),
|
|
1414
1408
|
)
|
|
1415
1409
|
|
|
1416
1410
|
r = redis.StrictRedis(
|
|
@@ -1470,7 +1464,6 @@ def process_self_contained_coordinator_stream(
|
|
|
1470
1464
|
temporary_dir,
|
|
1471
1465
|
test_name,
|
|
1472
1466
|
redis_password,
|
|
1473
|
-
args,
|
|
1474
1467
|
)
|
|
1475
1468
|
|
|
1476
1469
|
execute_init_commands(
|
|
@@ -1607,120 +1600,29 @@ def process_self_contained_coordinator_stream(
|
|
|
1607
1600
|
f"Using default container timeout: {container_timeout}s"
|
|
1608
1601
|
)
|
|
1609
1602
|
|
|
1610
|
-
# Prepare client container arguments
|
|
1611
|
-
client_container_args = {
|
|
1612
|
-
"image": client_container_image,
|
|
1613
|
-
"volumes": {
|
|
1614
|
-
temporary_dir_client: {
|
|
1615
|
-
"bind": client_mnt_point,
|
|
1616
|
-
"mode": "rw",
|
|
1617
|
-
},
|
|
1618
|
-
},
|
|
1619
|
-
"auto_remove": False, # Don't auto-remove so we can get logs if timeout
|
|
1620
|
-
"privileged": True,
|
|
1621
|
-
"working_dir": benchmark_tool_workdir,
|
|
1622
|
-
"command": benchmark_command_str,
|
|
1623
|
-
"network_mode": "host",
|
|
1624
|
-
"detach": True, # Detach to enable timeout
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
|
-
# Add CPU distribution settings if enabled
|
|
1628
|
-
enable_cpu_distribution = (
|
|
1629
|
-
getattr(args, 'enable_cpu_distribution', False) if args else False
|
|
1630
|
-
)
|
|
1631
|
-
if enable_cpu_distribution:
|
|
1632
|
-
client_cpu_count = len(
|
|
1633
|
-
client_cpuset_cpus.split(",")
|
|
1634
|
-
)
|
|
1635
|
-
client_nano_cpus = int(
|
|
1636
|
-
client_cpu_count * 1e9
|
|
1637
|
-
) # 1 CPU = 1e9 nano_cpus
|
|
1638
|
-
|
|
1639
|
-
client_container_args["cpuset_cpus"] = (
|
|
1640
|
-
client_cpuset_cpus
|
|
1641
|
-
)
|
|
1642
|
-
client_container_args["nano_cpus"] = (
|
|
1643
|
-
client_nano_cpus
|
|
1644
|
-
)
|
|
1645
|
-
|
|
1646
|
-
logging.info(
|
|
1647
|
-
f"Client container will use {client_cpu_count} CPUs (nano_cpus={client_nano_cpus}) on cores {client_cpuset_cpus} [CPU distribution enabled]"
|
|
1648
|
-
)
|
|
1649
|
-
else:
|
|
1650
|
-
logging.info(
|
|
1651
|
-
f"Client container will use default CPU allocation [CPU distribution disabled]"
|
|
1652
|
-
)
|
|
1653
|
-
|
|
1654
1603
|
try:
|
|
1655
1604
|
# Start container with detach=True to enable timeout handling
|
|
1656
1605
|
container = docker_client.containers.run(
|
|
1657
|
-
|
|
1606
|
+
image=client_container_image,
|
|
1607
|
+
volumes={
|
|
1608
|
+
temporary_dir_client: {
|
|
1609
|
+
"bind": client_mnt_point,
|
|
1610
|
+
"mode": "rw",
|
|
1611
|
+
},
|
|
1612
|
+
},
|
|
1613
|
+
auto_remove=False, # Don't auto-remove so we can get logs if timeout
|
|
1614
|
+
privileged=True,
|
|
1615
|
+
working_dir=benchmark_tool_workdir,
|
|
1616
|
+
command=benchmark_command_str,
|
|
1617
|
+
network_mode="host",
|
|
1618
|
+
detach=True, # Detach to enable timeout
|
|
1619
|
+
cpuset_cpus=client_cpuset_cpus,
|
|
1658
1620
|
)
|
|
1659
1621
|
|
|
1660
1622
|
logging.info(
|
|
1661
1623
|
f"Started container {container.name} ({container.id[:12]}) with {container_timeout}s timeout"
|
|
1662
1624
|
)
|
|
1663
1625
|
|
|
1664
|
-
# Apply CPU affinity using taskset if CPU distribution is enabled
|
|
1665
|
-
if enable_cpu_distribution:
|
|
1666
|
-
try:
|
|
1667
|
-
container_info = (
|
|
1668
|
-
docker_client.api.inspect_container(
|
|
1669
|
-
container.id
|
|
1670
|
-
)
|
|
1671
|
-
)
|
|
1672
|
-
container_pid = container_info["State"][
|
|
1673
|
-
"Pid"
|
|
1674
|
-
]
|
|
1675
|
-
|
|
1676
|
-
logging.info(
|
|
1677
|
-
f"Setting CPU affinity for client container PID {container_pid} to cores {client_cpuset_cpus}"
|
|
1678
|
-
)
|
|
1679
|
-
|
|
1680
|
-
# Set CPU affinity for the main process and all its threads
|
|
1681
|
-
subprocess.run(
|
|
1682
|
-
f"taskset -cp {client_cpuset_cpus} {container_pid}",
|
|
1683
|
-
shell=True,
|
|
1684
|
-
check=True,
|
|
1685
|
-
)
|
|
1686
|
-
|
|
1687
|
-
# Wait a moment for client to start its threads, then set affinity for all child processes
|
|
1688
|
-
time.sleep(1)
|
|
1689
|
-
result = subprocess.run(
|
|
1690
|
-
f"pgrep -P {container_pid}",
|
|
1691
|
-
shell=True,
|
|
1692
|
-
capture_output=True,
|
|
1693
|
-
text=True,
|
|
1694
|
-
)
|
|
1695
|
-
if result.returncode == 0:
|
|
1696
|
-
child_pids = (
|
|
1697
|
-
result.stdout.strip().split("\n")
|
|
1698
|
-
)
|
|
1699
|
-
for child_pid in child_pids:
|
|
1700
|
-
if child_pid.strip():
|
|
1701
|
-
try:
|
|
1702
|
-
subprocess.run(
|
|
1703
|
-
f"taskset -cp {client_cpuset_cpus} {child_pid.strip()}",
|
|
1704
|
-
shell=True,
|
|
1705
|
-
check=True,
|
|
1706
|
-
)
|
|
1707
|
-
logging.info(
|
|
1708
|
-
f"Set CPU affinity for client child process {child_pid.strip()}"
|
|
1709
|
-
)
|
|
1710
|
-
except (
|
|
1711
|
-
subprocess.CalledProcessError
|
|
1712
|
-
):
|
|
1713
|
-
pass # Child process may have exited
|
|
1714
|
-
|
|
1715
|
-
logging.info(
|
|
1716
|
-
f"✅ Applied CPU affinity to client container and all child processes"
|
|
1717
|
-
)
|
|
1718
|
-
|
|
1719
|
-
except Exception as e:
|
|
1720
|
-
logging.warning(
|
|
1721
|
-
f"Failed to set CPU affinity for client container: {e}"
|
|
1722
|
-
)
|
|
1723
|
-
|
|
1724
1626
|
# Wait for container with timeout
|
|
1725
1627
|
try:
|
|
1726
1628
|
result = container.wait(
|
|
@@ -2329,7 +2231,6 @@ def start_redis_container(
|
|
|
2329
2231
|
run_image,
|
|
2330
2232
|
temporary_dir,
|
|
2331
2233
|
auto_remove=False,
|
|
2332
|
-
enable_cpu_distribution=False,
|
|
2333
2234
|
):
|
|
2334
2235
|
logging.info(
|
|
2335
2236
|
"Running redis-server on docker image {} (cpuset={}) with the following args: {}".format(
|
|
@@ -2347,82 +2248,20 @@ def start_redis_container(
|
|
|
2347
2248
|
}
|
|
2348
2249
|
logging.info(f"setting volume as follow: {volumes}. working_dir={mnt_point}")
|
|
2349
2250
|
working_dir = mnt_point
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
"
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
"
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
# Add CPU distribution settings if enabled
|
|
2365
|
-
if enable_cpu_distribution:
|
|
2366
|
-
redis_cpu_count = len(db_cpuset_cpus.split(","))
|
|
2367
|
-
redis_nano_cpus = int(redis_cpu_count * 1e9) # 1 CPU = 1e9 nano_cpus
|
|
2368
|
-
|
|
2369
|
-
container_args["cpuset_cpus"] = db_cpuset_cpus
|
|
2370
|
-
container_args["nano_cpus"] = redis_nano_cpus
|
|
2371
|
-
|
|
2372
|
-
logging.info(
|
|
2373
|
-
f"Redis container will use {redis_cpu_count} CPUs (nano_cpus={redis_nano_cpus}) on cores {db_cpuset_cpus} [CPU distribution enabled]"
|
|
2374
|
-
)
|
|
2375
|
-
else:
|
|
2376
|
-
logging.info(
|
|
2377
|
-
f"Redis container will use default CPU allocation [CPU distribution disabled]"
|
|
2378
|
-
)
|
|
2379
|
-
|
|
2380
|
-
redis_container = docker_client.containers.run(**container_args)
|
|
2251
|
+
redis_container = docker_client.containers.run(
|
|
2252
|
+
image=run_image,
|
|
2253
|
+
volumes=volumes,
|
|
2254
|
+
auto_remove=auto_remove,
|
|
2255
|
+
privileged=True,
|
|
2256
|
+
working_dir=mnt_point,
|
|
2257
|
+
command=command_str,
|
|
2258
|
+
network_mode="host",
|
|
2259
|
+
detach=True,
|
|
2260
|
+
cpuset_cpus=db_cpuset_cpus,
|
|
2261
|
+
pid_mode="host",
|
|
2262
|
+
publish_all_ports=True,
|
|
2263
|
+
)
|
|
2381
2264
|
time.sleep(5)
|
|
2382
|
-
|
|
2383
|
-
# Apply CPU affinity using taskset if CPU distribution is enabled
|
|
2384
|
-
if enable_cpu_distribution:
|
|
2385
|
-
try:
|
|
2386
|
-
container_info = docker_client.api.inspect_container(redis_container.id)
|
|
2387
|
-
container_pid = container_info["State"]["Pid"]
|
|
2388
|
-
|
|
2389
|
-
logging.info(
|
|
2390
|
-
f"Setting CPU affinity for Redis container PID {container_pid} to cores {db_cpuset_cpus}"
|
|
2391
|
-
)
|
|
2392
|
-
|
|
2393
|
-
# Set CPU affinity for the main Redis process and all its threads
|
|
2394
|
-
subprocess.run(
|
|
2395
|
-
f"taskset -cp {db_cpuset_cpus} {container_pid}", shell=True, check=True
|
|
2396
|
-
)
|
|
2397
|
-
|
|
2398
|
-
# Wait a moment for Redis to start its IO threads, then set affinity for all Redis processes
|
|
2399
|
-
time.sleep(2)
|
|
2400
|
-
result = subprocess.run(
|
|
2401
|
-
f"pgrep -P {container_pid}", shell=True, capture_output=True, text=True
|
|
2402
|
-
)
|
|
2403
|
-
if result.returncode == 0:
|
|
2404
|
-
child_pids = result.stdout.strip().split("\n")
|
|
2405
|
-
for child_pid in child_pids:
|
|
2406
|
-
if child_pid.strip():
|
|
2407
|
-
try:
|
|
2408
|
-
subprocess.run(
|
|
2409
|
-
f"taskset -cp {db_cpuset_cpus} {child_pid.strip()}",
|
|
2410
|
-
shell=True,
|
|
2411
|
-
check=True,
|
|
2412
|
-
)
|
|
2413
|
-
logging.info(
|
|
2414
|
-
f"Set CPU affinity for Redis child process {child_pid.strip()}"
|
|
2415
|
-
)
|
|
2416
|
-
except subprocess.CalledProcessError:
|
|
2417
|
-
pass # Child process may have exited
|
|
2418
|
-
|
|
2419
|
-
logging.info(
|
|
2420
|
-
f"✅ Applied CPU affinity to Redis container and all child processes"
|
|
2421
|
-
)
|
|
2422
|
-
|
|
2423
|
-
except Exception as e:
|
|
2424
|
-
logging.warning(f"Failed to set CPU affinity for Redis container: {e}")
|
|
2425
|
-
|
|
2426
2265
|
redis_containers.append(redis_container)
|
|
2427
2266
|
return redis_container
|
|
2428
2267
|
|
|
@@ -2442,14 +2281,14 @@ def filter_test_files(
|
|
|
2442
2281
|
continue
|
|
2443
2282
|
|
|
2444
2283
|
if tests_regexp != ".*":
|
|
2445
|
-
logging.
|
|
2284
|
+
logging.info(
|
|
2446
2285
|
"Filtering all tests via a regular expression: {}".format(tests_regexp)
|
|
2447
2286
|
)
|
|
2448
2287
|
tags_regex_string = re.compile(tests_regexp)
|
|
2449
2288
|
|
|
2450
2289
|
match_obj = re.search(tags_regex_string, test_file)
|
|
2451
2290
|
if match_obj is None:
|
|
2452
|
-
logging.
|
|
2291
|
+
logging.info(
|
|
2453
2292
|
"Skipping {} given it does not match regex {}".format(
|
|
2454
2293
|
test_file, tests_regexp
|
|
2455
2294
|
)
|
|
@@ -2563,7 +2402,6 @@ def data_prepopulation_step(
|
|
|
2563
2402
|
temporary_dir,
|
|
2564
2403
|
test_name,
|
|
2565
2404
|
redis_password,
|
|
2566
|
-
args=None,
|
|
2567
2405
|
):
|
|
2568
2406
|
# setup the benchmark
|
|
2569
2407
|
(
|
|
@@ -2612,43 +2450,24 @@ def data_prepopulation_step(
|
|
|
2612
2450
|
preload_timeout = 1800 # 30 minutes default for data loading
|
|
2613
2451
|
logging.info(f"Starting preload container with {preload_timeout}s timeout")
|
|
2614
2452
|
|
|
2615
|
-
# Prepare preload container arguments
|
|
2616
|
-
preload_container_args = {
|
|
2617
|
-
"image": preload_image,
|
|
2618
|
-
"volumes": {
|
|
2619
|
-
temporary_dir: {
|
|
2620
|
-
"bind": client_mnt_point,
|
|
2621
|
-
"mode": "rw",
|
|
2622
|
-
},
|
|
2623
|
-
},
|
|
2624
|
-
"auto_remove": False, # Don't auto-remove so we can get logs if timeout
|
|
2625
|
-
"privileged": True,
|
|
2626
|
-
"working_dir": benchmark_tool_workdir,
|
|
2627
|
-
"command": preload_command_str,
|
|
2628
|
-
"network_mode": "host",
|
|
2629
|
-
"detach": True, # Detach to enable timeout
|
|
2630
|
-
}
|
|
2631
|
-
|
|
2632
|
-
# Add CPU distribution settings if enabled
|
|
2633
|
-
enable_cpu_distribution = getattr(args, 'enable_cpu_distribution', False) if args else False
|
|
2634
|
-
if enable_cpu_distribution:
|
|
2635
|
-
preload_cpu_count = len(client_cpuset_cpus.split(","))
|
|
2636
|
-
preload_nano_cpus = int(preload_cpu_count * 1e9) # 1 CPU = 1e9 nano_cpus
|
|
2637
|
-
|
|
2638
|
-
preload_container_args["cpuset_cpus"] = client_cpuset_cpus
|
|
2639
|
-
preload_container_args["nano_cpus"] = preload_nano_cpus
|
|
2640
|
-
|
|
2641
|
-
logging.info(
|
|
2642
|
-
f"Preload container will use {preload_cpu_count} CPUs (nano_cpus={preload_nano_cpus}) on cores {client_cpuset_cpus} [CPU distribution enabled]"
|
|
2643
|
-
)
|
|
2644
|
-
else:
|
|
2645
|
-
logging.info(
|
|
2646
|
-
f"Preload container will use default CPU allocation [CPU distribution disabled]"
|
|
2647
|
-
)
|
|
2648
|
-
|
|
2649
2453
|
try:
|
|
2650
2454
|
# Start container with detach=True to enable timeout handling
|
|
2651
|
-
container = docker_client.containers.run(
|
|
2455
|
+
container = docker_client.containers.run(
|
|
2456
|
+
image=preload_image,
|
|
2457
|
+
volumes={
|
|
2458
|
+
temporary_dir: {
|
|
2459
|
+
"bind": client_mnt_point,
|
|
2460
|
+
"mode": "rw",
|
|
2461
|
+
},
|
|
2462
|
+
},
|
|
2463
|
+
auto_remove=False, # Don't auto-remove so we can get logs if timeout
|
|
2464
|
+
privileged=True,
|
|
2465
|
+
working_dir=benchmark_tool_workdir,
|
|
2466
|
+
command=preload_command_str,
|
|
2467
|
+
network_mode="host",
|
|
2468
|
+
detach=True, # Detach to enable timeout
|
|
2469
|
+
cpuset_cpus=client_cpuset_cpus,
|
|
2470
|
+
)
|
|
2652
2471
|
|
|
2653
2472
|
logging.info(
|
|
2654
2473
|
f"Started preload container {container.name} ({container.id[:12]}) with {preload_timeout}s timeout"
|
|
@@ -137,7 +137,7 @@ def cli_command_logic(args, project_name, project_version):
|
|
|
137
137
|
version.Version(tag.name)
|
|
138
138
|
match_obj = re.search(tags_regex_string, tag.name)
|
|
139
139
|
if match_obj is None:
|
|
140
|
-
logging.
|
|
140
|
+
logging.info(
|
|
141
141
|
"Skipping {} given it does not match regex {}".format(
|
|
142
142
|
tag.name, tags_regexp
|
|
143
143
|
)
|
|
@@ -190,7 +190,7 @@ def cli_command_logic(args, project_name, project_version):
|
|
|
190
190
|
commit_summary = cdict["commit_summary"]
|
|
191
191
|
match_obj = re.search(hash_regexp_string, commit_hash)
|
|
192
192
|
if match_obj is None:
|
|
193
|
-
logging.
|
|
193
|
+
logging.info(
|
|
194
194
|
"Skipping {} given it does not match regex {}".format(
|
|
195
195
|
commit_hash, hash_regexp_string
|
|
196
196
|
)
|
|
@@ -26,10 +26,10 @@ spec:
|
|
|
26
26
|
redis_topology:
|
|
27
27
|
primaries: 1
|
|
28
28
|
replicas: 0
|
|
29
|
-
redis_arguments: --io-threads 2 --io-threads-do-reads yes
|
|
29
|
+
redis_arguments: --io-threads 2 --io-threads-do-reads yes
|
|
30
30
|
resources:
|
|
31
31
|
requests:
|
|
32
|
-
cpus: "
|
|
32
|
+
cpus: "3"
|
|
33
33
|
memory: "10g"
|
|
34
34
|
|
|
35
35
|
- name: oss-standalone-04-io-threads
|
|
@@ -37,10 +37,10 @@ spec:
|
|
|
37
37
|
redis_topology:
|
|
38
38
|
primaries: 1
|
|
39
39
|
replicas: 0
|
|
40
|
-
redis_arguments: --io-threads 4 --io-threads-do-reads yes
|
|
40
|
+
redis_arguments: --io-threads 4 --io-threads-do-reads yes
|
|
41
41
|
resources:
|
|
42
42
|
requests:
|
|
43
|
-
cpus: "
|
|
43
|
+
cpus: "5"
|
|
44
44
|
memory: "10g"
|
|
45
45
|
|
|
46
46
|
- name: oss-standalone-08-io-threads
|
|
@@ -48,10 +48,10 @@ spec:
|
|
|
48
48
|
redis_topology:
|
|
49
49
|
primaries: 1
|
|
50
50
|
replicas: 0
|
|
51
|
-
redis_arguments: --io-threads 8 --io-threads-do-reads yes
|
|
51
|
+
redis_arguments: --io-threads 8 --io-threads-do-reads yes
|
|
52
52
|
resources:
|
|
53
53
|
requests:
|
|
54
|
-
cpus: "
|
|
54
|
+
cpus: "9"
|
|
55
55
|
memory: "10g"
|
|
56
56
|
|
|
57
57
|
- name: oss-standalone-16-io-threads
|
|
@@ -62,7 +62,7 @@ spec:
|
|
|
62
62
|
redis_arguments: --io-threads 16 --io-threads-do-reads yes
|
|
63
63
|
resources:
|
|
64
64
|
requests:
|
|
65
|
-
cpus: "
|
|
65
|
+
cpus: "17"
|
|
66
66
|
memory: "10g"
|
|
67
67
|
|
|
68
68
|
- name: oss-standalone-32-io-threads
|
|
@@ -73,7 +73,7 @@ spec:
|
|
|
73
73
|
redis_arguments: --io-threads 32 --io-threads-do-reads yes
|
|
74
74
|
resources:
|
|
75
75
|
requests:
|
|
76
|
-
cpus: "
|
|
76
|
+
cpus: "33"
|
|
77
77
|
memory: "10g"
|
|
78
78
|
|
|
79
79
|
- name: oss-standalone-64-io-threads
|
|
@@ -84,7 +84,7 @@ spec:
|
|
|
84
84
|
redis_arguments: --io-threads 64 --io-threads-do-reads yes
|
|
85
85
|
resources:
|
|
86
86
|
requests:
|
|
87
|
-
cpus: "
|
|
87
|
+
cpus: "65"
|
|
88
88
|
memory: "10g"
|
|
89
89
|
- name: oss-standalone-1replica
|
|
90
90
|
type: oss-standalone
|
redis_benchmarks_specification/test-suites/memtier_benchmark-multiple-hll-pfcount-100B-values.yml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
version: 0.4
|
|
2
|
+
name: memtier_benchmark-multiple-hll-pfcount-100B-values
|
|
3
|
+
description: Runs memtier_benchmark, pre-loading multiple HyperLogLog keys with 100B sized random elements using PFADD, then testing PFCOUNT performance by counting these pre-loaded HLLs.
|
|
4
|
+
dbconfig:
|
|
5
|
+
configuration-parameters:
|
|
6
|
+
save: '""'
|
|
7
|
+
check:
|
|
8
|
+
keyspacelen: 3
|
|
9
|
+
preload_tool:
|
|
10
|
+
run_image: redislabs/memtier_benchmark:edge
|
|
11
|
+
tool: memtier_benchmark
|
|
12
|
+
arguments: '"--data-size" "100" --random-data --command "PFADD __key__ __data__" --command-key-pattern="P" --key-minimum=1 --key-maximum 3 -n 30000 -c 1 -t 1 --hide-histogram'
|
|
13
|
+
resources:
|
|
14
|
+
requests:
|
|
15
|
+
memory: 2g
|
|
16
|
+
tested-groups:
|
|
17
|
+
- hyperloglog
|
|
18
|
+
tested-commands:
|
|
19
|
+
- pfcount
|
|
20
|
+
redis-topologies:
|
|
21
|
+
- oss-standalone
|
|
22
|
+
build-variants:
|
|
23
|
+
- gcc:15.2.0-amd64-debian-bookworm-default
|
|
24
|
+
- gcc:15.2.0-arm64-debian-bookworm-default
|
|
25
|
+
- dockerhub
|
|
26
|
+
clientconfig:
|
|
27
|
+
run_image: redislabs/memtier_benchmark:edge
|
|
28
|
+
tool: memtier_benchmark
|
|
29
|
+
arguments: --test-time 60 --command "PFCOUNT memtier-1 memtier-2 memtier-3" -c 50 -t 4 --hide-histogram
|
|
30
|
+
resources:
|
|
31
|
+
requests:
|
|
32
|
+
cpus: '4'
|
|
33
|
+
memory: 2g
|
|
34
|
+
priority: 62
|