Skip to content

Commit 98b549e

Browse files
Add X-Pack Security benchmarks
Relates elastic#38
1 parent 19248da commit 98b549e

File tree

5 files changed

+206
-83
lines changed

5 files changed

+206
-83
lines changed

42.md

+13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ Our benchmark suite is maintained in a separate open source repo, called [rally-
2020

2121
We also document our [benchmarking methodology](https://elasticsearch-benchmarks.elastic.co/) publicly.
2222

23+
### How can I benchmark x-pack source builds?
24+
25+
As a general overview, please follow the [official Rally documentation on using Elasticsearch plugins](http://esrally.readthedocs.io/en/stable/elasticsearch_plugins.html). In order to benchmark source builds of x-pack, you need to add the following snippet to the `[source]` section of `~/.rally/rally.ini`:
26+
27+
```
28+
plugin.x-pack.remote.repo.url = [email protected]:elastic/x-pack-elasticsearch.git
29+
plugin.x-pack.src.subdir = elasticsearch-extra/x-pack-elasticsearch
30+
plugin.x-pack.build.task = :x-pack-elasticsearch:plugin:assemble
31+
plugin.x-pack.build.artifact.subdir = plugin/build/distributions
32+
```
33+
34+
To run a benchmark locally, run `esrally --revision="elasticsearch:some_revision,x-pack:some-other-revision" --elasticsearch-plugins="x-pack:security"`. See [Rally's command line reference](http://esrally.readthedocs.io/en/stable/command_line_reference.html#revision) on the correct format for the `--revision` command line parameter.
35+
2336
### What benchmark suites are available?
2437

2538
* The official benchmark suite of Rally, called [rally-tracks](https://github.com/elastic/rally-tracks) which is open-source.

night_rally.py

+116-50
Original file line numberDiff line numberDiff line change
@@ -99,33 +99,51 @@ def __init__(self, effective_start_date, target_host, root_dir):
9999
def report_path(self, track, challenge, car):
100100
return "%s/reports/rally/%s/%s/%s/%s/report.csv" % (self.root_dir, date_for_path(self.effective_start_date), track, challenge, car)
101101

102-
def runnable(self, track, challenge, car):
102+
def runnable(self, track, challenge, car, plugins):
103103
return True
104104

105-
def command_line(self, track, challenge, car):
105+
def command_line(self, track, challenge, car, plugins):
106106
raise NotImplementedError("abstract method")
107107

108108

109109
class SourceBasedCommand(BaseCommand):
110-
def __init__(self, effective_start_date, target_host, root_dir, revision, configuration_name, user_tag=None, override_src_dir=None):
110+
def __init__(self, effective_start_date, target_host, root_dir, revision, configuration_name, user_tag=None):
111111
super().__init__(effective_start_date, target_host, root_dir)
112112
self.revision = revision
113113
self.configuration_name = configuration_name
114114
self.pipeline = "from-sources-complete"
115-
if override_src_dir is not None:
116-
self.override = " --override-src-dir=%s" % override_src_dir
117-
else:
118-
self.override = ""
115+
self.pipeline_with_plugins = "from-sources-complete"
119116
if user_tag:
120117
self.user_tag = " --user-tag=\"intention:%s\"" % user_tag
121118
else:
122119
self.user_tag = ""
123120

124-
def command_line(self, track, challenge, car):
125-
cmd = "{11} --configuration-name={9} --target-host={8} --pipeline={6} --quiet --revision \"{0}\" " \
126-
"--effective-start-date \"{1}\" --track={2} --challenge={3} --car={4} --report-format=csv --report-file={5}{7}{10}". \
127-
format(self.revision, self.ts, track, challenge, car, self.report_path(track, challenge, car), self.pipeline, self.override,
128-
self.target_host, self.configuration_name, self.user_tag, RALLY_BINARY)
121+
def command_line(self, track, challenge, car, plugins):
122+
cmd = RALLY_BINARY
123+
cmd += " --configuration-name=%s" % self.configuration_name
124+
cmd += " --target-host=%s" % self.target_host
125+
# force a build if plugins are involved because we do not know whether we've build these plugins before
126+
if plugins:
127+
cmd += " --pipeline=%s" % self.pipeline_with_plugins
128+
else:
129+
cmd += " --pipeline=%s" % self.pipeline
130+
#cmd += " --quiet"
131+
cmd += " --revision \"%s\"" % self.revision
132+
cmd += " --effective-start-date \"%s\"" % self.effective_start_date
133+
cmd += " --track=%s" % track
134+
cmd += " --challenge=%s" % challenge
135+
cmd += " --car=%s" % car
136+
cmd += " --report-format=csv"
137+
cmd += " --report-file=%s" % self.report_path(track, challenge, car)
138+
cmd += self.user_tag
139+
140+
if plugins:
141+
self.pipeline_with_plugins = "from-sources-skip-build"
142+
cmd += " --elasticsearch-plugins=\"%s\"" % plugins
143+
if "x-pack:security" in plugins:
144+
cmd += " --cluster-health=yellow"
145+
cmd += " --client-options=\"use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'\""
146+
129147
# after we've executed the first benchmark, there is no reason to build again from sources
130148
self.pipeline = "from-sources-skip-build"
131149
return cmd
@@ -134,14 +152,14 @@ def command_line(self, track, challenge, car):
134152
class NightlyCommand(SourceBasedCommand):
135153
CONFIG_NAME = "nightly"
136154

137-
def __init__(self, effective_start_date, target_host, root_dir, override_src_dir=None):
155+
def __init__(self, effective_start_date, target_host, root_dir):
138156
super().__init__(effective_start_date, target_host, root_dir, "@%s" % to_iso8601(effective_start_date),
139-
NightlyCommand.CONFIG_NAME, user_tag=None, override_src_dir=override_src_dir)
157+
NightlyCommand.CONFIG_NAME, user_tag=None)
140158

141159

142160
class AdHocCommand(SourceBasedCommand):
143-
def __init__(self, revision, effective_start_date, target_host, root_dir, configuration_name, user_tag, override_src_dir=None):
144-
super().__init__(effective_start_date, target_host, root_dir, revision, configuration_name, user_tag, override_src_dir)
161+
def __init__(self, revision, effective_start_date, target_host, root_dir, configuration_name, user_tag):
162+
super().__init__(effective_start_date, target_host, root_dir, revision, configuration_name, user_tag)
145163

146164

147165
class ReleaseCommand(BaseCommand):
@@ -153,26 +171,38 @@ def __init__(self, effective_start_date, target_host, plugins, root_dir, distrib
153171
self.distribution_version = distribution_version
154172
self._tag = tag
155173

156-
def runnable(self, track, challenge, car):
174+
def runnable(self, track, challenge, car, plugins):
157175
# Do not run 1g benchmarks at all at the moment. Earlier versions of ES OOM.
158176
if car == "1gheap":
159177
return False
178+
# Do not run plugin-specific tracks. We run either the whole suite with or without plugins.
179+
if plugins != "":
180+
return False
160181
# cannot run "sorted" challenges - it's a 6.0+ feature
161182
if int(self.distribution_version[0]) < 6:
162183
return "sorted" not in challenge
163184
return True
164185

165-
def command_line(self, track, challenge, car):
166-
cmd = "{10} --configuration-name={8} --target-host={7} --pipeline={6} --quiet --distribution-version={0} " \
167-
"--effective-start-date \"{1}\" --track={2} --challenge={3} --car={4} --report-format=csv --report-file={5} " \
168-
"--user-tag=\"{9}\"".format(self.distribution_version, self.ts, track, challenge, car,
169-
self.report_path(track, challenge, car), self.pipeline,
170-
self.target_host, self.configuration_name, self.tag(), RALLY_BINARY)
171-
if self.plugins:
172-
cmd += " --elasticsearch-plugins=\"%s\"" % self.plugins
173-
if "x-pack:security" in self.plugins:
174-
cmd += " --cluster-health=yellow " \
175-
"--client-options=\"use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'\""
186+
def command_line(self, track, challenge, car, plugins):
187+
cmd = RALLY_BINARY
188+
cmd += " --configuration-name=%s" % self.configuration_name
189+
cmd += " --target-host=%s" % self.target_host
190+
cmd += " --pipeline=%s" % self.pipeline
191+
cmd += " --quiet"
192+
cmd += " --distribution-version=%s" % self.distribution_version
193+
cmd += " --effective-start-date \"%s\"" % self.effective_start_date
194+
cmd += " --track=%s" % track
195+
cmd += " --challenge=%s" % challenge
196+
cmd += " --car=%s" % car
197+
cmd += " --report-format=csv"
198+
cmd += " --report-file=%s" % self.report_path(track, challenge, car)
199+
cmd += " --user-tag=\"%s\"" % self.tag()
200+
201+
if plugins:
202+
cmd += " --elasticsearch-plugins=\"%s\"" % plugins
203+
if "x-pack:security" in plugins:
204+
cmd += " --cluster-health=yellow"
205+
cmd += "--client-options=\"use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'\""
176206

177207
return cmd
178208

@@ -187,20 +217,33 @@ def __init__(self, effective_start_date, target_host, root_dir, distribution_ver
187217
self.pipeline = "docker"
188218
self.distribution_version = distribution_version
189219

190-
def runnable(self, track, challenge, car):
220+
def runnable(self, track, challenge, car, plugins):
191221
if car in ["two_nodes", "verbose_iw", "1gheap"]:
192222
return False
223+
# no plugin installs on Docker
224+
if plugins != "":
225+
return False
193226
# cannot run "sorted" challenges - it's a 6.0+ feature
194227
if int(self.distribution_version[0]) < 6:
195228
return "sorted" not in challenge
196229
return True
197230

198-
def command_line(self, track, challenge, car):
199-
cmd = "{10} --configuration-name={8} --target-host={7} --pipeline={6} --quiet --distribution-version={0} " \
200-
"--effective-start-date \"{1}\" --track={2} --challenge={3} --car={4} --report-format=csv --report-file={5} " \
201-
"--cluster-health=yellow --user-tag=\"{9}\"". \
202-
format(self.distribution_version, self.ts, track, challenge, car, self.report_path(track, challenge, car), self.pipeline,
203-
self.target_host, self.configuration_name, self.tag(), RALLY_BINARY)
231+
def command_line(self, track, challenge, car, plugins):
232+
cmd = RALLY_BINARY
233+
cmd += " --configuration-name=%s" % self.configuration_name
234+
cmd += " --target-host=%s" % self.target_host
235+
cmd += " --pipeline=%s" % self.pipeline
236+
cmd += " --quiet"
237+
cmd += " --distribution-version=%s" % self.distribution_version
238+
cmd += " --effective-start-date \"%s\"" % self.effective_start_date
239+
cmd += " --track=%s" % track
240+
cmd += " --challenge=%s" % challenge
241+
cmd += " --car=%s" % car
242+
cmd += " --report-format=csv"
243+
cmd += " --report-file=%s" % self.report_path(track, challenge, car)
244+
cmd += " --user-tag=\"%s\"" % self.tag()
245+
# due to the possibility that x-pack is active (that depends on Rally)
246+
cmd += " --cluster-health=yellow"
204247
return cmd
205248

206249
@staticmethod
@@ -219,20 +262,28 @@ def run_rally(tracks, command, dry_run=False, system=os.system):
219262
for combination in track["combinations"]:
220263
challenge = combination["challenge"]
221264
car = combination["car"]
222-
if command.runnable(track_name, challenge, car):
223-
logger.info("Running Rally on track [%s] with challenge [%s] and car [%s]" % (track_name, challenge, car))
265+
plugins = combination.get("plugins", "")
266+
info = race_info(track_name, challenge, car, plugins)
267+
if command.runnable(track_name, challenge, car, plugins):
268+
logger.info("Running Rally on %s" % info)
224269
start = time.perf_counter()
225-
if runner(command.command_line(track_name, challenge, car)):
270+
if runner(command.command_line(track_name, challenge, car, plugins)):
226271
rally_failure = True
227-
logger.error("Failed to run track [%s]. Please check the logs." % track_name)
272+
logger.error("Failed to run %s. Please check the logs." % info)
228273
stop = time.perf_counter()
229-
logger.info("Finished running on track [%s] with challenge [%s] and car [%s] in [%f] seconds." % (
230-
track_name, challenge, car, (stop - start)))
274+
logger.info("Finished running on %s in [%f] seconds." % (info, (stop - start)))
231275
else:
232-
logger.info("Skipping track [%s], challenge [%s] and car [%s] (not supported by command)." % (track_name, challenge, car))
276+
logger.info("Skipping %s (not supported by command)." % info)
233277
return rally_failure
234278

235279

280+
def race_info(track, challenge, car, plugins):
281+
if plugins:
282+
return "track [%s] with challenge [%s], car [%s] and plugins [%s]" % (track, challenge, car, plugins)
283+
else:
284+
return "track [%s] with challenge [%s] and car [%s]" % (track, challenge, car)
285+
286+
236287
#################################################
237288
# Reporting
238289
#################################################
@@ -247,10 +298,29 @@ def copy_results_for_release_comparison(effective_start_date, dry_run, tag):
247298
es = client.create_client()
248299
es.indices.refresh(index="rally-results-*")
249300
ts = to_iso8601_short(effective_start_date)
301+
# find all of today's results but exclude "x-pack" ones because we will not have release charts for them (x-pack has
302+
# their own dedicated trial runs on releases)
250303
query = {
251304
"query": {
252-
"term": {
253-
"trial-timestamp": ts
305+
"bool": {
306+
"must": [
307+
{
308+
"term": {
309+
"trial-timestamp": {
310+
"value": ts
311+
}
312+
}
313+
}
314+
],
315+
"must_not": [
316+
{
317+
"term": {
318+
"plugins": {
319+
"value": "x-pack"
320+
}
321+
}
322+
}
323+
]
254324
}
255325
}
256326
}
@@ -347,10 +417,6 @@ def parse_args():
347417
"trial runs",
348418
required=True,
349419
type=lambda s: datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S"))
350-
parser.add_argument(
351-
"--override-src-dir",
352-
help=argparse.SUPPRESS,
353-
default=None)
354420
parser.add_argument(
355421
"--tag",
356422
help=argparse.SUPPRESS,
@@ -440,13 +506,13 @@ def main():
440506
logger.info("Running adhoc benchmarks for revision [%s] against [%s]." % (args.revision, args.target_host))
441507
# copy data from templates directory to our dedicated output directory
442508
env_name = sanitize(args.release)
443-
command = AdHocCommand(args.revision, start_date, args.target_host, root_dir, env_name, args.tag, args.override_src_dir)
509+
command = AdHocCommand(args.revision, start_date, args.target_host, root_dir, env_name, args.tag)
444510
else:
445511
if plugins:
446512
raise RuntimeError("User specified plugins [%s] but this is not supported for nightly benchmarks." % plugins)
447513
logger.info("Running nightly benchmarks against [%s]." % args.target_host)
448514
env_name = NightlyCommand.CONFIG_NAME
449-
command = NightlyCommand(start_date, args.target_host, root_dir, args.override_src_dir)
515+
command = NightlyCommand(start_date, args.target_host, root_dir)
450516

451517
configure_rally(env_name, args.dry_run)
452518
rally_failure = run_rally(tracks, command, args.dry_run)

night_rally.sh

+33-30
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ ANSIBLE_SKIP_TAGS_STRING=""
3535
SELF_UPDATE=NO
3636
DRY_RUN=NO
3737
SKIP_S3=NO
38+
SKIP_ANSIBLE=NO
3839
# We invoke Rally with the current (UTC) timestamp. This determines the version to checkout.
3940
START_DATE=`date -u "+%Y-%m-%d %H:%M:%S"`
4041
MODE="nightly"
@@ -49,6 +50,7 @@ PLUGINS=""
4950
for i in "$@"
5051
do
5152
case ${i} in
53+
# TODO: Remove this option, it is not recognized by Rally anymore
5254
--override-src-dir=*)
5355
OVERRIDE_SRC_DIR="${i#*=}"
5456
shift # past argument=value
@@ -65,6 +67,10 @@ case ${i} in
6567
DRY_RUN=YES
6668
shift # past argument with no value
6769
;;
70+
--skip-ansible)
71+
SKIP_ANSIBLE=YES
72+
shift # past argument with no value
73+
;;
6874
--skip-s3)
6975
SKIP_S3=YES
7076
shift # past argument with no value
@@ -121,40 +127,37 @@ then
121127
popd >/dev/null 2>&1
122128
fi
123129

124-
############### TO BE CONVERTED TO A FUNCTION ###################
125-
for fixture in "${ANSIBLE_ALL_TAGS[@]}"
126-
do
127-
if [[ $FIXTURES != *$fixture* ]] ; then
128-
ANSIBLE_SKIP_TAGS+=("$fixture")
129-
fi
130-
done
131-
132-
if [[ ${#ANSIBLE_SKIP_TAGS[@]} == 0 ]]; then
133-
ANSIBLE_SKIP_TAGS_STRING=""
134-
else
135-
# join tags with a comma (,) character
136-
ANSIBLE_SKIP_TAGS_STRING=$(printf ",%s" "${ANSIBLE_SKIP_TAGS[@]}")
137-
ANSIBLE_SKIP_TAGS_STRING=${ANSIBLE_SKIP_TAGS_STRING:1}
138-
ANSIBLE_SKIP_TAGS_STRING="--skip-tags $ANSIBLE_SKIP_TAGS_STRING"
139-
fi
140-
141-
echo "About to run ansible-playbook ... with '$ANSIBLE_SKIP_TAGS_STRING'"
142-
if [ ${DRY_RUN} == NO ]
130+
if [ ${SKIP_ANSIBLE} == NO ]
143131
then
144-
pushd . >/dev/null 2>&1
132+
for fixture in "${ANSIBLE_ALL_TAGS[@]}"
133+
do
134+
if [[ $FIXTURES != *$fixture* ]] ; then
135+
ANSIBLE_SKIP_TAGS+=("$fixture")
136+
fi
137+
done
138+
139+
if [[ ${#ANSIBLE_SKIP_TAGS[@]} == 0 ]]; then
140+
ANSIBLE_SKIP_TAGS_STRING=""
141+
else
142+
# join tags with a comma (,) character
143+
ANSIBLE_SKIP_TAGS_STRING=$(printf ",%s" "${ANSIBLE_SKIP_TAGS[@]}")
144+
ANSIBLE_SKIP_TAGS_STRING=${ANSIBLE_SKIP_TAGS_STRING:1}
145+
ANSIBLE_SKIP_TAGS_STRING="--skip-tags $ANSIBLE_SKIP_TAGS_STRING"
146+
fi
145147

146-
cd ${NIGHT_RALLY_HOME}/fixtures/ansible
147-
ansible-playbook -i inventory/production -u rally playbooks/update-rally.yml
148-
ansible-playbook -i inventory/production -u rally playbooks/setup.yml ${ANSIBLE_SKIP_TAGS_STRING}
148+
echo "About to run ansible-playbook ... with '$ANSIBLE_SKIP_TAGS_STRING'"
149+
if [ ${DRY_RUN} == NO ]
150+
then
151+
pushd . >/dev/null 2>&1
149152

150-
popd >/dev/null 2>&1
151-
fi
153+
cd ${NIGHT_RALLY_HOME}/fixtures/ansible
154+
ansible-playbook -i inventory/production -u rally playbooks/update-rally.yml
155+
ansible-playbook -i inventory/production -u rally playbooks/setup.yml ${ANSIBLE_SKIP_TAGS_STRING}
152156

153-
if [ -n "${OVERRIDE_SRC_DIR}" ]
154-
then
155-
NIGHT_RALLY_OVERRIDE="--override-src-dir=${OVERRIDE_SRC_DIR}"
157+
popd >/dev/null 2>&1
158+
fi
156159
else
157-
NIGHT_RALLY_OVERRIDE=""
160+
echo "Skipping Ansible execution."
158161
fi
159162

160163
if [ ${DRY_RUN} == YES ]
@@ -169,7 +172,7 @@ fi
169172
#****************************
170173
set +e
171174
# Avoid failing before we transferred all results. Usually only a single benchmark trial run fails but lots of other succeed.
172-
python3 ${NIGHT_RALLY_HOME}/night_rally.py --target-host=${TARGET_HOST} --elasticsearch-plugins="${PLUGINS}" --effective-start-date="${START_DATE}" ${NIGHT_RALLY_OVERRIDE} --mode=${MODE} ${NIGHT_RALLY_DRY_RUN} --fixtures="${FIXTURES}" --revision="${REVISION}" --release="${RELEASE}" --tag="${TAG}"
175+
python3 ${NIGHT_RALLY_HOME}/night_rally.py --target-host=${TARGET_HOST} --elasticsearch-plugins="${PLUGINS}" --effective-start-date="${START_DATE}" --mode=${MODE} ${NIGHT_RALLY_DRY_RUN} --fixtures="${FIXTURES}" --revision="${REVISION}" --release="${RELEASE}" --tag="${TAG}"
173176
exit_code=$?
174177

175178
echo "Killing any lingering Rally processes"

0 commit comments

Comments
 (0)