Skip to content

Commit ad690c3

Browse files
Extended HSET benchmarks to include larger field count (#272)
* Included LPOS benchmarks * Added LINDEX LINSERT and LREM benchmarks * Extended HSET benchmarks to include larger field count * Included 24.04 OS checks * SPEC fields validation fix
1 parent caebf3e commit ad690c3

17 files changed

+487
-27
lines changed

.github/workflows/tox.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111
strategy:
1212
matrix:
1313
python-version: [ '3.10', '3.11', '3.12' ]
14+
os: [ "ubuntu-latest", "ubuntu-24.04" ]
1415
fail-fast: false
1516
env:
1617
ACTIONS_ALLOW_UNSECURE_COMMANDS: true

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "redis-benchmarks-specification"
3-
version = "0.1.235"
3+
version = "0.1.240"
44
description = "The Redis benchmarks specification describes the cross-language/tools requirements and expectations to foster performance and observability standards around redis related technologies. Members from both industry and academia, including organizations and individuals are encouraged to contribute."
55
authors = ["filipecosta90 <[email protected]>","Redis Performance Group <[email protected]>"]
66
readme = "Readme.md"

redis_benchmarks_specification/__cli__/args.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#
66
import datetime
77
import os
8-
8+
from distutils.util import strtobool
99
from redis_benchmarks_specification.__common__.env import (
1010
GH_REDIS_SERVER_HOST,
1111
GH_TOKEN,
@@ -71,6 +71,12 @@ def spec_cli_args(parser):
7171
action="store_true",
7272
help="Include modules statistics on commandstats.",
7373
)
74+
parser.add_argument(
75+
"--use-git-timestamp",
76+
type=lambda x: bool(strtobool(x)),
77+
default=True,
78+
help="Use git timestamp",
79+
)
7480
parser.add_argument("--github_token", type=str, default=PERFORMANCE_GH_TOKEN)
7581
parser.add_argument("--pull-request", type=str, default=None, nargs="?", const="")
7682
parser.add_argument(

redis_benchmarks_specification/__cli__/cli.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,15 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
445445
git_branch = cdict["git_branch"]
446446
commit_datetime = cdict["commit_datetime"]
447447
commit_summary = cdict["commit_summary"]
448+
reply_fields = {}
449+
use_git_timestamp = args.use_git_timestamp
450+
if use_git_timestamp is False:
451+
reply_fields["use_git_timestamp"] = str(use_git_timestamp)
452+
453+
logging.info(
454+
f"Setting use use_git_timestamp={use_git_timestamp}. ({args.use_git_timestamp})"
455+
)
456+
448457
if result is True:
449458
stream_id = "n/a"
450459
if args.dry_run is False:
@@ -455,7 +464,7 @@ def trigger_tests_cli_command_logic(args, project_name, project_version):
455464
) = request_build_from_commit_info(
456465
conn,
457466
commit_dict,
458-
{},
467+
reply_fields,
459468
binary_key,
460469
binary_value,
461470
REDIS_BINS_EXPIRE_SECS,

redis_benchmarks_specification/__common__/github.py

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -107,32 +107,37 @@ def check_github_available_and_actionable(
107107
logging.info("Detected github token")
108108
g = Github(github_token)
109109
if pull_request is not None and pull_request != "":
110-
pull_request_n = int(pull_request)
111-
github_pr = (
112-
g.get_user(tf_github_org)
113-
.get_repo(tf_github_repo)
114-
.get_issue(pull_request_n)
115-
)
116-
comments = github_pr.get_comments()
117-
pr_link = github_pr.html_url
118-
logging.info("Working on github PR already: {}".format(pr_link))
119-
is_actionable_pr = True
120-
contains_regression_comment, pos = fn(comments)
121-
if contains_regression_comment:
122-
regression_comment = comments[pos]
123-
old_regression_comment_body = regression_comment.body
124-
logging.info(
125-
"Already contains PR comment. Link: {}".format(
126-
regression_comment.html_url
110+
try:
111+
pull_request_n = int(pull_request)
112+
github_pr = (
113+
g.get_user(tf_github_org)
114+
.get_repo(tf_github_repo)
115+
.get_issue(pull_request_n)
116+
)
117+
comments = github_pr.get_comments()
118+
pr_link = github_pr.html_url
119+
logging.info("Working on github PR already: {}".format(pr_link))
120+
is_actionable_pr = True
121+
contains_regression_comment, pos = fn(comments)
122+
if contains_regression_comment:
123+
regression_comment = comments[pos]
124+
old_regression_comment_body = regression_comment.body
125+
logging.info(
126+
"Already contains PR comment. Link: {}".format(
127+
regression_comment.html_url
128+
)
127129
)
130+
if verbose:
131+
logging.info("Printing old PR comment:")
132+
print("".join(["-" for x in range(1, 80)]))
133+
print(regression_comment.body)
134+
print("".join(["-" for x in range(1, 80)]))
135+
else:
136+
logging.info("Does not contain PR comment")
137+
except Exception as e:
138+
logging.error(
139+
f"an error occured when checking github info. {e.__str__()}. proceeding..."
128140
)
129-
if verbose:
130-
logging.info("Printing old PR comment:")
131-
print("".join(["-" for x in range(1, 80)]))
132-
print(regression_comment.body)
133-
print("".join(["-" for x in range(1, 80)]))
134-
else:
135-
logging.info("Does not contain PR comment")
136141
logging.info(
137142
f"contains_regression_comment: {contains_regression_comment}, is_actionable_pr: {is_actionable_pr}, pr_link: {pr_link}"
138143
)

redis_benchmarks_specification/__compare__/compare.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,10 @@ def compute_regression_table(
664664
total_comparison_points,
665665
regressions_list,
666666
improvements_list,
667+
unstable_list,
668+
baseline_only_list,
669+
comparison_only_list,
670+
no_datapoints_list,
667671
) = from_rts_to_regression_table(
668672
baseline_deployment_name,
669673
comparison_deployment_name,
@@ -708,6 +712,29 @@ def compute_regression_table(
708712
baseline_deployment_name,
709713
)
710714

715+
if total_unstable > 0:
716+
old_stdout = sys.stdout
717+
sys.stdout = mystdout = StringIO()
718+
table_output += "#### Unstable Table\n\n"
719+
writer_regressions = MarkdownTableWriter(
720+
table_name="",
721+
headers=[
722+
"Test Case",
723+
f"Baseline {baseline_github_org}/{baseline_github_repo} {baseline_str} (median obs. +- std.dev)",
724+
f"Comparison {comparison_github_org}/{comparison_github_repo} {comparison_str} (median obs. +- std.dev)",
725+
"% change ({})".format(metric_mode),
726+
"Note",
727+
],
728+
value_matrix=table_unstable,
729+
)
730+
writer_regressions.dump(mystdout, False)
731+
table_output += mystdout.getvalue()
732+
table_output += "\n\n"
733+
test_names_str = "|".join([l[0] for l in unstable_list])
734+
table_output += f"Unstable test regexp names: {test_names_str}\n\n"
735+
mystdout.close()
736+
sys.stdout = old_stdout
737+
711738
if total_regressions > 0:
712739
old_stdout = sys.stdout
713740
sys.stdout = mystdout = StringIO()
@@ -774,6 +801,27 @@ def compute_regression_table(
774801
sys.stdout = old_stdout
775802
table_output += mystdout.getvalue()
776803
table_output += "\n</details>\n"
804+
len_baseline_only_list = len(baseline_only_list)
805+
if len_baseline_only_list > 0:
806+
table_output += f"\n WARNING: There were {len_baseline_only_list} benchmarks with datapoints only on baseline.\n\n"
807+
baseline_only_test_names_str = "|".join([l[0] for l in baseline_only_list])
808+
table_output += (
809+
f" Baseline only test regexp names: {baseline_only_test_names_str}\n\n"
810+
)
811+
len_comparison_only_list = len(comparison_only_list)
812+
if len_comparison_only_list > 0:
813+
table_output += f"\n WARNING: There were {len_comparison_only_list} benchmarks with datapoints only on comparison.\n\n"
814+
comparison_only_test_names_str = "|".join([l[0] for l in comparison_only_list])
815+
table_output += (
816+
f" Comparison only test regexp names: {comparison_only_test_names_str}\n\n"
817+
)
818+
len_no_datapoints = len(no_datapoints_list)
819+
if len_no_datapoints > 0:
820+
table_output += f"\n WARNING: There were {len_no_datapoints} benchmarks with NO datapoints for both baseline and comparison.\n\n"
821+
no_datapoints_test_names_str = "|".join([l[0] for l in no_datapoints_list])
822+
table_output += (
823+
f" NO DATAPOINTS test regexp names: {no_datapoints_test_names_str}\n\n"
824+
)
777825

778826
return (
779827
detected_regressions,
@@ -967,6 +1015,10 @@ def from_rts_to_regression_table(
9671015
progress = tqdm(unit="benchmark time-series", total=len(test_names))
9681016
regressions_list = []
9691017
improvements_list = []
1018+
unstable_list = []
1019+
baseline_only_list = []
1020+
comparison_only_list = []
1021+
no_datapoints_list = []
9701022
for test_name in test_names:
9711023
compare_version = "main"
9721024
github_link = "https://github.com/redis/redis-benchmarks-specification/blob"
@@ -1110,6 +1162,17 @@ def from_rts_to_regression_table(
11101162
logging.error("Detected a ZeroDivisionError. {}".format(e.__str__()))
11111163
pass
11121164
unstable = False
1165+
1166+
if baseline_v != "N/A" and comparison_v == "N/A":
1167+
logging.warning(
1168+
"Baseline contains datapoints but comparison not for test: {test_name}"
1169+
)
1170+
baseline_only_list.append(test_name)
1171+
if comparison_v != "N/A" and baseline_v == "N/A":
1172+
logging.warning(
1173+
"Comparison contains datapoints but baseline not for test: {test_name}"
1174+
)
1175+
comparison_only_list.append(test_name)
11131176
if (
11141177
baseline_v != "N/A"
11151178
and comparison_pct_change != "N/A"
@@ -1119,6 +1182,7 @@ def from_rts_to_regression_table(
11191182
if comparison_pct_change > 10.0 or baseline_pct_change > 10.0:
11201183
note = "UNSTABLE (very high variance)"
11211184
unstable = True
1185+
unstable_list.append([test_name, "n/a"])
11221186

11231187
baseline_v_str = prepare_value_str(
11241188
baseline_pct_change, baseline_v, baseline_values, simplify_table
@@ -1212,6 +1276,21 @@ def from_rts_to_regression_table(
12121276
if should_add_line:
12131277
total_comparison_points = total_comparison_points + 1
12141278
table_full.append(line)
1279+
else:
1280+
logging.warning(
1281+
"There were no datapoints both for baseline and comparison for test: {test_name}"
1282+
)
1283+
no_datapoints_list.append(test_name)
1284+
logging.warning(
1285+
f"There is a total of {len(no_datapoints_list)} tests without datapoints for baseline AND comparison"
1286+
)
1287+
logging.info(
1288+
f"There is a total of {len(comparison_only_list)} tests without datapoints for baseline"
1289+
)
1290+
logging.info(
1291+
f"There is a total of {len(baseline_only_list)} tests without datapoints for comparison"
1292+
)
1293+
logging.info(f"There is a total of {len(unstable_list)} UNSTABLE tests")
12151294
return (
12161295
detected_regressions,
12171296
table_full,
@@ -1226,6 +1305,10 @@ def from_rts_to_regression_table(
12261305
total_comparison_points,
12271306
regressions_list,
12281307
improvements_list,
1308+
unstable_list,
1309+
baseline_only_list,
1310+
comparison_only_list,
1311+
no_datapoints_list,
12291312
)
12301313

12311314

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version: 0.4
2+
name: memtier_benchmark-100Kkeys-load-hash-50-fields-with-1000B-values
3+
description: Runs memtier_benchmark, for a keyspace length of 100K keys loading HASHES with 50 fields each. Each field value has a data size of 1000 Bytes.
4+
dbconfig:
5+
configuration-parameters:
6+
save: '""'
7+
check:
8+
keyspacelen: 0
9+
resources:
10+
requests:
11+
memory: 6g
12+
tested-groups:
13+
- hash
14+
tested-commands:
15+
- hset
16+
redis-topologies:
17+
- oss-standalone
18+
build-variants:
19+
- gcc:8.5.0-amd64-debian-buster-default
20+
- dockerhub
21+
clientconfig:
22+
run_image: redislabs/memtier_benchmark:edge
23+
tool: memtier_benchmark
24+
arguments: --test-time 120 --distinct-client-seed "--data-size" "1000" --command "HSET __key__ field:1 __data__ field:2 __data__ field:3 __data__ field:4 __data__ field:5 __data__ field:6 __data__ field:7 __data__ field:8 __data__ field:9 __data__ field:10 __data__ field:11 __data__ field:12 __data__ field:13 __data__ field:14 __data__ field:15 __data__ field:16 __data__ field:17 __data__ field:18 __data__ field:19 __data__ field:20 __data__ field:21 __data__ field:22 __data__ field:23 __data__ field:24 __data__ field:25 __data__ field:26 __data__ field:27 __data__ field:28 __data__ field:29 __data__ field:30 __data__ field:31 __data__ field:32 __data__ field:33 __data__ field:34 __data__ field:35 __data__ field:36 __data__ field:37 __data__ field:38 __data__ field:39 __data__ field:40 __data__ field:41 __data__ field:42 __data__ field:43 __data__ field:44 __data__ field:45 __data__ field:46 __data__ field:47 __data__ field:48 __data__ field:49 __data__ field:50 __data__" --command-key-pattern="R" --key-minimum=1 --key-maximum 100000 -c 50 -t 4 --hide-histogram
25+
resources:
26+
requests:
27+
cpus: '4'
28+
memory: 2g
29+
30+
priority: 5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version: 0.4
2+
name: memtier_benchmark-100Kkeys-load-hash-50-fields-with-100B-values
3+
description: Runs memtier_benchmark, for a keyspace length of 100K keys loading HASHES with 50 fields each. Each field value has a data size of 100 Bytes.
4+
dbconfig:
5+
configuration-parameters:
6+
save: '""'
7+
check:
8+
keyspacelen: 0
9+
resources:
10+
requests:
11+
memory: 6g
12+
tested-groups:
13+
- hash
14+
tested-commands:
15+
- hset
16+
redis-topologies:
17+
- oss-standalone
18+
build-variants:
19+
- gcc:8.5.0-amd64-debian-buster-default
20+
- dockerhub
21+
clientconfig:
22+
run_image: redislabs/memtier_benchmark:edge
23+
tool: memtier_benchmark
24+
arguments: --test-time 120 --distinct-client-seed "--data-size" "100" --command "HSET __key__ field:1 __data__ field:2 __data__ field:3 __data__ field:4 __data__ field:5 __data__ field:6 __data__ field:7 __data__ field:8 __data__ field:9 __data__ field:10 __data__ field:11 __data__ field:12 __data__ field:13 __data__ field:14 __data__ field:15 __data__ field:16 __data__ field:17 __data__ field:18 __data__ field:19 __data__ field:20 __data__ field:21 __data__ field:22 __data__ field:23 __data__ field:24 __data__ field:25 __data__ field:26 __data__ field:27 __data__ field:28 __data__ field:29 __data__ field:30 __data__ field:31 __data__ field:32 __data__ field:33 __data__ field:34 __data__ field:35 __data__ field:36 __data__ field:37 __data__ field:38 __data__ field:39 __data__ field:40 __data__ field:41 __data__ field:42 __data__ field:43 __data__ field:44 __data__ field:45 __data__ field:46 __data__ field:47 __data__ field:48 __data__ field:49 __data__ field:50 __data__" --command-key-pattern="R" --key-minimum=1 --key-maximum 100000 -c 50 -t 4 --hide-histogram
25+
resources:
26+
requests:
27+
cpus: '4'
28+
memory: 2g
29+
30+
priority: 5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version: 0.4
2+
name: memtier_benchmark-100Kkeys-load-hash-50-fields-with-10B-values
3+
description: Runs memtier_benchmark, for a keyspace length of 100K keys loading HASHES with 50 fields each. Each field value has a data size of 10 Bytes.
4+
dbconfig:
5+
configuration-parameters:
6+
save: '""'
7+
check:
8+
keyspacelen: 0
9+
resources:
10+
requests:
11+
memory: 6g
12+
tested-groups:
13+
- hash
14+
tested-commands:
15+
- hset
16+
redis-topologies:
17+
- oss-standalone
18+
build-variants:
19+
- gcc:8.5.0-amd64-debian-buster-default
20+
- dockerhub
21+
clientconfig:
22+
run_image: redislabs/memtier_benchmark:edge
23+
tool: memtier_benchmark
24+
arguments: --test-time 120 --distinct-client-seed "--data-size" "10" --command "HSET __key__ field:1 __data__ field:2 __data__ field:3 __data__ field:4 __data__ field:5 __data__ field:6 __data__ field:7 __data__ field:8 __data__ field:9 __data__ field:10 __data__ field:11 __data__ field:12 __data__ field:13 __data__ field:14 __data__ field:15 __data__ field:16 __data__ field:17 __data__ field:18 __data__ field:19 __data__ field:20 __data__ field:21 __data__ field:22 __data__ field:23 __data__ field:24 __data__ field:25 __data__ field:26 __data__ field:27 __data__ field:28 __data__ field:29 __data__ field:30 __data__ field:31 __data__ field:32 __data__ field:33 __data__ field:34 __data__ field:35 __data__ field:36 __data__ field:37 __data__ field:38 __data__ field:39 __data__ field:40 __data__ field:41 __data__ field:42 __data__ field:43 __data__ field:44 __data__ field:45 __data__ field:46 __data__ field:47 __data__ field:48 __data__ field:49 __data__ field:50 __data__" --command-key-pattern="R" --key-minimum=1 --key-maximum 100000 -c 50 -t 4 --hide-histogram
25+
resources:
26+
requests:
27+
cpus: '4'
28+
memory: 2g
29+
30+
priority: 5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version: 0.4
2+
name: memtier_benchmark-10Kkeys-load-hash-50-fields-with-10000B-values
3+
description: Runs memtier_benchmark, for a keyspace length of 100K keys loading HASHES with 50 fields each. Each field value has a data size of 1000 Bytes.
4+
dbconfig:
5+
configuration-parameters:
6+
save: '""'
7+
check:
8+
keyspacelen: 0
9+
resources:
10+
requests:
11+
memory: 6g
12+
tested-groups:
13+
- hash
14+
tested-commands:
15+
- hset
16+
redis-topologies:
17+
- oss-standalone
18+
build-variants:
19+
- gcc:8.5.0-amd64-debian-buster-default
20+
- dockerhub
21+
clientconfig:
22+
run_image: redislabs/memtier_benchmark:edge
23+
tool: memtier_benchmark
24+
arguments: --test-time 120 --distinct-client-seed "--data-size" "10000" --command "HSET __key__ field:1 __data__ field:2 __data__ field:3 __data__ field:4 __data__ field:5 __data__ field:6 __data__ field:7 __data__ field:8 __data__ field:9 __data__ field:10 __data__ field:11 __data__ field:12 __data__ field:13 __data__ field:14 __data__ field:15 __data__ field:16 __data__ field:17 __data__ field:18 __data__ field:19 __data__ field:20 __data__ field:21 __data__ field:22 __data__ field:23 __data__ field:24 __data__ field:25 __data__ field:26 __data__ field:27 __data__ field:28 __data__ field:29 __data__ field:30 __data__ field:31 __data__ field:32 __data__ field:33 __data__ field:34 __data__ field:35 __data__ field:36 __data__ field:37 __data__ field:38 __data__ field:39 __data__ field:40 __data__ field:41 __data__ field:42 __data__ field:43 __data__ field:44 __data__ field:45 __data__ field:46 __data__ field:47 __data__ field:48 __data__ field:49 __data__ field:50 __data__" --command-key-pattern="R" --key-minimum=1 --key-maximum 10000 -c 50 -t 4 --hide-histogram
25+
resources:
26+
requests:
27+
cpus: '4'
28+
memory: 2g
29+
30+
priority: 5

0 commit comments

Comments
 (0)