1 <?xml version='1.0' encoding='UTF-8'?>
2 <chapter xmlns="http://docbook.org/ns/docbook"
3 xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en-US"
4 xml:id="benchmarkingtests">
5 <title xml:id="benchmarkingtests.title">Benchmarking Lustre File System Performance (Lustre I/O
7 <para>This chapter describes the Lustre I/O kit, a collection of I/O
8 benchmarking tools for a Lustre cluster. It includes:</para>
11 <para><xref linkend="benchmark.iokit"/></para>
14 <para><xref linkend="benchmark.sgpdd-survey"/></para>
17 <para><xref linkend="benchmark.ost_perf"/></para>
20 <para><xref linkend="benchmark.ost_io"/></para>
23 <para><xref linkend="benchmark.mds_survey_ref"/></para>
26 <para><xref linkend="benchmark.stats-collect"/></para>
29 <section xml:id="benchmark.iokit">
32 <primary>benchmarking</primary>
33 <secondary>with Lustre I/O Kit</secondary>
35 <indexterm><primary>profiling</primary><see>benchmarking</see></indexterm>
36 <indexterm><primary>tuning</primary><see>benchmarking</see></indexterm>
38 <primary>performance</primary><see>benchmarking</see>
40 Using Lustre I/O Kit Tools</title>
41 <para>The tools in the Lustre I/O Kit are used to benchmark Lustre file
42 system hardware and validate that it is working as expected before you
43 install the Lustre software. It can also be used to to validate the
44 performance of the various hardware and software layers in the cluster and
45 also to find and troubleshoot I/O issues.</para>
46 <para>Typically, performance is measured starting with single raw devices
47 and then proceeding to groups of devices. Once raw performance has been
48 established, other software layers are then added incrementally and tested.
51 <title>Contents of the Lustre I/O Kit</title>
52 <para>The I/O kit contains three tests, each of which tests a
53 progressively higher layer in the Lustre software stack:</para>
56 <para><literal>sgpdd-survey</literal> - Measure basic
57 'bare metal' performance of devices while bypassing the
58 kernel block device layers, buffer cache, and file system.</para>
61 <para><literal>obdfilter-survey</literal> - Measure the performance of
62 one or more OSTs directly on the OSS node or alternately over the
63 network from a Lustre client.</para>
66 <para><literal>ost-survey</literal> - Performs I/O against OSTs
67 individually to allow performance comparisons to detect if an OST is
68 performing sub-optimally due to hardware issues.</para>
71 <para>Typically with these tests, a Lustre file system should deliver
72 85-90% of the raw device performance.</para>
73 <para>A utility <literal>stats-collect</literal> is also provided to
74 collect application profiling information from Lustre clients and servers.
75 See <xref linkend="benchmark.stats-collect"/> for more information.</para>
78 <title>Preparing to Use the Lustre I/O Kit</title>
79 <para>The following prerequisites must be met to use the tests in the
80 Lustre I/O kit:</para>
83 <para>Password-free remote access to nodes in the system (provided by
84 <literal>ssh</literal> or <literal>rsh</literal>).</para>
87 <para>LNet self-test completed to test that Lustre networking has been
88 properly installed and configured. See <xref linkend="lnetselftest"/>.
92 <para>Lustre file system software installed.</para>
95 <para><literal>sg3_utils</literal> package providing the
96 <literal>sgp_dd</literal> tool (<literal>sg3_utils</literal> is a
97 separate RPM package available online using YUM).</para>
100 <para>Download the Lustre I/O kit (<literal>lustre-iokit</literal>)from:
103 <link xl:href="https://downloads.whamcloud.com/">https://downloads.whamcloud.com/</link>
107 <section xml:id="benchmark.sgpdd-survey">
109 <primary>benchmarking</primary>
110 <secondary>raw hardware with sgpdd-survey</secondary></indexterm>
111 Testing I/O Performance of Raw Hardware (<literal>sgpdd-survey</literal>)
113 <para>The <literal>sgpdd-survey</literal> tool is used to test bare metal
114 I/O performance of the raw hardware, while bypassing as much of the kernel
115 as possible. This survey may be used to characterize the performance of a
116 SCSI device by simulating an OST serving multiple stripe files. The data
117 gathered by this survey can help set expectations for the performance of a
118 Lustre OST using this device.</para>
119 <para>The script uses <literal>sgp_dd</literal> to carry out raw sequential
120 disk I/O. It runs with variable numbers of <literal>sgp_dd</literal> threads
121 to show how performance varies with different request queue depths.</para>
122 <para>The script spawns variable numbers of <literal>sgp_dd</literal>
123 instances, each reading or writing a separate area of the disk to
124 demonstrate performance variance within a number of concurrent stripe files.
126 <para>Several tips and insights for disk performance measurement are
127 described below. Some of this information is specific to RAID arrays and/or
128 the Linux RAID implementation.</para>
131 <para><emphasis>Performance is limited by the slowest disk.</emphasis>
133 <para>Before creating a RAID array, benchmark all disks individually.
134 We have frequently encountered situations where drive performance was
135 not consistent for all devices in the array. Replace any disks that are
136 significantly slower than the rest.</para>
140 <emphasis>Disks and arrays are very sensitive to request size.
143 <para>To identify the optimal request size for a given disk, benchmark
144 the disk with different record sizes ranging from 4 KB to 1 to 2 MB.
149 <para>The <literal>sgpdd-survey</literal> script overwrites the device
150 being tested, which results in the <emphasis><emphasis role="bold">
151 LOSS OF ALL DATA</emphasis></emphasis> on that device. Exercise caution
152 when selecting the device to be tested.</para>
155 <para>Array performance with all LUNs loaded does not always match the
156 performance of a single LUN when tested in isolation.</para>
158 <para><emphasis role="bold">Prerequisites:</emphasis></para>
161 <para><literal>sgp_dd</literal> tool in the <literal>sg3_utils</literal>
165 <para>Lustre software is <emphasis>NOT</emphasis> required</para>
168 <para>The device(s) being tested must meet one of these two requirements:
172 <para>If the device is a SCSI device, it must appear in the output of
173 <literal>sg_map</literal> (make sure the kernel module
174 <literal>sg</literal> is loaded).</para>
177 <para>If the device is a raw device, it must appear in the output of
178 <literal>raw -qa</literal>.</para>
181 <para>Raw and SCSI devices cannot be mixed in the test specification.</para>
183 <para>If you need to create raw devices to use the
184 <literal>sgpdd-survey</literal> tool, note that raw device 0 cannot be
185 used due to a bug in certain versions of the "raw" utility
186 (including the version shipped with Red Hat Enterprise Linux 4U4.)</para>
189 <title><indexterm><primary>benchmarking</primary>
190 <secondary>tuning storage</secondary></indexterm>
191 Tuning Linux Storage Devices</title>
192 <para>To get large I/O transfers (1 MB) to disk, it may be necessary to
193 tune several kernel parameters as specified:</para>
194 <screen>/sys/block/sdN/queue/max_sectors_kb = 4096
195 /sys/block/sdN/queue/max_phys_segments = 256
196 /proc/scsi/sg/allow_dio = 1
197 /sys/module/ib_srp/parameters/srp_sg_tablesize = 255
198 /sys/block/sdN/queue/scheduler</screen>
200 <para>Recommended schedulers are <emphasis role="bold">deadline
201 </emphasis> and <emphasis role="bold">noop</emphasis>. The scheduler is
202 set by default to <emphasis role="bold">deadline</emphasis>, unless it
203 has already been set to <emphasis role="bold">noop</emphasis>.</para>
207 <title>Running sgpdd-survey</title>
208 <para>The <literal>sgpdd-survey</literal> script must be customized for
209 the particular device being tested and for the location where the script
210 saves its working and result files (by specifying the
211 <literal>${rslt}</literal> variable). Customization variables are
212 described at the beginning of the script.</para>
213 <para>When the <literal>sgpdd-survey</literal> script runs, it creates a
214 number of working files and a pair of result files. The names of all the
215 files created start with the prefix defined in the variable
216 <literal>${rslt}</literal>. (The default value is <literal>/tmp</literal>.
217 ) The files include:</para>
220 <para>File containing standard output data (same as
221 <literal>stdout</literal>)</para>
222 <screen><replaceable>rslt_date_time</replaceable>.summary</screen>
225 <para>Temporary (tmp) files</para>
226 <screen><replaceable>rslt_date_time</replaceable>_*</screen>
229 <para>Collected tmp files for post-mortem</para>
230 <screen><replaceable>rslt_date_time</replaceable>.detail</screen>
233 <para>The <literal>stdout</literal> and the <literal>.summary</literal>
234 file will contain lines like this:</para>
235 <screen>total_size 8388608K rsz 1024 thr 1 crg 1 180.45 MB/s 1 x 180.50 \
236 = 180.50 MB/s</screen>
237 <para>Each line corresponds to a run of the test. Each test run will have
238 a different number of threads, record size, or number of regions.</para>
241 <para><literal>total_size</literal> - Size of file being tested in
242 KBs (8 GB in above example).</para>
245 <para><literal>rsz</literal> - Record size in KBs (1 MB in above
249 <para><literal>thr</literal> - Number of threads generating I/O (1
250 thread in above example).</para>
253 <para><literal>crg</literal> - Current regions, the number of
254 disjoint areas on the disk to which I/O is being sent (1 region in
255 above example, indicating that no seeking is done).</para>
258 <para><literal>MB/s</literal> - Aggregate bandwidth measured by
259 dividing the total amount of data by the elapsed time (180.45 MB/s in
260 the above example).</para>
263 <para><literal>MB/s</literal> - The remaining numbers show the number
264 of regions X performance of the slowest disk as a sanity check on the
265 aggregate bandwidth.</para>
268 <para>If there are so many threads that the <literal>sgp_dd</literal>
269 script is unlikely to be able to allocate I/O buffers, then
270 <literal>ENOMEM</literal> is printed in place of the aggregate bandwidth
272 <para>If one or more <literal>sgp_dd</literal> instances do not
273 successfully report a bandwidth number, then <literal>FAILED</literal>
274 is printed in place of the aggregate bandwidth result.</para>
277 <section xml:id="benchmark.ost_perf">
279 <primary>benchmarking</primary>
280 <secondary>OST performance</secondary>
281 </indexterm>Testing OST Performance (<literal>obdfilter-survey</literal>)
283 <para>The <literal>obdfilter-survey</literal> script generates sequential
284 I/O from varying numbers of threads and objects (files) to simulate the I/O
285 patterns of a Lustre client.</para>
286 <para>The <literal>obdfilter-survey</literal> script can be run directly on
287 the OSS node to measure the OST storage performance without any intervening
288 network, or it can be run remotely on a Lustre client to measure the OST
289 performance including network overhead.</para>
290 <para>The <literal>obdfilter-survey</literal> is used to characterize the
291 performance of the following:</para>
294 <para><emphasis role="bold">Local file system</emphasis> - In this mode,
295 the <literal>obdfilter-survey</literal> script exercises one or more
296 instances of the obdfilter directly. The script may run on one or more
297 OSS nodes, for example, when the OSSs are all attached to the same
298 multi-ported disk subsystem.</para>
299 <para>Run the script using the <literal>case=disk</literal> parameter to
300 run the test against all the local OSTs. The script automatically
301 detects all local OSTs and includes them in the survey.</para>
302 <para>To run the test against only specific OSTs, run the script using
303 the <literal>targets=parameter</literal> to list the OSTs to be tested
304 explicitly. If some OSTs are on remote nodes, specify their hostnames in
305 addition to the OST name (for example,
306 <literal>oss2:lustre-OST0004</literal>).</para>
307 <para>All <literal>obdfilter</literal> instances are driven directly.
308 The script automatically loads the <literal>obdecho</literal> module (if
309 required) and creates one instance of <literal>echo_client</literal> for
310 each <literal>obdfilter</literal> instance in order to generate I/O
311 requests directly to the OST.</para>
312 <para>For more details, see <xref linkend="dbdoclet.50438212_59319"/>.
316 <para><emphasis role="bold">Network</emphasis> - In this mode, the
317 Lustre client generates I/O requests over the network but these requests
318 are not sent to the OST file system. The OSS node runs the obdecho
319 server to receive the requests but discards them before they are sent to
321 <para>Pass the parameters <literal>case=network</literal> and
322 <literal>targets=<replaceable>hostname|IP_of_server</replaceable>
323 </literal> to the script. For each network case, the script does the
324 required setup.</para>
325 <para>For more details, see <xref linkend="benchmark.network"/>
329 <para><emphasis role="bold">Remote file system over the network
330 </emphasis> - In this mode the <literal>obdfilter-survey</literal>
331 script generates I/O from a Lustre client to a remote OSS to write the
332 data to the file system.</para>
333 <para>To run the test against all the local OSCs, pass the parameter
334 <literal>case=netdisk</literal> to the script. Alternately you can pass
335 the target= parameter with one or more OSC devices (e.g.,
336 <literal>lustre-OST0000-osc-ffff88007754bc00</literal>) against which
337 the tests are to be run.</para>
338 <para>For more details, see <xref linkend="benchmark.remote_disk"/>.
343 <para>The <literal>obdfilter-survey</literal> script is potentially
344 destructive and there is a small risk data may be lost. To reduce this
345 risk, <literal>obdfilter-survey</literal> should not be run on devices
346 that contain data that needs to be preserved. Thus, the best time to run
347 <literal>obdfilter-survey</literal> is before the Lustre file system is
348 put into production. The reason <literal>obdfilter-survey</literal> may be
349 safe to run on a production file system is because it creates objects with
350 object sequence 2. Normal file system objects are typically created with
351 object sequence 0.</para>
354 <para>If the <literal>obdfilter-survey</literal> test is terminated before
355 it completes, some small amount of space is leaked. you can either ignore
356 it or reformat the file system.</para>
359 <para>The <literal>obdfilter-survey</literal> script is
360 <emphasis>NOT</emphasis> scalable beyond tens of OSTs since it is only
361 intended to measure the I/O performance of individual storage subsystems,
362 not the scalability of the entire system.</para>
365 <para>The <literal>obdfilter-survey</literal> script must be customized,
366 depending on the components under test and where the script's working
367 files should be kept. Customization variables are described at the
368 beginning of the <literal>obdfilter-survey</literal> script. In
369 particular, pay attention to the listed maximum values listed for each
370 parameter in the script.</para>
372 <section xml:id="dbdoclet.50438212_59319">
373 <title><indexterm><primary>benchmarking</primary>
374 <secondary>local disk</secondary></indexterm>
375 Testing Local Disk Performance</title>
376 <para>The <literal>obdfilter-survey</literal> script can be run
377 automatically or manually against a local disk. This script profiles the
378 overall throughput of storage hardware, including the file system and RAID
379 layers managing the storage, by sending workloads to the OSTs that vary in
380 thread count, object count, and I/O size.</para>
381 <para>When the <literal>obdfilter-survey</literal> script is run, it
382 provides information about the performance abilities of the storage
383 hardware and shows the saturation points.</para>
384 <para>The <literal>plot-obdfilter</literal> script generates from the
385 output of the <literal>obdfilter-survey</literal> a CSV file and
386 parameters for importing into a spreadsheet or gnuplot to visualize the
388 <para>To run the <literal>obdfilter-survey</literal> script, create a
389 standard Lustre file system configuration; no special setup is needed.
391 <para><emphasis role="bold">To perform an automatic run:</emphasis></para>
394 <para>Start the Lustre OSTs.</para>
395 <para>The Lustre OSTs should be mounted on the OSS node(s) to be
396 tested. The Lustre client is not required to be mounted at this time.
400 <para>Verify that the obdecho module is loaded. Run:</para>
401 <screen>modprobe obdecho</screen>
404 <para>Run the <literal>obdfilter-survey</literal> script with the
405 parameter <literal>case=disk</literal>.</para>
406 <para>For example, to run a local test with up to two objects
407 (nobjhi), up to two threads (thrhi), and 1024 MB transfer size (size):
409 <screen>$ nobjhi=2 thrhi=2 size=1024 case=disk sh obdfilter-survey</screen>
412 <para>Performance measurements for write, rewrite, read etc are
413 provided below:</para>
414 <screen># example output
415 Fri Sep 25 11:14:03 EDT 2015 Obdfilter-survey for case=disk from hds1fnb6123
416 ost 10 sz 167772160K rsz 1024K obj 10 thr 10 write 10982.73 [ 601.97,2912.91] rewrite 15696.54 [1160.92,3450.85] read 12358.60 [ 938.96,2634.87]
419 <literal>./lustre-iokit/obdfilter-survey/README.obdfilter-survey
420 </literal>provides an explaination for the output as follows:</para>
421 <screen>ost 10 is the total number of OSTs under test.
422 sz 167772160K is the total amount of data read or written (in bytes).
423 rsz 1024K is the record size (size of each echo_client I/O, in bytes).
424 obj 10 is the total number of objects over all OSTs
425 thr 10 is the total number of threads over all OSTs and objects
426 write is the test name. If more tests have been specified they
427 all appear on the same line.
428 10982.73 is the aggregate bandwidth over all OSTs measured by
429 dividing the total number of MB by the elapsed time.
430 [601.97,2912.91] are the minimum and maximum instantaneous bandwidths seen on
432 Note that although the numbers of threads and objects are specifed per-OST
433 in the customization section of the script, results are reported aggregated
434 over all OSTs.</screen>
437 <para><emphasis role="italic">To perform a manual run:</emphasis></para>
440 <para>Start the Lustre OSTs.</para>
441 <para>The Lustre OSTs should be mounted on the OSS node(s) to be
442 tested. The Lustre client is not required to be mounted at this time.
446 <para>Verify that the <literal>obdecho</literal> module is loaded.
448 <screen>modprobe obdecho</screen>
451 <para>Determine the OST names.</para>
452 <para>On the OSS nodes to be tested, run the
453 <literal>lctl dl</literal> command. The OST device names are listed in
454 the fourth column of the output. For example:</para>
455 <screen>$ lctl dl |grep obdfilter
456 0 UP obdfilter lustre-OST0001 lustre-OST0001_UUID 1159
457 2 UP obdfilter lustre-OST0002 lustre-OST0002_UUID 1159
461 <para>List all OSTs you want to test.</para>
462 <para>Use the <literal>targets=parameter</literal> to list the OSTs
463 separated by spaces. List the individual OSTs by name using the format
465 <replaceable>fsname</replaceable>-<replaceable>OSTnumber</replaceable>
466 </literal> (for example, <literal>lustre-OST0001</literal>). You do
467 not have to specify an MDS or LOV.</para>
470 <para>Run the <literal>obdfilter-survey</literal> script with the
471 <literal>targets=parameter</literal>.</para>
472 <para>For example, to run a local test with up to two objects
473 (<literal>nobjhi</literal>), up to two threads (
474 <literal>thrhi</literal>), and 1024 Mb (size) transfer size:</para>
475 <screen>$ nobjhi=2 thrhi=2 size=1024 targets="lustre-OST0001 \
476 lustre-OST0002" sh obdfilter-survey</screen>
480 <section xml:id="benchmark.network">
481 <title><indexterm><primary>benchmarking</primary>
482 <secondary>network</secondary></indexterm>
483 Testing Network Performance</title>
484 <para>The <literal>obdfilter-survey</literal> script can only be run
485 automatically against a network; no manual test is provided.</para>
486 <para>To run the network test, a specific Lustre file system setup is
487 needed. Make sure that these configuration requirements have been met.
489 <para><emphasis role="bold">To perform an automatic run:</emphasis></para>
492 <para>Start the Lustre OSTs.</para>
493 <para>The Lustre OSTs should be mounted on the OSS node(s) to be
494 tested. The Lustre client is not required to be mounted at this time.
498 <para>Verify that the <literal>obdecho</literal> module is loaded.
500 <screen>modprobe obdecho</screen>
503 <para>Start <literal>lctl</literal> and check the device list, which
504 must be empty. Run:</para>
505 <screen>lctl dl</screen>
508 <para>Run the <literal>obdfilter-survey</literal> script with the
509 parameters <literal>case=network</literal> and
510 <literal>targets=<replaceable>hostname|ip_of_server</replaceable>
511 </literal>. For example:</para>
512 <screen>$ nobjhi=2 thrhi=2 size=1024 targets="oss0 oss1" \
513 case=network sh obdfilter-survey</screen>
516 <para>On the server side, view the statistics at:</para>
517 <screen>lctl get_param obdecho.<replaceable>echo_srv</replaceable>.stats</screen>
518 <para>where <literal><replaceable>echo_srv</replaceable></literal>
519 is the <literal>obdecho</literal> server created by the script.</para>
523 <section xml:id="benchmark.remote_disk">
524 <title><indexterm><primary>benchmarking</primary>
525 <secondary>remote disk</secondary></indexterm>
526 Testing Remote Disk Performance</title>
527 <para>The <literal>obdfilter-survey</literal> script can be run
528 automatically or manually against a network disk. To run the network disk
529 test, start with a standard Lustre configuration. No special setup is
531 <para><emphasis role="bold">To perform an automatic run:</emphasis></para>
534 <para>Start the Lustre OSTs.</para>
535 <para>The Lustre OSTs should be mounted on the OSS node(s) to be
536 tested. The Lustre client is not required to be mounted at this time.
540 <para>Verify that the <literal>obdecho</literal> module is loaded.
542 <screen>modprobe obdecho</screen>
545 <para>Run the <literal>obdfilter-survey</literal> script with the
546 parameter <literal>case=netdisk</literal>. For example:</para>
547 <screen>$ nobjhi=2 thrhi=2 size=1024 case=netdisk sh obdfilter-survey
551 <para><emphasis role="bold">To perform a manual run:</emphasis></para>
554 <para>Start the Lustre OSTs.</para>
555 <para>The Lustre OSTs should be mounted on the OSS node(s) to be
556 tested. The Lustre client is not required to be mounted at this time.
560 <para>Verify that the <literal>obdecho</literal> module is loaded.
562 <para>modprobe obdecho</para>
565 <para>Determine the OSC names.</para>
566 <para>On the OSS nodes to be tested, run the
567 <literal>lctl dl</literal> command. The OSC device names are listed in
568 the fourth column of the output. For example:</para>
569 <screen>$ lctl dl |grep obdfilter
570 3 UP osc lustre-OST0000-osc-ffff88007754bc00 \
571 54b91eab-0ea9-1516-b571-5e6df349592e 5
572 4 UP osc lustre-OST0001-osc-ffff88007754bc00 \
573 54b91eab-0ea9-1516-b571-5e6df349592e 5
578 <para>List all OSCs you want to test.</para>
579 <para>Use the <literal>targets=parameter</literal> to list the OSCs
580 separated by spaces. List the individual OSCs by name separated by
581 spaces using the format <literal>
582 <replaceable>fsname</replaceable>-<replaceable>OST_name</replaceable>-osc-<replaceable>instance</replaceable>
583 </literal> (for example,
584 <literal>lustre-OST0000-osc-ffff88007754bc00</literal>). You
585 <emphasis>do not have to specify an MDS or LOV.</emphasis></para>
588 <para>Run the <literal>obdfilter-survey</literal> script with the
589 <literal>targets=<replaceable>osc</replaceable></literal> and
590 <literal>case=netdisk</literal>.</para>
591 <para>An example of a local test run with up to two objects
592 (<literal>nobjhi</literal>), up to two threads
593 (<literal>thrhi</literal>), and 1024 Mb (size) transfer size is shown
595 <screen>$ nobjhi=2 thrhi=2 size=1024 \
596 targets="lustre-OST0000-osc-ffff88007754bc00 \
597 lustre-OST0001-osc-ffff88007754bc00" sh obdfilter-survey</screen>
602 <title>Output Files</title>
603 <para>When the <literal>obdfilter-survey</literal> script runs, it creates
604 a number of working files and a pair of result files. All files start with
605 the prefix defined in the variable <literal>${rslt}</literal>.</para>
606 <informaltable frame="all">
608 <colspec colname="c1" colwidth="50*"/>
609 <colspec colname="c2" colwidth="50*"/>
613 <para><emphasis role="bold">File</emphasis></para>
616 <para><emphasis role="bold">Description</emphasis></para>
623 <para> <literal>${rslt}.summary</literal></para>
626 <para> Same as stdout</para>
631 <para> <literal>${rslt}.script_*</literal></para>
634 <para> Per-host test script files</para>
639 <para> <literal>${rslt}.detail_tmp*</literal></para>
642 <para> Per-OST result files</para>
647 <para> <literal>${rslt}.detail</literal></para>
650 <para> Collected result files for post-mortem</para>
656 <para>The <literal>obdfilter-survey</literal> script iterates over the
657 given number of threads and objects performing the specified tests and
658 checks that all test processes have completed successfully.</para>
660 <para>The <literal>obdfilter-survey</literal> script may not clean up
661 properly if it is aborted or if it encounters an unrecoverable error. In
662 this case, a manual cleanup may be required, possibly including killing
663 any running instances of <literal>lctl</literal> (local or remote),
664 removing <literal>echo_client</literal> instances created by the script
665 and unloading <literal>obdecho</literal>.</para>
668 <title>Script Output</title>
669 <para>The <literal>.summary</literal> file and <literal>stdout</literal>
670 of the <literal>obdfilter-survey</literal> script contain lines like:
672 <screen>ost 8 sz 67108864K rsz 1024 obj 8 thr 8 write 613.54 [ 64.00, 82.00]</screen>
674 <informaltable frame="all">
676 <colspec colname="c1" colwidth="50*"/>
677 <colspec colname="c2" colwidth="50*"/>
681 <para><emphasis role="bold">Parameter and value</emphasis>
685 <para><emphasis role="bold">Description</emphasis></para>
695 <para> Total number of OSTs being tested.</para>
700 <para> sz 67108864K</para>
703 <para> Total amount of data read or written (in KB).</para>
708 <para> rsz 1024</para>
711 <para> Record size (size of each echo_client I/O, in KB).
720 <para> Total number of objects over all OSTs.</para>
728 <para> Total number of threads over all OSTs and objects.
737 <para> Test name. If more tests have been specified, they all
738 appear on the same line.</para>
746 <para> Aggregate bandwidth over all OSTs (measured by dividing
747 the total number of MB by the elapsed time).</para>
752 <para> [64, 82.00]</para>
755 <para> Minimum and maximum instantaneous bandwidths on an
756 individual OST.</para>
763 <para>Although the numbers of threads and objects are specified
764 per-OST in the customization section of the script, the reported
765 results are aggregated over all OSTs.</para>
769 <title>Visualizing Results</title>
770 <para>It is useful to import the <literal>obdfilter-survey</literal>
771 script summary data (it is fixed width) into Excel (or any graphing
772 package) and graph the bandwidth versus the number of threads for
773 varying numbers of concurrent regions. This shows how the OSS performs
774 for a given number of concurrently-accessed objects (files) with varying
775 numbers of I/Os in flight.</para>
776 <para>It is also useful to monitor and record average disk I/O sizes
777 during each test using the 'disk io size' histogram in the
778 file <literal>lctl get_param obdfilter.*.brw_stats</literal>
779 (see <xref linkend="dbdoclet.50438271_55057"/> for details). These
780 numbers help identify problems in the system when full-sized I/Os are
781 not submitted to the underlying disk. This may be caused by problems in
782 the device driver or Linux block layer.</para>
783 <para>The <literal>plot-obdfilter</literal> script included in the I/O
784 toolkit is an example of processing output files to a .csv format and
785 plotting a graph using <literal>gnuplot</literal>.</para>
789 <section xml:id="benchmark.ost_io">
791 <primary>benchmarking</primary>
792 <secondary>OST I/O</secondary></indexterm>
793 Testing OST I/O Performance (<literal>ost-survey</literal>)</title>
794 <para>The <literal>ost-survey</literal> tool is a shell script that uses
795 <literal>lfs setstripe</literal> to perform I/O against a single OST. The
796 script writes a file (currently using <literal>dd</literal>) to each OST
797 in the Lustre file system, and compares read and write speeds. The
798 <literal>ost-survey</literal> tool is used to detect anomalies between
799 otherwise identical disk subsystems.</para>
801 <para>We have frequently discovered wide performance variations across
802 all LUNs in a cluster. This may be caused by faulty disks, RAID parity
803 reconstruction during the test, or faulty network hardware.</para>
805 <para>To run the <literal>ost-survey</literal> script, supply a file size
806 (in KB) and the Lustre file system mount point. For example, run:</para>
807 <screen>$ ./ost-survey.sh -s 10 /mnt/lustre</screen>
808 <para>Typical output is:</para>
810 Number of Active OST devices : 4
811 Worst Read OST indx: 2 speed: 2835.272725
812 Best Read OST indx: 3 speed: 2872.889668
813 Read Average: 2852.508999 +/- 16.444792 MB/s
814 Worst Write OST indx: 3 speed: 17.705545
815 Best Write OST indx: 2 speed: 128.172576
816 Write Average: 95.437735 +/- 45.518117 MB/s
817 Ost# Read(MB/s) Write(MB/s) Read-time Write-time
818 ----------------------------------------------------
819 0 2837.440 126.918 0.035 0.788
820 1 2864.433 108.954 0.035 0.918
821 2 2835.273 128.173 0.035 0.780
822 3 2872.890 17.706 0.035 5.648</screen>
824 <section xml:id="benchmark.mds_survey_ref">
825 <title><indexterm><primary>benchmarking</primary>
826 <secondary>MDS performance</secondary></indexterm>
827 Testing MDS Performance (<literal>mds-survey</literal>)</title>
828 <para>The <literal>mds-survey</literal> script tests the local
829 metadata performance using the <literal>echo_client</literal> to
830 drive the MDD layer of the MDS stack.
831 It can be used with the following classes of operations:</para>
834 <para><literal>Open-create/mkdir/create</literal></para>
837 <para><literal>Lookup/getattr/setxattr</literal></para>
840 <para><literal>Delete/destroy</literal></para>
843 <para><literal>Unlink/rmdir</literal></para>
846 <para>These operations will be run by a variable number of concurrent
847 threads and will test with the number of directories specified by the user.
848 The run can be executed such that all threads operate in a single directory
849 (dir_count=1) or in private/unique directory (dir_count=x thrlo=x thrhi=x).
851 <para>The mdd instance is driven directly. The script automatically loads
852 the obdecho module if required and creates instance of echo_client.</para>
853 <para>This script can also create OST objects by providing stripe_count
854 greater than zero.</para>
855 <para><emphasis role="bold">To perform a run:</emphasis></para>
858 <para>Start the Lustre MDT.</para>
859 <para>The Lustre MDT should be mounted on the MDS node to be tested.
863 <para>Start the Lustre OSTs (optional, only required when test with
865 <para>The Lustre OSTs should be mounted on the OSS node(s).</para>
868 <para>Run the <literal>mds-survey</literal> script as explain below
870 <para>The script must be customized according to the components under
871 test and where it should keep its working files. Customization
872 variables are described as followed:</para>
875 <para><literal>thrlo</literal> - threads to start testing. skipped
876 if less than <literal>dir_count</literal></para>
879 <para><literal>thrhi</literal> - maximum number of threads to test
883 <para><literal>targets</literal> - MDT instance</para>
886 <para><literal>file_count</literal> - number of files per thread
890 <para><literal>dir_count</literal> - total number of directories
891 to test. Must be less than or equal to <literal>thrhi</literal>
895 <para><literal>stripe_count </literal>- number stripe on OST
899 <para><literal>tests_str</literal> - test operations. Must have at
900 least "create" and "destroy"</para>
903 <para><literal>start_number</literal> - base number for each
904 thread to prevent name collisions</para>
907 <para><literal>layer</literal> - MDS stack's layer to be tested
911 <para>Run without OST objects creation:</para>
912 <para>Setup the Lustre MDS without OST mounted. Then invoke the
913 <literal>mds-survey</literal> script</para>
914 <screen>$ thrhi=64 file_count=200000 sh mds-survey</screen>
915 <para>Run with OST objects creation:</para>
916 <para>Setup the Lustre MDS with at least one OST mounted. Then invoke
917 the <literal>mds-survey</literal> script with
918 <literal>stripe_count</literal> parameter</para>
919 <screen>$ thrhi=64 file_count=200000 stripe_count=2 sh mds-survey</screen>
920 <para>Note: a specific MDT instance can be specified using targets
922 <screen>$ targets=lustre-MDT0000 thrhi=64 file_count=200000 stripe_count=2 sh mds-survey</screen>
926 <title>Output Files</title>
927 <para>When the <literal>mds-survey</literal> script runs, it creates a
928 number of working files and a pair of result files. All files start with
929 the prefix defined in the variable <literal>${rslt}</literal>.</para>
930 <informaltable frame="all">
932 <colspec colname="c1" colwidth="50*"/>
933 <colspec colname="c2" colwidth="50*"/>
937 <para><emphasis role="bold">File</emphasis></para>
940 <para><emphasis role="bold">Description</emphasis></para>
947 <para> <literal>${rslt}.summary</literal></para>
950 <para> Same as stdout</para>
955 <para> <literal>${rslt}.script_*</literal></para>
958 <para> Per-host test script files</para>
963 <para> <literal>${rslt}.detail_tmp*</literal></para>
966 <para> Per-mdt result files</para>
971 <para> <literal>${rslt}.detail</literal></para>
974 <para> Collected result files for post-mortem</para>
980 <para>The <literal>mds-survey</literal> script iterates over the given
981 number of threads performing the specified tests and checks that all test
982 processes have completed successfully.</para>
984 <para>The <literal>mds-survey</literal> script may not clean up properly
985 if it is aborted or if it encounters an unrecoverable error. In this
986 case, a manual cleanup may be required, possibly including killing any
987 running instances of <literal>lctl</literal>, removing
988 <literal>echo_client</literal> instances created by the script and
989 unloading <literal>obdecho</literal>.</para>
993 <title>Script Output</title>
994 <para>The <literal>.summary</literal> file and <literal>stdout</literal>
995 of the <literal>mds-survey</literal> script contain lines like:</para>
996 <screen>mdt 1 file 100000 dir 4 thr 4 create 5652.05 [ 999.01,46940.48] destroy 5797.79 [ 0.00,52951.55] </screen>
998 <informaltable frame="all">
1000 <colspec colname="c1" colwidth="50*"/>
1001 <colspec colname="c2" colwidth="50*"/>
1005 <para><emphasis role="bold">Parameter and value</emphasis></para>
1008 <para><emphasis role="bold">Description</emphasis></para>
1018 <para>Total number of MDT under test</para>
1023 <para>file 100000</para>
1026 <para>Total number of files per thread to operate</para>
1034 <para>Total number of directories to operate</para>
1042 <para>Total number of threads operate over all directories
1048 <para>create, destroy</para>
1051 <para>Tests name. More tests will be displayed on the same line.
1060 <para>Aggregate operations over MDT measured by dividing the
1061 total number of operations by the elapsed time.</para>
1066 <para>[999.01,46940.48]</para>
1069 <para>Minimum and maximum instantaneous operation seen on any
1070 individual MDT</para>
1077 <para>If script output has "ERROR", this usually means there is issue
1078 during the run such as running out of space on the MDT and/or OST.
1079 More detailed debug information is available in the ${rslt}.detail
1084 <section xml:id="benchmark.stats-collect">
1085 <title><indexterm><primary>benchmarking</primary>
1086 <secondary>application profiling</secondary></indexterm>
1087 Collecting Application Profiling Information (
1088 <literal>stats-collect</literal>)</title>
1089 <para>The <literal>stats-collect</literal> utility contains the following
1090 scripts used to collect application profiling information from Lustre
1091 clients and servers:</para>
1094 <para><literal>lstat.sh</literal> - Script for a single node that is
1095 run on each profile node.</para>
1098 <para><literal>gather_stats_everywhere.sh</literal> - Script that
1099 collect statistics.</para>
1102 <para><literal>config.sh</literal> - Script that contains customized
1103 configuration descriptions.</para>
1106 <para>The <literal>stats-collect</literal> utility requires:</para>
1109 <para>Lustre software to be installed and set up on your cluster</para>
1112 <para>SSH and SCP access to these nodes without requiring a password</para>
1115 <section remap="h3">
1116 <title>Using <literal>stats-collect</literal></title>
1117 <para>The stats-collect utility is configured by including profiling
1118 configuration variables in the config.sh script. Each configuration
1119 variable takes the following form, where 0 indicates statistics are to be
1120 collected only when the script starts and stops and <emphasis>n</emphasis>
1121 indicates the interval in seconds at which statistics are to be collected:
1123 <screen><replaceable>statistic</replaceable>_INTERVAL=<replaceable>0|n</replaceable></screen>
1124 <para>Statistics that can be collected include:</para>
1127 <para><literal>VMSTAT</literal> - Memory and CPU usage and aggregate
1128 read/write operations</para>
1131 <para><literal>SERVICE</literal> - Lustre OST and MDT RPC service
1135 <para><literal>BRW</literal> - OST bulk read/write statistics
1139 <para><literal>SDIO</literal> - SCSI disk IO statistics (sd_iostats)
1143 <para><literal>MBALLOC</literal> - <literal>ldiskfs</literal> block
1144 allocation statistics</para>
1147 <para><literal>IO</literal> - Lustre target operations statistics
1151 <para><literal>JBD</literal> - ldiskfs journal statistics</para>
1154 <para><literal>CLIENT</literal> - Lustre OSC request statistics
1158 <para>To collect profile information:</para>
1159 <para>Begin collecting statistics on each node specified in the config.sh
1163 <para>Starting the collect profile daemon on each node by entering:
1165 <screen>sh gather_stats_everywhere.sh config.sh start </screen>
1168 <para>Run the test.</para>
1171 <para>Stop collecting statistics on each node, clean up the temporary
1172 file, and create a profiling tarball.</para>
1174 <screen>sh gather_stats_everywhere.sh config.sh stop <replaceable>log_name</replaceable>.tgz</screen>
1175 <para>When <literal><replaceable>log_name</replaceable>.tgz</literal>
1176 is specified, a profile tarball
1177 <literal><replaceable>/tmp/log_name</replaceable>.tgz</literal> is
1181 <para>Analyze the collected statistics and create a csv tarball for
1182 the specified profiling data.</para>
1183 <screen>sh gather_stats_everywhere.sh config.sh analyse log_tarball.tgz csv</screen>
1190 vim:expandtab:shiftwidth=2:tabstop=8: