From 6a64e7da6e962405d2d590ac375805e3cf5afdce Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 15 Apr 2025 17:39:09 +0100 Subject: [PATCH 1/7] initial commit for LP --- .../disk-io-benchmark/_index.md | 40 ++++++ .../disk-io-benchmark/_next-steps.md | 8 ++ .../characterising-workload.md | 131 +++++++++++++++++ .../disk-io-benchmark/diskio.jpeg | Bin 0 -> 31998 bytes .../disk-io-benchmark/introduction.md | 50 +++++++ .../disk-io-benchmark/using-fio.md | 134 ++++++++++++++++++ 6 files changed, 363 insertions(+) create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_next-steps.md create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/diskio.jpeg create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md new file mode 100644 index 0000000000..5a19949afa --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md @@ -0,0 +1,40 @@ +--- +title: Benchmark Storage I/O Performance with Fio + +minutes_to_complete: 30 + +who_is_this_for: A cloud developer who wants to optimise storage cost or performance of their application. Developers who want to uncover potential storage-bound bottlenecks or changes when migrating an application to a different platform. + +learning_objectives: + - Understand basic data flow for storage devices + - Understand how to run the fio microbenchmark + +prerequisites: + - Access to an Arm-based server + - Basic understanding of Linux + +author: Kieran Hejmadi + +### Tags +skilllevels: Introductory +subjects: Runbook, Performance and Architecture +armips: + - Neoverse +tools_software_languages: + - bash +operatingsystems: + - Linux + + +further_reading: + - resource: + title: Fio documentation + link: https://fio.readthedocs.io/en/latest/fio_doc.html#running-fio + type: documentation + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md new file mode 100644 index 0000000000..a0ad33e8cb --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md @@ -0,0 +1,131 @@ +--- +title: Characterising a Workload +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Characterising your Workload + +The basic attributes of a given workload are the following. + +- IOPS +- I/O Size +- Throughput +- Read to Write Ratio +- Random vs Sequential access + +The characteristics of many real-world workloads will vary over time, for example an application that periodically flushes writes to disk. Further, the system-wide and process-specific characteristics may be significantly differently. + +## Example Workload + +Connect to an Arm-based cloud instance. As an example workload, we will be using the media manipulation tool, FFMPEG on an AWS `t4g.medium` instance, using the default block storage options provided by AWS. + + +```bash +sudo apt update +sudo apt install ffmpeg iotop -y +``` + +Download the popular example video, `BigBuckBunny.mp4` to demonstrate a transcoding workload. + +```bash +wget http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 +``` + +Run the following command to begin transcoding the video and audio using the `H.264` and `aac` transcoders respectively. We use the `-flush_packets` flag to write each chunk of video back to storage. + +```bash +ffmpeg -i BigBuckBunny.mp4 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k -flush_packets 1 output_video.mp4 +``` +Whilst the transcoding is running, we can use the `pidstat` command to see the disk statistics. + +```bash +pidstat -d -p $(pgrep ffmpeg) 1 +``` +From the table below, we can observe this process is predominantly writing to disk at ~`300 kB/s`. + +```output +Linux 6.8.0-1024-aws (ip-10-248-213-118) 04/15/25 _aarch64_ (2 CPU) + +10:01:24 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command +10:01:25 1000 24250 0.00 276.00 0.00 0 ffmpeg +10:01:26 1000 24250 0.00 256.00 0.00 0 ffmpeg +10:01:27 1000 24250 0.00 216.00 0.00 0 ffmpeg +10:01:28 1000 24250 0.00 184.00 0.00 0 ffmpeg +10:01:29 1000 24250 0.00 424.00 0.00 0 ffmpeg +10:01:30 1000 24250 0.00 312.00 0.00 0 ffmpeg +10:01:31 1000 24250 0.00 372.00 0.00 0 ffmpeg +10:01:32 1000 24250 0.00 344.00 0.00 0 ffmpeg +``` + +Since this example `151MB` video fits within memory, we observe no `kB_rd/s` for the storage device. However, since we are flushing to storage we observe ~275 `kB_wr/s` for this specific process. + +We can use iotop to confirm that our `ffmpeg` process has the greatest disk utilisation. + +```bash +sudo iotop +``` + +```output +Total DISK READ: 0.00 B/s | Total DISK WRITE: 332.11 K/s +Current DISK READ: 0.00 B/s | Current DISK WRITE: 0.00 B/s + TID PRIO USER DISK READ DISK WRITE> COMMAND + 24891 be/4 ubuntu 0.00 B/s 332.11 K/s ffmpeg -i BigBuckBunny.mp4 -c:v ~ts 1 output_video.mp4 [mux0:mp4] + 1 be/4 root 0.00 B/s 0.00 B/s systemd --system --deserialize=74 + 2 be/4 root 0.00 B/s 0.00 B/s [kthreadd] +``` + +Using the input, output statistics command (`iostat`) we can observe the system-wide metrics from the `nvme0n1` drive. Please Note that we are using a snapshot of this workload, more accurate characteristics can be obtained by measuring the distribution of a workload. + +```bash +watch -n 0.1 iostat -z nvme0n1 +``` +You should see output similar to that below. + +```output +Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd +nvme0n1 3.81 31.63 217.08 0.00 831846 5709210 0 +``` + +The following characteristics are calculated as follows. + +1. IOPS + +**Value:** 3.81 +_This is taken directly from the `tps` (transfers per second) field._ + +2. Throughput + +**Read:** 31.63 kB/s +**Write:** 217.08 kB/s +**Total:** 248.71 kB/s +_Sum of read and write throughput values._ + +3. Average I/O Size + +**Value:** ≈ 65.3 KB +_Calculated as total throughput divided by IOPS: 248.71 / 3.81._ + + +4. Read/Write Ratio + +**Read:** ~13% +**Write:** ~87% +_Computed as: (read or write throughput) ÷ total throughput._ + +Finally, to the access pattern of our workload (i.e. random vs. sequential) is slightly more complicated. We can infer the locality of our accesses through our understanding of the program, the cache hit rate (for reads), and merge rate on the dispatch side. Metrics that show high degree of merging, cache hits and low wait times suggest that our accesses are sequential in nature. + +Running the following command. + +```bash +iostat -xz nvme0n1 +``` + +```output +Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util +nvme0n1 0.66 29.64 0.24 26.27 0.73 44.80 2.92 203.88 3.17 52.01 2.16 69.70 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.15 +``` + +The `wrqm/s` column is the number of write requests merged per second before being issued. Calculated the percentage or writes merged compared to writes is one indicator of how sequental the data accesses are. diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/diskio.jpeg b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/diskio.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..cd21b646545b67714ab40a69c37953c639ee2423 GIT binary patch literal 31998 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 tvP|ZGM}Fy# Date: Wed, 16 Apr 2025 11:38:21 +0100 Subject: [PATCH 2/7] added workload characteristics --- .../disk-io-benchmark/EBS.png | Bin 0 -> 118494 bytes .../disk-io-benchmark/_index.md | 2 +- .../characterising-workload.md | 4 +- .../disk-io-benchmark/introduction.md | 3 +- .../disk-io-benchmark/using-fio.md | 131 +++++++++++------- 5 files changed, 83 insertions(+), 57 deletions(-) create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/EBS.png diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/EBS.png b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/EBS.png new file mode 100644 index 0000000000000000000000000000000000000000..13f8422e2efb743370f6a140411a4601c75ecfdc GIT binary patch literal 118494 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®m{o_aH$^aE1 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 literal 0 HcmV?d00001 diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md index 5a19949afa..42d40167ae 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md @@ -1,5 +1,5 @@ --- -title: Benchmark Storage I/O Performance with Fio +title: Microbenchmark Storage Performance with Fio minutes_to_complete: 30 diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md index a0ad33e8cb..6b2d6986fb 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md @@ -20,7 +20,9 @@ The characteristics of many real-world workloads will vary over time, for exampl ## Example Workload -Connect to an Arm-based cloud instance. As an example workload, we will be using the media manipulation tool, FFMPEG on an AWS `t4g.medium` instance, using the default block storage options provided by AWS. +Connect to an Arm-based cloud instance. As an example workload, we will be using the media manipulation tool, FFMPEG on an AWS `t4g.medium` instance, with 2 Elastic Block Storage (EBS) volumes as per the image below. + +![ebs](./EBS.png) ```bash diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md index 3530320db3..5944de1bc4 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md @@ -46,5 +46,4 @@ In benchmarking tools like fio, you might select I/O engines such as sync (synch ### Typical Storage Types for Cloud Instances -Instance storage = volatile, lost when instance is stopped -Block storage = e.g., El \ No newline at end of file +In a cloud environment, you are typically sharing a physical instance of a server with multiple tenants. As such the CPU cores and storage devices may be shared. As such, cloud service providers often provide an IOPS per GB. Where your system's storage performance is proportional to the block device size. See [this example](https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/blockvolumeperformance.htm) for more information. \ No newline at end of file diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md index d1428238b9..64dca8dff7 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md @@ -6,7 +6,7 @@ weight: 4 layout: learningpathall --- -## Simulating Workload with FIO +## Install Fio Flexible I/O (fio) is a command-line tool to generate a synthetic workload with specific I/O characteristics. @@ -29,106 +29,131 @@ fio-3.36 gnuplot 6.0 patchlevel 0 ``` - -## Best Practices for Microbenchmarking - -Software which you did not write or has been less extensively tested will have bugs. Be aware of some of the known [bug tracker](https://github.com/axboe/fio/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug). - -List any assumptions you have, for example, there are no chron jobs running at the time, that the storage media has an on-disk cache, the storage device has the latest stable firmware, temperatures are nominal. - ## Locate Device -Use the disk free, `df` command to see the mounted storage devices connected to your server. We are excluding the temporary file system, `tmpfs` for clarity. +We have the option to directly microbenchmark the block device or microbenchmark a mounted filesystem. Use the disk free, `df` command to see if the mounted storage devices connected to your server. We are excluding the temporary file system, `tmpfs` for clarity. ```bash df -hTx tmpfs ``` -As we can see the storage we configured through the AWS console is at `/dev/root` with 30GB available. **Please Note** using the incorrect filesystem name can cause issues. +The output below shows a 30GB ```output Filesystem Type Size Used Avail Use% Mounted on -/dev/root ext4 30G 2.2G 28G 8% / -efivarfs efivarfs 128K 3.1K 125K 3% /sys/firmware/efi/efivars +Filesystem Type Size Used Avail Use% Mounted on +/dev/root ext4 6.8G 2.8G 4.0G 41% / +efivarfs efivarfs 128K 3.7K 125K 3% /sys/firmware/efi/efivars /dev/nvme0n1p16 ext4 891M 57M 772M 7% /boot /dev/nvme0n1p15 vfat 98M 6.4M 92M 7% /boot/efi ``` -Using the `lsblk` command to view the 2 elastic block storage (EBS) devices attached to the server (`nvme1n1` and `nvme2n1`). This may be useful if you want to target a specific partition of the disk. Here we can see how the `NVMe` storage device has been partitioned. Fio allows us to test a device through a filesystem or to directly write to block device without a file system. +Using the `lsblk` command to view the EBS volumes attached to the server (`nvme1n1` and `nvme2n1`). The immediate number appended to `nvme`, e.g., `nvme0`, shows it is a physically separate device. + +```bash +lsblk -e 7 +``` ```output -nvme2n1 259:0 0 16G 0 disk -nvme0n1 259:1 0 16G 0 disk -├─nvme0n1p1 259:3 0 15G 0 part / +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS +nvme1n1 259:0 0 8G 0 disk +nvme0n1 259:1 0 8G 0 disk +├─nvme0n1p1 259:3 0 7G 0 part / ├─nvme0n1p15 259:4 0 99M 0 part /boot/efi └─nvme0n1p16 259:5 0 923M 0 part /boot -nvme1n1 259:2 0 16G 0 disk +nvme2n1 259:2 0 8G 0 disk ``` +We can use the `blkid` command to find the directory for `nvme1n1`. ## Generating a Synthetic Workload -The fio tool uses simple configuration `jobfiles` to describe the characterisics of your synthetic workload. A template `jobfile` is shown below. Parameters under the `[global]` option are shared among jobs. These can be overwritten if a new value is specified under the job. - -```output -; -- start job file -- -[global] -; Common param -[job1] -; job1's parameters -[job2] -; job2's parameters -``` +Let us say we want to simulate an loggin system with the following characteristics observed using the tools from the previous section. -Please refer to the [documentation](https://fio.readthedocs.io/en/latest/fio_doc.html#job-file-format) for full details on the configuration file structure. +*The logging workload has a light sequential write averaging 100 IOPS. The system write throughput is 5 MB/s with 83% writes. There are infrequent bursts of reads, operating at 1000 IOPS and 256MB/s. The workload can scale the infrequent reads and writes to use up to 16 threads each.* +The fio tool uses simple configuration `jobfiles` to describe the characterisics of your synthetic workload. A template `jobfile` is shown below. Parameters under the `[global]` option are shared among jobs. From the example above, we have created 2 jobs to represent the steady write and infrequent reads. -Let us say we want to simulate an I/O workload with the following characteristed observed using various tools. +Please refer to the [documentation](https://fio.readthedocs.io/en/latest/fio_doc.html#job-file-format) for full details on the configuration file structure. -*The system's disks have a light sequential write workload averaging 100 IOPS. The system throughput is 5 MB/s with 80% writes. There are infrequent bursts of reads, operating at 1000 IOPS and 256MB/s. The workload can scale the infrequent read to use all the available cores. However, the writes are limited to a single job* +Copy and paste the configuration file below into 2 files named `nvme.fio`. Replace the `` with the block devices we are comparing and just the `filename` parameter accordingly. -Copy and paste the configuration file below into a file named `example.fio`. Replace the `filename` with the location of where you'd like to read / write to. Please note: Do not write to a drive that contains critical information such as drives used for booting. We recommend writing to an unformatted block device or a mounted filesystem that you are OK to lose data from. +**Please note**: Do not write to a drive that contains critical information such as drives used for booting. We recommend writing to an unformatted block device or a mounted filesystem that you are OK to lose data from. ```ini ; -- start job file including.fio -- [global] ioengine=libaio -direct=1 +direct=1 ; write directly to the drive time_based runtime=30 -group_reporting +group_reporting=1 log_avg_msec=1000 -filename=/dev/nvme1n1 +filename=/dev/nvme1n1 ; or nvme1n1 [steady_write] name=steady_write rw=write -bs=64k -rate=5m -numjobs=1 -iodepth=1 -write_bw_log=steady_write -write_iops_log=steady_write -write_lat_log=steady_write +bs=64k ; Block size of 64KiB (default block size of 4 KiB) +rate=5m ; limit to 5 MiB/s +numjobs=${NUM_JOBS} ; set at the command line +iodepth=${IO_DEPTH} + [burst_read] name=burst_read rw=read -bs=256k -rate=256m +bs=256k ; adjust the block size to 64KiB writes (default is 4KiB) +rate=256m ; limit to 256 MiB/s numjobs=${NUM_JOBS} -iodepth=64 -startdelay=10 -runtime=5 -write_bw_log=burst_read -write_iops_log=burst_read -write_lat_log=burst_read - +iodepth=${IO_DEPTH} +startdelay=10 ; simulate infrequent reads (5 seconds out 30) +runtime=5s ; -- end job file including.fio -- ``` -Run the following command to run the workload. +Run the following commands to run each test back to back. ```bash -sudo NUM_JOBS=$(nproc) fio example.fio +sudo NUM_JOBS=16 IO_DEPTH=64 fio nvme1.fio ``` +Then + +```bash +sudo NUM_JOBS=16 IO_DEPTH=64 fio nvme2.fio +``` +The output from NVMe1 shows: + +```output +Run status group 0 (all jobs): + READ: bw=127MiB/s (133MB/s), 127MiB/s-127MiB/s (133MB/s-133MB/s), io=677MiB (710MB), run=5333-5333msec + WRITE: bw=80.0MiB/s (83.9MB/s), 80.0MiB/s-80.0MiB/s (83.9MB/s-83.9MB/s), io=2400MiB (2517MB), run=30003-30003msec + +Disk stats (read/write): + nvme1n1: ios=2805/38226, sectors=1391184/4892928, merge=0/0, ticks=188746/514998, in_queue=703745, util=88.53% +``` + +```output +Run status group 0 (all jobs): + READ: bw=87.9MiB/s (92.1MB/s), 87.9MiB/s-87.9MiB/s (92.1MB/s-92.1MB/s), io=462MiB (484MB), run=5256-5256msec + WRITE: bw=59.5MiB/s (62.4MB/s), 59.5MiB/s-59.5MiB/s (62.4MB/s-62.4MB/s), io=1794MiB (1881MB), run=30128-30128msec + +Disk stats (read/write): + nvme2n1: ios=1896/28700, sectors=947760/3673600, merge=0/0, ticks=169728/1054671, in_queue=1224400, util=80.22% +``` + +More interestingly, the latency for each request is different. + +```output + lat (msec) : 2=57.80%, 4=0.15%, 10=0.34%, 20=1.46%, 50=3.50% + lat (msec) : 100=1.85%, 250=6.17%, 500=11.80%, 750=5.73%, 1000=2.79% + lat (msec) : 2000=4.41%, >=2000=4.01% +``` + +With the `nvme2` device showing 20% of writes taking 2+ seconds to confirm a write, compared to the 4% with `nvme1`. These insights suggest that if this contrived logging system is latency sensitive, the `nvme2` can offer better performance. + +```output + lat (msec) : 2=30.37%, 4=0.07%, 10=0.37%, 20=0.14%, 50=0.07% + lat (msec) : 100=0.46%, 250=1.89%, 500=6.17%, 750=9.99%, 1000=9.27% + lat (msec) : 2000=20.61%, >=2000=9.02% +``` From 4cee80d8008e0471a2f3161b2ce3e5a6cfa47992 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 17 Apr 2025 11:09:53 +0100 Subject: [PATCH 3/7] minor update of LP for clarity --- .../disk-io-benchmark/IOPS.png | Bin 0 -> 40437 bytes .../disk-io-benchmark/_index.md | 6 +- .../characterising-workload.md | 79 +++++++------- .../disk-io-benchmark/introduction.md | 25 +++-- .../disk-io-benchmark/using-fio.md | 100 ++++++++++-------- 5 files changed, 112 insertions(+), 98 deletions(-) create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/IOPS.png diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/IOPS.png b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/IOPS.png new file mode 100644 index 0000000000000000000000000000000000000000..37d9d49bdeb1eeb8d334301d63fcd6fe1012cf79 GIT binary patch literal 40437 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 AGynhq literal 0 HcmV?d00001 diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md index 42d40167ae..8ac495d0ad 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md @@ -7,7 +7,8 @@ who_is_this_for: A cloud developer who wants to optimise storage cost or perform learning_objectives: - Understand basic data flow for storage devices - - Understand how to run the fio microbenchmark + - Use basic observability utilities such as iostat, iotop and pidstat + - Understand how to run fio for microbenchmarking a block storage device prerequisites: - Access to an Arm-based server @@ -17,11 +18,12 @@ author: Kieran Hejmadi ### Tags skilllevels: Introductory -subjects: Runbook, Performance and Architecture +subjects: Performance and Architecture armips: - Neoverse tools_software_languages: - bash + - Runbook operatingsystems: - Linux diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md index 6b2d6986fb..bc3061a571 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md @@ -6,7 +6,7 @@ weight: 3 layout: learningpathall --- -## Characterising your Workload +## Basic Characteristics The basic attributes of a given workload are the following. @@ -18,21 +18,23 @@ The basic attributes of a given workload are the following. The characteristics of many real-world workloads will vary over time, for example an application that periodically flushes writes to disk. Further, the system-wide and process-specific characteristics may be significantly differently. -## Example Workload +## Running an Example Workload -Connect to an Arm-based cloud instance. As an example workload, we will be using the media manipulation tool, FFMPEG on an AWS `t4g.medium` instance, with 2 Elastic Block Storage (EBS) volumes as per the image below. - -![ebs](./EBS.png) +Connect to an Arm-based cloud instance. As an example workload, we will be using the media manipulation tool, FFMPEG on an AWS `t4g.medium` instance. +First install the prequistite tools. ```bash sudo apt update sudo apt install ffmpeg iotop -y ``` -Download the popular example video, `BigBuckBunny.mp4` to demonstrate a transcoding workload. +Download the popular reference video for transcoding, `BigBuckBunny.mp4` which is available under the [Creative Commons 3.0 License](https://creativecommons.org/licenses/by/3.0/). ```bash +cd ~ +mkdir src +cd src wget http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 ``` @@ -41,12 +43,15 @@ Run the following command to begin transcoding the video and audio using the `H. ```bash ffmpeg -i BigBuckBunny.mp4 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k -flush_packets 1 output_video.mp4 ``` -Whilst the transcoding is running, we can use the `pidstat` command to see the disk statistics. + +### Observing Disk Usage + +Whilst the transcoding is running, we can use the `pidstat` command to see the disk statistics of that specific process. ```bash pidstat -d -p $(pgrep ffmpeg) 1 ``` -From the table below, we can observe this process is predominantly writing to disk at ~`300 kB/s`. +Since this example `151MB` video fits within memory, we observe no `kB_rd/s` for the storage device. However, since we are flushing to storage we observe ~275 `kB_wr/s` for this specific process. ```output Linux 6.8.0-1024-aws (ip-10-248-213-118) 04/15/25 _aarch64_ (2 CPU) @@ -62,9 +67,11 @@ Linux 6.8.0-1024-aws (ip-10-248-213-118) 04/15/25 _aarch64_ 10:01:32 1000 24250 0.00 344.00 0.00 0 ffmpeg ``` -Since this example `151MB` video fits within memory, we observe no `kB_rd/s` for the storage device. However, since we are flushing to storage we observe ~275 `kB_wr/s` for this specific process. +{{% notice Please Note%}} +In this simple example, since we are interacting with a file on the mounted filesystem, we are also observing the behaviour of the filesystem. +{{% /notice %}} -We can use iotop to confirm that our `ffmpeg` process has the greatest disk utilisation. +Of course, there may be other processes or background services that are writing to this disk. We can use `iotop` command for inspection. As per the output below, the `ffmpeg` process has the greatest disk utilisation. ```bash sudo iotop @@ -91,35 +98,7 @@ Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_w nvme0n1 3.81 31.63 217.08 0.00 831846 5709210 0 ``` -The following characteristics are calculated as follows. - -1. IOPS - -**Value:** 3.81 -_This is taken directly from the `tps` (transfers per second) field._ - -2. Throughput - -**Read:** 31.63 kB/s -**Write:** 217.08 kB/s -**Total:** 248.71 kB/s -_Sum of read and write throughput values._ - -3. Average I/O Size - -**Value:** ≈ 65.3 KB -_Calculated as total throughput divided by IOPS: 248.71 / 3.81._ - - -4. Read/Write Ratio - -**Read:** ~13% -**Write:** ~87% -_Computed as: (read or write throughput) ÷ total throughput._ - -Finally, to the access pattern of our workload (i.e. random vs. sequential) is slightly more complicated. We can infer the locality of our accesses through our understanding of the program, the cache hit rate (for reads), and merge rate on the dispatch side. Metrics that show high degree of merging, cache hits and low wait times suggest that our accesses are sequential in nature. - -Running the following command. +To observe the more detailed metrics we can run `iostat` with the `-x` option. ```bash iostat -xz nvme0n1 @@ -130,4 +109,24 @@ Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB nvme0n1 0.66 29.64 0.24 26.27 0.73 44.80 2.92 203.88 3.17 52.01 2.16 69.70 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.15 ``` -The `wrqm/s` column is the number of write requests merged per second before being issued. Calculated the percentage or writes merged compared to writes is one indicator of how sequental the data accesses are. +### Basic Characteristics of our Example Workload + +This is a simple transcoding workload with flushed writes, where most data is processed and stored in memory. Disk I/O is minimal, with an IOPS of just 3.81, low throughput (248.71 kB/s), and an average IO depth of 0.01 — all indicating very low disk utilization. The 52% write merge rate and low latencies further suggest sequential, infrequent disk access, reinforcing that the workload is primarily memory-bound. + + +| Metric | Calculation Explanation | Value | +|--------------------|-------------------------------------------------------------------------------------------------------------|---------------| +| IOPS | Taken directly from the `tps` (transfers per second) field | 3.81 | +| Throughput (Read) | From monitoring tool output | 31.63 kB/s | +| Throughput (Write) | From monitoring tool output | 217.08 kB/s | +| Throughput (Total) | Sum of read and write throughput | 248.71 kB/s | +| Avg I/O Size | Total throughput divided by IOPS: 248.71 / 3.81 | ≈ 65.3 KB | +| Read Ratio | Read throughput ÷ total throughput: 31.63 / 248.71 | ~13% | +| Write Ratio | Write throughput ÷ total throughput: 217.08 / 248.71 | ~87% | +| IO Depth | Taken directly from `aqu-sz` (average number of in-flight I/Os) | 0.01 | +| Access Pattern | Based on cache hits, merge rates, and low wait times. 52% of writes were merged (`wrqm/s` = 3.17, `w/s` = 2.92) → suggests mostly sequential access | Sequential-ish (52.01% merged) | + + +{{% notice Please Note%}} +If you have access to the workloads source code, the expected access patterns can more easily be observed. +{{% /notice %}} diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md index 5944de1bc4..90b1d2cd2a 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md @@ -12,7 +12,7 @@ The ideal storage activity of your system is 0. In this situation all of your ap ## High-Level Flow of Data -The diagram below is a high-level overview of how data can be written or read from a storage device. +The diagram below is a high-level overview of how data can be written or read from a storage device. This diagram illustrates a multi-disk I/O architecture where each disk (Disk 1 to Disk N) has an I/O queue and optional disk cache, communicating with a central CPU via a disk controller. Memory is not explicitly shown but typically resides between the CPU and storage, offering faster access times than disk but is volatile. File systems, though not depicted, operate at the OS/kernel level to handling file access metadata and offer a familiar way to interact with files and directories. In NVMe-based systems, the disk controller is located on the drive itself, reducing latency and improving parallelism. ![disk i/o](./diskio.jpeg) @@ -20,30 +20,33 @@ Many techniques are transparent to a developer. The queue at the operating syste ## Key Terms -**Sectors and Blocks** +#### Sectors and Blocks Sectors are the basic physical units on a storage device. For instance, traditional hard drives typically use a sector size of 512 bytes, while many modern disks use 4096 bytes (or 4K sectors) to improve error correction and efficiency. Blocks are the logical grouping of one or more sectors used by filesystems for data organization. A common filesystem block size is 4096 bytes, meaning that each block might consist of 8 of the 512-byte sectors, or simply map directly to a 4096-byte physical sector layout if the disk supports it. -**Input Output Operations per second (IOPS)** -IOPS is a measure of how much traffic your storage system can manage. It is worth noting that IOPS can vary by block size depending on the storage medium (e.g., flash drives). +#### Input Output Operations per second (IOPS) +IOPS is a measure of how much random read or write requests your storage system can manage. It is worth noting that IOPS can vary by block size depending on the storage medium (e.g., flash drives). Importantly, traditional hard disk drives (HDDs) often don't specify the IOPS. For example the IOPS value for HDD volume on AWS is not shown. -**Throughput / Bandwidth** -Throughput is the data transfer rate normally in MB/s. IOPS x block size is the bandwidth utilisation of your system. +![iops_hdd](./IOPS.png) -**Queue Depth** +#### Throughput / Bandwidth +Throughput is the data transfer rate normally in MB/s. IOPS x block size is the bandwidth utilisation of your system. Max throughput is usually reached for sequential access patterns. + +#### Queue Depth Queue depth refers to the number of simultaneous I/O operations that can be pending on a device. Consumer SSDs might typically have a queue depth in the range of 32 to 64, whereas enterprise-class NVMe drives can support hundreds or even thousands of concurrent requests per queue. This parameter affects how much the device can parallelize operations and therefore influences overall I/O performance. -**I/O Schedule Engine** +#### I/O Schedule Engine The I/O engine is the software component within Linux responsible for managing I/O requests between applications and the storage subsystem. For example, in Linux, the kernel’s block I/O scheduler acts as an I/O engine by queuing and dispatching requests to device drivers. Schedulers use multiple queues to reorder requests optimal disk access. In benchmarking tools like fio, you might select I/O engines such as sync (synchronous I/O), `libaio` (Linux native asynchronous I/O library), or `io_uring` (which leverages newer Linux kernel capabilities for asynchronous I/O). -**Merging** +#### I/O Wait +This is the perceived time spent waiting for I/O to return the value from the perspective of the CPU core. +### Considerations for Cloud Storage -### Typical Storage Types for Cloud Instances +In a cloud environment, you are typically sharing a physical instance of a server with multiple tenants. As such the CPU cores and storage devices may be shared resulting in cloud service providers often provide an IOPS per GB. Where your system's storage performance is proportional to the block device size. See [this example](https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/blockvolumeperformance.htm) for more information. -In a cloud environment, you are typically sharing a physical instance of a server with multiple tenants. As such the CPU cores and storage devices may be shared. As such, cloud service providers often provide an IOPS per GB. Where your system's storage performance is proportional to the block device size. See [this example](https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/blockvolumeperformance.htm) for more information. \ No newline at end of file diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md index 64dca8dff7..e542fb754b 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md @@ -6,37 +6,36 @@ weight: 4 layout: learningpathall --- -## Install Fio +## Setup and Install Fio -Flexible I/O (fio) is a command-line tool to generate a synthetic workload with specific I/O characteristics. +I will be using the same `t4g.medium` instance from the previous section with 2 different types of SSD-based elastic block storage devices as per the console screenshot below. Both block devices have the same, 8GiB capacity but the `io1` type offers greater IOPS. In this section we want to observe what the real-world performance for our workload is so that it can inform our selection. -Fio is available through most Linux distribution packages. Please refer to the [documentation](https://github.com/axboe/fio) for the binary package availability. +![EBS](./EBS.png) + +Flexible I/O (fio) is a command-line tool to generate a synthetic workload with specific I/O characteristics. Fio is available through most Linux distribution packages. Please refer to the [documentation](https://github.com/axboe/fio) for the binary package availability. ```bash sudo apt update -sudo apt install fio gnuplot -y +sudo apt install fio -y ``` Confirm installation with the following commands. ```bash fio --version -gnuplot --version ``` ```output fio-3.36 -gnuplot 6.0 patchlevel 0 ``` ## Locate Device -We have the option to directly microbenchmark the block device or microbenchmark a mounted filesystem. Use the disk free, `df` command to see if the mounted storage devices connected to your server. We are excluding the temporary file system, `tmpfs` for clarity. +`Fio` allows us to microbenchmark either the block device or a mounted filesystem. The disk free, `df` command to confirm our EBS volumes are not mounted. ```bash df -hTx tmpfs ``` -The output below shows a 30GB ```output Filesystem Type Size Used Avail Use% Mounted on @@ -47,7 +46,7 @@ efivarfs efivarfs 128K 3.7K 125K 3% /sys/firmware/efi/efivars /dev/nvme0n1p15 vfat 98M 6.4M 92M 7% /boot/efi ``` -Using the `lsblk` command to view the EBS volumes attached to the server (`nvme1n1` and `nvme2n1`). The immediate number appended to `nvme`, e.g., `nvme0`, shows it is a physically separate device. +Using the `lsblk` command to view the EBS volumes attached to the server (`nvme1n1` and `nvme2n1`). The immediate number appended to `nvme`, e.g., `nvme0`, shows it is a physically separate device. `nvme1n1` corresponds to the faster `io2` block device and `nvme2n1` corresponds to the slower `gp3` block device. ```bash lsblk -e 7 @@ -62,22 +61,27 @@ nvme0n1 259:1 0 8G 0 disk └─nvme0n1p16 259:5 0 923M 0 part /boot nvme2n1 259:2 0 8G 0 disk ``` + +{{% notice Please Note%}} +If you have more than 1 block volumes attached to an instance, the `sudo nvme list` command from the `nvme-cli` package and be used to differentiate between volumes +{{% /notice %}} + We can use the `blkid` command to find the directory for `nvme1n1`. ## Generating a Synthetic Workload -Let us say we want to simulate an loggin system with the following characteristics observed using the tools from the previous section. +Let us say we want to simulate a fictional logging application with the following characteristics observed using the tools from the previous section. -*The logging workload has a light sequential write averaging 100 IOPS. The system write throughput is 5 MB/s with 83% writes. There are infrequent bursts of reads, operating at 1000 IOPS and 256MB/s. The workload can scale the infrequent reads and writes to use up to 16 threads each.* +{{% notice Workload%}} +The logging workload has a light sequential read and write workload. The system write throughput per thread is 5 MB/s with 83% writes. There are infrequent bursts of reads for approximately 5 seconds, operating at 16MB/s per thread. The workload can scale the infrequent reads and writes to use up to 16 threads each. The block size for the writes and reads are 64KiB and 256KiB respectively (as opposed to the standard 4KiB Page size). -The fio tool uses simple configuration `jobfiles` to describe the characterisics of your synthetic workload. A template `jobfile` is shown below. Parameters under the `[global]` option are shared among jobs. From the example above, we have created 2 jobs to represent the steady write and infrequent reads. +Further, the application is sensitive to latency and since it holds critical information, needs to write directly to non-volatile storage (directIO). +{{% /notice %}} -Please refer to the [documentation](https://fio.readthedocs.io/en/latest/fio_doc.html#job-file-format) for full details on the configuration file structure. +The fio tool uses simple configuration `jobfiles` to describe the characterisics of your synthetic workload. Parameters under the `[global]` option are shared among jobs. From the example below, we have created 2 jobs to represent the steady write and infrequent reads. Please refer to the official [documentation](https://fio.readthedocs.io/en/latest/fio_doc.html#job-file-format) for more details. Copy and paste the configuration file below into 2 files named `nvme.fio`. Replace the `` with the block devices we are comparing and just the `filename` parameter accordingly. -**Please note**: Do not write to a drive that contains critical information such as drives used for booting. We recommend writing to an unformatted block device or a mounted filesystem that you are OK to lose data from. - ```ini ; -- start job file including.fio -- [global] @@ -87,27 +91,22 @@ time_based runtime=30 group_reporting=1 log_avg_msec=1000 -filename=/dev/nvme1n1 ; or nvme1n1 - +rate=16m,5m ; limit to 16 MB/s and 5MB/s for read and write per job +numjobs=${NUM_JOBS} ; set at the command line +iodepth=${IO_DEPTH} ; set at the command line +filename=/dev/nvme1n1 ; or nvme2n1 [steady_write] name=steady_write -rw=write +rw=write ; sequential write bs=64k ; Block size of 64KiB (default block size of 4 KiB) -rate=5m ; limit to 5 MiB/s -numjobs=${NUM_JOBS} ; set at the command line -iodepth=${IO_DEPTH} - [burst_read] name=burst_read rw=read bs=256k ; adjust the block size to 64KiB writes (default is 4KiB) -rate=256m ; limit to 256 MiB/s -numjobs=${NUM_JOBS} -iodepth=${IO_DEPTH} startdelay=10 ; simulate infrequent reads (5 seconds out 30) -runtime=5s +runtime=5 ; -- end job file including.fio -- ``` @@ -122,38 +121,49 @@ Then ```bash sudo NUM_JOBS=16 IO_DEPTH=64 fio nvme2.fio ``` -The output from NVMe1 shows: + +### Interpreting Results ```output + +nvme1: + Run status group 0 (all jobs): - READ: bw=127MiB/s (133MB/s), 127MiB/s-127MiB/s (133MB/s-133MB/s), io=677MiB (710MB), run=5333-5333msec - WRITE: bw=80.0MiB/s (83.9MB/s), 80.0MiB/s-80.0MiB/s (83.9MB/s-83.9MB/s), io=2400MiB (2517MB), run=30003-30003msec + READ: bw=118MiB/s (124MB/s), 118MiB/s-118MiB/s (124MB/s-124MB/s), io=629MiB (660MB), run=5324-5324msec + WRITE: bw=80.0MiB/s (83.9MB/s), 80.0MiB/s-80.0MiB/s (83.9MB/s-83.9MB/s), io=2400MiB (2517MB), run=30006-30006msec Disk stats (read/write): - nvme1n1: ios=2805/38226, sectors=1391184/4892928, merge=0/0, ticks=188746/514998, in_queue=703745, util=88.53% -``` + nvme1n1: ios=2663/38225, sectors=1294480/4892800, merge=0/0, ticks=148524/454840, in_queue=603364, util=62.19% + +nvme2: -```output Run status group 0 (all jobs): - READ: bw=87.9MiB/s (92.1MB/s), 87.9MiB/s-87.9MiB/s (92.1MB/s-92.1MB/s), io=462MiB (484MB), run=5256-5256msec - WRITE: bw=59.5MiB/s (62.4MB/s), 59.5MiB/s-59.5MiB/s (62.4MB/s-62.4MB/s), io=1794MiB (1881MB), run=30128-30128msec + READ: bw=85.6MiB/s (89.8MB/s), 85.6MiB/s-85.6MiB/s (89.8MB/s-89.8MB/s), io=456MiB (478MB), run=5322-5322msec + WRITE: bw=60.3MiB/s (63.2MB/s), 60.3MiB/s-60.3MiB/s (63.2MB/s-63.2MB/s), io=1816MiB (1904MB), run=30119-30119msec Disk stats (read/write): - nvme2n1: ios=1896/28700, sectors=947760/3673600, merge=0/0, ticks=169728/1054671, in_queue=1224400, util=80.22% + nvme2n1: ios=1872/28855, sectors=935472/3693440, merge=0/0, ticks=159753/1025104, in_queue=1184857, util=89.83% ``` -More interestingly, the latency for each request is different. +Here we can see that the faster `io2` block storage (`nvme1`) is able to meet the throughput requirement of 80MB/s for steady writes when all 16 write threads are running (5MB/s per thread). However `gp2` saturates at 60.3 MiB/s with over 89.8% SSD utilisation. + +We are told the fictional logging application is sensitive to operation latency. The output belows highlights that over ~35% operations have a latency above 1s on nvme2 compared to ~7% on nvme1. ```output - lat (msec) : 2=57.80%, 4=0.15%, 10=0.34%, 20=1.46%, 50=3.50% - lat (msec) : 100=1.85%, 250=6.17%, 500=11.80%, 750=5.73%, 1000=2.79% - lat (msec) : 2000=4.41%, >=2000=4.01% -``` -With the `nvme2` device showing 20% of writes taking 2+ seconds to confirm a write, compared to the 4% with `nvme1`. These insights suggest that if this contrived logging system is latency sensitive, the `nvme2` can offer better performance. + nvme2: -```output - lat (msec) : 2=30.37%, 4=0.07%, 10=0.37%, 20=0.14%, 50=0.07% - lat (msec) : 100=0.46%, 250=1.89%, 500=6.17%, 750=9.99%, 1000=9.27% - lat (msec) : 2000=20.61%, >=2000=9.02% + lat (usec) : 10=0.01%, 500=1.53%, 750=5.13%, 1000=7.55% + lat (msec) : 2=29.49%, 4=0.89%, 10=0.09%, 20=0.02%, 50=0.21% + lat (msec) : 100=0.56%, 250=1.84%, 500=6.39%, 750=9.76%, 1000=10.17% + lat (msec) : 2000=19.59%, >=2000=6.77% + + nvme1: + + lat (usec) : 750=0.44%, 1000=0.41% + lat (msec) : 2=62.63%, 4=1.12%, 10=0.34%, 20=1.61%, 50=3.91% + lat (msec) : 100=2.34%, 250=5.91%, 500=8.46%, 750=4.33%, 1000=2.50% + lat (msec) : 2000=3.62%, >=2000=2.38% ``` + +The insights gathered by microbenchmarking with fio above can lead to more informed decisions about which block storage to connect to your Arm-based instance. From f9157a3b2077dbe99b9da73aa5875038eb9de5af Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 17 Apr 2025 11:17:50 +0100 Subject: [PATCH 4/7] remove df-h command as not necessary for LP --- .../disk-io-benchmark/using-fio.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md index e542fb754b..c72bac07f8 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md @@ -8,7 +8,7 @@ layout: learningpathall ## Setup and Install Fio -I will be using the same `t4g.medium` instance from the previous section with 2 different types of SSD-based elastic block storage devices as per the console screenshot below. Both block devices have the same, 8GiB capacity but the `io1` type offers greater IOPS. In this section we want to observe what the real-world performance for our workload is so that it can inform our selection. +I will be using the same `t4g.medium` instance from the previous section with 2 different types of SSD-based block storage devices as per the console screenshot below. Both block devices have the same, 8GiB capacity but the `io1` is geared towards I/O as opposed to the general purpose SSD `gp2`. In this section we want to observe what the real-world performance for our workload is so that it can inform our selection. ![EBS](./EBS.png) @@ -33,19 +33,6 @@ fio-3.36 `Fio` allows us to microbenchmark either the block device or a mounted filesystem. The disk free, `df` command to confirm our EBS volumes are not mounted. -```bash -df -hTx tmpfs -``` - -```output -Filesystem Type Size Used Avail Use% Mounted on -Filesystem Type Size Used Avail Use% Mounted on -/dev/root ext4 6.8G 2.8G 4.0G 41% / -efivarfs efivarfs 128K 3.7K 125K 3% /sys/firmware/efi/efivars -/dev/nvme0n1p16 ext4 891M 57M 772M 7% /boot -/dev/nvme0n1p15 vfat 98M 6.4M 92M 7% /boot/efi -``` - Using the `lsblk` command to view the EBS volumes attached to the server (`nvme1n1` and `nvme2n1`). The immediate number appended to `nvme`, e.g., `nvme0`, shows it is a physically separate device. `nvme1n1` corresponds to the faster `io2` block device and `nvme2n1` corresponds to the slower `gp3` block device. ```bash @@ -66,8 +53,6 @@ nvme2n1 259:2 0 8G 0 disk If you have more than 1 block volumes attached to an instance, the `sudo nvme list` command from the `nvme-cli` package and be used to differentiate between volumes {{% /notice %}} -We can use the `blkid` command to find the directory for `nvme1n1`. - ## Generating a Synthetic Workload Let us say we want to simulate a fictional logging application with the following characteristics observed using the tools from the previous section. From 6e722fbdb49dfecd9bb8770ffbbaec2ce4db30d1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 17 Apr 2025 11:21:15 +0100 Subject: [PATCH 5/7] removed cloud considerations to simplify LP --- .../disk-io-benchmark/introduction.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md index 90b1d2cd2a..697690922a 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md @@ -45,8 +45,3 @@ In benchmarking tools like fio, you might select I/O engines such as sync (synch #### I/O Wait This is the perceived time spent waiting for I/O to return the value from the perspective of the CPU core. - -### Considerations for Cloud Storage - -In a cloud environment, you are typically sharing a physical instance of a server with multiple tenants. As such the CPU cores and storage devices may be shared resulting in cloud service providers often provide an IOPS per GB. Where your system's storage performance is proportional to the block device size. See [this example](https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/blockvolumeperformance.htm) for more information. - From 228250b1d177b7c21581ba93702da81d8f8b638e Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 17 Apr 2025 11:41:17 +0100 Subject: [PATCH 6/7] added tip for visualisation --- .../disk-io-benchmark/using-fio.md | 16 ++++++++++++++-- .../disk-io-benchmark/visualisations.png | Bin 0 -> 15379 bytes 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/visualisations.png diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md index c72bac07f8..efad4d0867 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md @@ -12,7 +12,7 @@ I will be using the same `t4g.medium` instance from the previous section with 2 ![EBS](./EBS.png) -Flexible I/O (fio) is a command-line tool to generate a synthetic workload with specific I/O characteristics. Fio is available through most Linux distribution packages. Please refer to the [documentation](https://github.com/axboe/fio) for the binary package availability. +Flexible I/O (fio) is a command-line tool to generate a synthetic workload with specific I/O characteristics. This serves as a simpler alternative to full record and replay testing. Fio is available through most Linux distribution packages, please refer to the [documentation](https://github.com/axboe/fio) for the binary package availability. ```bash sudo apt update @@ -109,8 +109,9 @@ sudo NUM_JOBS=16 IO_DEPTH=64 fio nvme2.fio ### Interpreting Results -```output +The final terminal output from both runs are shown below. +```output nvme1: Run status group 0 (all jobs): @@ -134,6 +135,7 @@ Here we can see that the faster `io2` block storage (`nvme1`) is able to meet th We are told the fictional logging application is sensitive to operation latency. The output belows highlights that over ~35% operations have a latency above 1s on nvme2 compared to ~7% on nvme1. + ```output nvme2: @@ -151,4 +153,14 @@ We are told the fictional logging application is sensitive to operation latency. lat (msec) : 2000=3.62%, >=2000=2.38% ``` +This insights above suggest the SSD designed for throughput, `io2` is more suitable than the general purpose `gp2` storage to meet the requirements of our logging application. + +{{% notice Tip%}} +If the text output is hard to follow, you can use the `fio2gnuplot` package to plot the data graphically or use the visualisations available from the cloud service provider's dashboard. See image below for an example. + + ![plot](./visualisations.png) +{{% /notice %}} + The insights gathered by microbenchmarking with fio above can lead to more informed decisions about which block storage to connect to your Arm-based instance. + + diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/visualisations.png b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/visualisations.png new file mode 100644 index 0000000000000000000000000000000000000000..20f83e8d72db6806b83a0cd5a59e0512484fa1fe GIT binary patch literal 15379 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%0D0hXGRzvi(|qf7+#R)l8b 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 Date: Thu, 17 Apr 2025 12:04:09 +0100 Subject: [PATCH 7/7] final review --- .../disk-io-benchmark/_index.md | 2 +- .../disk-io-benchmark/characterising-workload.md | 8 ++++---- .../disk-io-benchmark/introduction.md | 7 +++---- .../disk-io-benchmark/using-fio.md | 10 +++++----- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md index 8ac495d0ad..28b4d145e2 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/_index.md @@ -6,7 +6,7 @@ minutes_to_complete: 30 who_is_this_for: A cloud developer who wants to optimise storage cost or performance of their application. Developers who want to uncover potential storage-bound bottlenecks or changes when migrating an application to a different platform. learning_objectives: - - Understand basic data flow for storage devices + - Understand the flow of data for storage devices - Use basic observability utilities such as iostat, iotop and pidstat - Understand how to run fio for microbenchmarking a block storage device diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md index bc3061a571..06116a2a22 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/characterising-workload.md @@ -16,7 +16,7 @@ The basic attributes of a given workload are the following. - Read to Write Ratio - Random vs Sequential access -The characteristics of many real-world workloads will vary over time, for example an application that periodically flushes writes to disk. Further, the system-wide and process-specific characteristics may be significantly differently. +There are many more characteristics to observe, just as latency but since this is an introductory topic we will mostly stick to the high-level metrics listed above. ## Running an Example Workload @@ -38,7 +38,7 @@ cd src wget http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 ``` -Run the following command to begin transcoding the video and audio using the `H.264` and `aac` transcoders respectively. We use the `-flush_packets` flag to write each chunk of video back to storage. +Run the following command to begin transcoding the video and audio using the `H.264` and `aac` transcoders respectively. We use the `-flush_packets` flag to write each chunk of video back to storage from memory. ```bash ffmpeg -i BigBuckBunny.mp4 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k -flush_packets 1 output_video.mp4 @@ -51,7 +51,7 @@ Whilst the transcoding is running, we can use the `pidstat` command to see the d ```bash pidstat -d -p $(pgrep ffmpeg) 1 ``` -Since this example `151MB` video fits within memory, we observe no `kB_rd/s` for the storage device. However, since we are flushing to storage we observe ~275 `kB_wr/s` for this specific process. +Since this example `151MB` video fits within memory, we observe no `kB_rd/s` for the storage device after the initial read. However, since we are flushing to storage we observe period ~275 `kB_wr/s`. ```output Linux 6.8.0-1024-aws (ip-10-248-213-118) 04/15/25 _aarch64_ (2 CPU) @@ -111,7 +111,7 @@ nvme0n1 0.66 29.64 0.24 26.27 0.73 44.80 2.92 203. ### Basic Characteristics of our Example Workload -This is a simple transcoding workload with flushed writes, where most data is processed and stored in memory. Disk I/O is minimal, with an IOPS of just 3.81, low throughput (248.71 kB/s), and an average IO depth of 0.01 — all indicating very low disk utilization. The 52% write merge rate and low latencies further suggest sequential, infrequent disk access, reinforcing that the workload is primarily memory-bound. +This is a simple transcoding workload with flushed writes, where most data is processed and stored in memory. Disk I/O is minimal, with an IOPS of just 3.81, low throughput (248.71 kB/s), and an average IO depth of 0.01 — all summarised in very low disk utilization. The 52% write merge rate and low latencies further suggest sequential, infrequent disk access, reinforcing that the workload is primarily memory-bound. | Metric | Calculation Explanation | Value | diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md index 697690922a..08a9a873d5 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/introduction.md @@ -8,15 +8,14 @@ layout: learningpathall ## Introduction -The ideal storage activity of your system is 0. In this situation all of your applications data and instructions are available in memory or caches and no reads or writes to a spinning hard-disk drive or solid-state SSD are required. However, due to physical capacity limitations, data volatility and need to store large amounts of data, many applications require frequent access to storage media. +The ideal storage activity of your system is 0. In this situation all of your application data and instructions are available in memory or caches with no reads or writes to a spinning hard-disk drive or solid-state SSD required. However, due to physical capacity limitations, data volatility and need to store large amounts of data, many applications require frequent access to storage media. ## High-Level Flow of Data -The diagram below is a high-level overview of how data can be written or read from a storage device. This diagram illustrates a multi-disk I/O architecture where each disk (Disk 1 to Disk N) has an I/O queue and optional disk cache, communicating with a central CPU via a disk controller. Memory is not explicitly shown but typically resides between the CPU and storage, offering faster access times than disk but is volatile. File systems, though not depicted, operate at the OS/kernel level to handling file access metadata and offer a familiar way to interact with files and directories. In NVMe-based systems, the disk controller is located on the drive itself, reducing latency and improving parallelism. +The diagram below is a high-level overview of how data can be written or read from a storage device. This diagram illustrates a multi-disk I/O architecture where each disk (Disk 1 to Disk N) has an I/O queue and optional disk cache, communicating with a central CPU via a disk controller. Memory is not explicitly shown but resides between the CPU and storage, offering fast access times with the tradeoff of volatile. File systems, though not depicted, operate at the OS/kernel level to handling file access metadata and offer a friendly way to interact through files and directories. ![disk i/o](./diskio.jpeg) -Many techniques are transparent to a developer. The queue at the operating system level and disk level may reorder I/O requests to improve efficiency (for example an atomic write that increments a value by 1 followed by a minus by 1). ## Key Terms @@ -32,7 +31,7 @@ IOPS is a measure of how much random read or write requests your storage system ![iops_hdd](./IOPS.png) #### Throughput / Bandwidth -Throughput is the data transfer rate normally in MB/s. IOPS x block size is the bandwidth utilisation of your system. Max throughput is usually reached for sequential access patterns. +Throughput is the data transfer rate normally in MB/s with bandwidth specifying the maximum amount that a connection can transfer. IOPS x block size can be used to calculate the storage throughput of your application. #### Queue Depth Queue depth refers to the number of simultaneous I/O operations that can be pending on a device. Consumer SSDs might typically have a queue depth in the range of 32 to 64, whereas enterprise-class NVMe drives can support hundreds or even thousands of concurrent requests per queue. This parameter affects how much the device can parallelize operations and therefore influences overall I/O performance. diff --git a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md index efad4d0867..bc50025ac4 100644 --- a/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md +++ b/content/learning-paths/servers-and-cloud-computing/disk-io-benchmark/using-fio.md @@ -8,7 +8,7 @@ layout: learningpathall ## Setup and Install Fio -I will be using the same `t4g.medium` instance from the previous section with 2 different types of SSD-based block storage devices as per the console screenshot below. Both block devices have the same, 8GiB capacity but the `io1` is geared towards I/O as opposed to the general purpose SSD `gp2`. In this section we want to observe what the real-world performance for our workload is so that it can inform our selection. +I will be using the same `t4g.medium` instance from the previous section with 2 different types of SSD-based block storage devices as per the console screenshot below. Both block devices have the same, 8GiB capacity but the `io1` is geared towards throughput as opposed to the general purpose SSD `gp2`. In this section we want to observe what the real-world performance for our workload is so that it can inform our selection. ![EBS](./EBS.png) @@ -31,9 +31,9 @@ fio-3.36 ## Locate Device -`Fio` allows us to microbenchmark either the block device or a mounted filesystem. The disk free, `df` command to confirm our EBS volumes are not mounted. +`Fio` allows us to microbenchmark either the block device or a mounted filesystem. The disk free, `df` command to confirm our EBS volumes are not mounted. Writing to drives that hold critical information may cause issues. Hence we are writing to blank, unmounted block storage device. -Using the `lsblk` command to view the EBS volumes attached to the server (`nvme1n1` and `nvme2n1`). The immediate number appended to `nvme`, e.g., `nvme0`, shows it is a physically separate device. `nvme1n1` corresponds to the faster `io2` block device and `nvme2n1` corresponds to the slower `gp3` block device. +Using the `lsblk` command to view the EBS volumes attached to the server (`nvme1n1` and `nvme2n1`). The immediate number appended to `nvme`, e.g., `nvme0`, shows it is a physically separate device. `nvme1n1` corresponds to the faster `io2` block device and `nvme2n1` corresponds to the slower `gp2` block device. ```bash lsblk -e 7 @@ -58,9 +58,9 @@ If you have more than 1 block volumes attached to an instance, the `sudo nvme li Let us say we want to simulate a fictional logging application with the following characteristics observed using the tools from the previous section. {{% notice Workload%}} -The logging workload has a light sequential read and write workload. The system write throughput per thread is 5 MB/s with 83% writes. There are infrequent bursts of reads for approximately 5 seconds, operating at 16MB/s per thread. The workload can scale the infrequent reads and writes to use up to 16 threads each. The block size for the writes and reads are 64KiB and 256KiB respectively (as opposed to the standard 4KiB Page size). +The logging workload has light sequential read and write characteristics. The system write throughput per thread is 5 MB/s with 83% writes. There are infrequent bursts of reads for approximately 5 seconds, operating at up to 16MB/s per thread. The workload can scale the infrequent reads and writes to use up to 16 threads each. The block size for the writes and reads are 64KiB and 256KiB respectively (as opposed to the standard 4KiB Page size). -Further, the application is sensitive to latency and since it holds critical information, needs to write directly to non-volatile storage (directIO). +Further, the application latency sensitive and given it holds critical information, needs to write directly to non-volatile storage through direct IO. {{% /notice %}} The fio tool uses simple configuration `jobfiles` to describe the characterisics of your synthetic workload. Parameters under the `[global]` option are shared among jobs. From the example below, we have created 2 jobs to represent the steady write and infrequent reads. Please refer to the official [documentation](https://fio.readthedocs.io/en/latest/fio_doc.html#job-file-format) for more details.