Do I/O Schedulers Perform Better in Virtual Machines or in Docker Containers?

0
352
Tux

The I/O schedulers in Linux manage the order in which the I/O requests of processes are handled by the disk subsystem. This article compares the performance of different I/O schedulers in Linux virtual machines and Docker containers, offering insights into optimising disk access for improved system performance.

Process schedulers are essential to the functionality and responsiveness of Linux systems and are well-known to the majority of users. Their primary role is to manage the distribution of system resources among processes, including the CPU, memory, and I/O hardware. The process scheduler’s objective is to maximise system throughput, reduce response time, and ensure fairness among all active processes.

In addition to process schedulers, Linux also has I/O schedulers that manage the order in which processes’ I/O requests are handled by the disk subsystem. The I/O scheduler performs a similar role to the process scheduler, but instead manages the processes’ disk access rather than the CPU. In situations where multiple I/O requests from different processes compete for disk access, the I/O scheduler is crucial to the system’s overall performance.

Despite the use of flash and solid-state storage, disk access remains the most expensive form of data access, being slower than data access from RAM. I/O schedulers optimise disk access requests to improve performance.

This article compares the efficiency of different I/O schedulers when SSDs are used, and the results are particularly relevant for processes that involve intensive disk access. The comparison is made between running benchmarks on Ubuntu 20.04 and using Docker and containers (where files must first be copied into the container to run the benchmarks).

“Prior to Ubuntu 19.04 with Linux 5.0 or Ubuntu 18.04.3 with Linux 4.15, the multiqueue I/O scheduling was not enabled by default and just the deadline, cfq and noop I/O schedulers were available by default. For Ubuntu 19.10 with Linux 5.0 or Ubuntu 18.04.3 with Linux 5.0 onwards, multiqueue is enabled by default providing the bfq, kyber, mq-deadline and none I/O schedulers. For Ubuntu 19.10 with Linux 5.3 the deadline, cfq and noop I/O schedulers are deprecated.” (Ubuntu Wiki, 2019)

The above statement can be taken as true for Ubuntu 20.04 too. Hence, for the comparison only the following I/O schedulers were taken into account:

  • none I/O scheduler
  • mq-deadline I/O scheduler
  • bfq I/O scheduler
  • kyber I/O scheduler

I/O scheduler commands

To check the available I/O schedulers, run the following command:

$ cat /sys/block/sda/queue/scheduler

The output would be something like:

[mq-deadline] none

This means that the currently selected I/O scheduler is mq-deadline, and other options are available in the I/O scheduler, for example, none. (Ubuntu Wiki, 2019). Usually, mq-deadline and none are available by default. If the other I/O schedulers are missing you could use the following commands:

$ sudo modprobe bfq
$ sudo modprobe kyber-iosched

Now run the following command to check the available I/O schedulers:

$ cat /sys/block/sda/queue/scheduler

The output would be something like:

[mq-deadline] none bfq kyber

Let’s now move on to the benchmarks.

Test 1: writes-starving-reads

This test evaluates the performance of the I/O schedulers when there is a write operation going on in the background and how efficiently the read operations can be completed without starvation. Benchmark Test 1 is designed in a way to get results for better comparison.

You can perform the write operation in the background, using the following command:

$ while true; do dd if=/dev/zero of=file bs=1M; done &

This command runs a write operation in the background due to the ‘&’ symbol used at the end of the command. The above command is an infinite while loop.

After the testing on benchmarks is done, remember to kill this process using its process ID.

The code for changing to the none scheduler and then running Benchmark Test 1 is given below.

Step 1: Perform the write operation in the background.

Step 2: Find out how long does it take to read a file of various sizes.

echo none
while true; do dd if=/dev/zero of=file bs=1M; done &
echo none > /sys/block/sda/queue/scheduler
time cat 10MB.txt > /dev/null
time cat 20MB.txt > /dev/null
time cat 30MB.txt > /dev/null
time cat 40MB.txt > /dev/null
time cat 50MB.txt > /dev/null
time cat 60MB.txt > /dev/null
time cat 70MB.txt > /dev/null
time cat 80MB.txt > /dev/null
time cat 90MB.txt > /dev/null
time cat 100MB.txt > /dev/null

We executed the read and write operations test cases in a virtual machine and Docker container, and the results are tabulated in Tables 1 to 4 for various schedulers.

Table 1: none I/O scheduler results
File size Real-time in Ubuntu 20.04 (in seconds) Real-time in Docker and container (in seconds) Percentage improvement
10MB 0.003 0.002 33.33
20MB 0.005 0.003 40
30MB 0.006 0.005 16.67
40MB 0.008 0.006 25
50MB 0.009 0.007 22.22
60MB 0.01 0.008 20
70MB 0.012 0.01 16.67
80MB 0.013 0.011 15.38
90MB 0.015 0.012 20
100MB 0.017 0.013 23.53

 

Figure 1 shows the performance comparison of none I/O schedulers in a virtual machine versus a Docker container.

 Graphical performance comparison of none I/O schedulers in VM vs Docker container
Figure 1: Graphical performance comparison of none I/O schedulers in VM vs Docker container

Figure 2 shows the performance comparison of mq-deadline I/O schedulers in a virtual machine versus a Docker container.

Table 2: mq-deadline I/O scheduler results
File size Real-time in Ubuntu 20.04 (in seconds) Real-time in Docker and container (in seconds) Percentage improvement
10MB 0.012 0.002 83.33
20MB 0.018 0.003 83.33
30MB 0.024 0.004 83.33
40MB 0.036 0.005 86.11
50MB 0.046 0.007 84.78
60MB 0.051 0.008 84.31
70MB 0.059 0.01 83.05
80MB 0.062 0.012 80.65
90MB 0.072 0.013 81.94
100MB 0.076 0.013 82.89
Graphical performance comparison of mq-deadline I/O schedulers in VM vs Docker container
Figure 2: Graphical performance comparison of mq-deadline I/O schedulers in VM vs Docker container

Figure 3 shows the performance comparison of bfq I/O schedulers in a virtual machine versus a Docker container.

Table 3: bfq I/O scheduler results
File size Real-time in Ubuntu 20.04 (in seconds) Real-time in Docker and container (in seconds) Percentage improvement
10MB 0.012 0.002 83.33
20MB 0.017 0.003 82.35
30MB 0.023 0.004 82.61
40MB 0.038 0.005 86.84
50MB 0.038 0.007 81.58
60MB 0.052 0.008 84.62
70MB 0.058 0.01 82.76
80MB 0.092 0.012 86.96
90MB 0.122 0.013 89.34
100MB 0.128 0.014 89.06
Graphical performance comparison of bfq I/O schedulers in VM vs Docker container
Figure 3: Graphical performance comparison of bfq I/O schedulers in VM vs Docker container

Figure 4 compares the performance of kyber I/O schedulers in VM vs Docker container.

Table 4: kyber I/O scheduler results
File size Real-time in Ubuntu 20.04 (in seconds) Real-time in Docker and container (in seconds) Percentage improvement
10MB 0.013 0.002 84.62
20MB 0.018 0.004 77.78
30MB 0.093 0.004 95.7
40MB 0.073 0.006 91.78
50MB 0.074 0.006 91.89
60MB 0.144 0.009 93.75
70MB 0.111 0.01 90.99
80MB 0.072 0.014 80.56
90MB 0.259 0.014 94.59
100MB 0.162 0.016 90.12
Figure 4: Graphical performance comparison of kyber I/O schedulers in VM vs Docker container

Test 2: Effects of high read latency

This benchmark checks how well the I/O scheduler works when reading several small files while also reading a large file.

The code for changing to none scheduler and then running the Benchmark Test 2 is given below.

Step 1: Perform the read operation in the background.

Step 2: Record the time taken to read every file in the Android SDK.

$ while true; do cat BigFile.txt > /dev/null;done & 
$ echo
$ echo none
$ echo none > /sys/block/sda/queue/scheduler
$ time find ../../../Android/Sdk/. -type f -exec cat ‘{}’ ‘;’ > 
/dev/null # path to Android Sdk

The test results obtained for various I/O schedulers are given in Table 5.

Table 5: Test results obtained for various I/O schedulers
I/O scheduler VM (in seconds) Container (in seconds) Percentage improvement
none 94.133 79.805 17.9537623
mq-deadline 99.765 82.228 21.32728511
kyber 100.315 86.747 15.64088672
bfq 114.214 92.577 23.37189583

 

The performance evaluation of different I/O schedulers (none, kyber, bfq, and mq-deadline) was conducted, and the results showed that the none I/O scheduler outperformed the others in both Test 1 and Test 2. Interestingly, all the I/O schedulers performed better when used inside a container. However, the none I/O scheduler proved to be the most suitable choice for the given test conditions, as it provided the best results for both tests.

These findings are particularly relevant for processes that involve intensive disk access. In such cases, reading from a Docker container is faster and can significantly improve performance. For instance, if there are numerous reading and writing operations, such as reading a .csv file for data analytics and storing the results in a file, the none I/O scheduler can be particularly useful in enhancing performance.

LEAVE A REPLY

Please enter your comment!
Please enter your name here