-
Notifications
You must be signed in to change notification settings - Fork 18.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slow IO performance inside container compared with the host. #21485
Comments
Is this above the performance degradation described in the docs? |
hi @alkmim it seems you are using loop device not real device, is it ? loop device is slow |
@alkmim with "A data volume was used as the partition were to execute the benchmark." do you mean, that a volume is used, e.g. |
Hi. @thaJeztah: Yes. Considering I am using data volume (-v /some/path) to execute the benchmark, a performance degradation of 60% is too much. |
@alkmim what is the backing filesystem that |
@thaJeztah: It is an ext4 on an lvm. I'm not sure why docker did not detect it.
|
@alkmim Please provide the exact commands you've used to run the container and the benchmarks. |
Hello @unclejack The container was started running: docker run -v /datavolume:/datavolume opensuse /bin/bash The benchmark used was the iometer. |
@alkmim You're using devicemapper with loopback mounted block devices. This is known to have poor performance and it's also potentially unsafe. You've mentioned that bind mounts were being used with Loopback mounted block devices have poor performance. This is something to be expected. Docker makes use of the exact same loopback mounted block devices by default for devicemapper. There's nothing Docker itself can do to gain back the loss in performance when using the loopback mounted storage over using the host's disk directly. You might want to take a look at the official docs on storage drivers to figure out how to get a setup which uses devicemapper on real block devices. You might also want to try to make use of the bind mounted storage for benchmarks. There's nothing more to investigate for this issue. I'll close it now. Please feel free to comment. |
@unclejack: I posted the wrong command and forgot to add the configuration file for the tests on the container. The attachment had just the configuration file for the execution on the host. This is the reason why you saw the tests running on the "/". I'm sorry for this mistake. I did use the "-v" option followed by the path. The container was started running: The configuration file I sent was for the test on the host. I forgot to send you the configuration file for the test on the container. I'm sorry for this. Attached are both configuration files. I just changed the "Test Description" field to protect confidential information. Sorry for the confusion. Could you please re-open the issue? |
I am also noticing that when my containers writes data on my host with "docker run -v /workspace:/home/workspace ...", etc. it is so much slower than when I run my services directly on my host. Is this bug being fixed on docker already? |
This does not happen only on docker version 1.9.1 as the original author has posted, it's on 1.11.1 as well... It's still very easy to replicate the results on my environment and to verify that the performance can be improved on docker vs host. Here is the information from my environment to compare this:
|
My kernel is: 3.16.7-35 As from the tests above, the difference between 100kB/s to 30kB/s impacts my applications when I use docker containers. I have installed all the latest components available to test this. |
I don't see these differences (although timing between runs can differ quite a bit); On the host; [root@fedora-2gb-ams3-01 ~]# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 1.11208 s, 460 kB/s
real 0m1.114s
user 0m0.000s
sys 0m0.075s
[root@fedora-2gb-ams3-01 ~]# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 1.05731 s, 484 kB/s
real 0m1.059s
user 0m0.003s
sys 0m0.071s
[root@fedora-2gb-ams3-01 ~]# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 0.743486 s, 689 kB/s
real 0m0.745s
user 0m0.005s
sys 0m0.048s In a container (I added "read-only", to verify that nothing is written to the container's filesystem); [root@fedora-2gb-ams3-01 ~]# docker run --rm --read-only -it --net=host -v "/workspace:/workspace" opensuse bash
bash-4.2# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 0.789156 s, 649 kB/s
real 0m0.790s
user 0m0.000s
sys 0m0.048s
bash-4.2# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 0.901782 s, 568 kB/s
real 0m0.903s
user 0m0.006s
sys 0m0.048s
bash-4.2# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync
1000+0 records in
1000+0 records out
512000 bytes (512 kB) copied, 1.04446 s, 490 kB/s
real 0m1.047s
user 0m0.002s
sys 0m0.071s |
Running exactly like you did it still slow: rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync1000+0 records in real 0m3.562s rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync1000+0 records in real 0m3.268s rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync1000+0 records in real 0m4.578s docker run --rm --read-only -it --net=host -v "/workspace:/workspace" opensuse bashbash-4.2# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync real 0m19.324s bash-4.2# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync real 0m17.287s bash-4.2# rm -f /workspace/* && time dd if=/dev/zero of=/workspace/test_container1.img bs=512 count=1000 oflag=dsync real 0m17.349s |
If I mount /workspace on a RAM (tmpfs) or use an SSD storage it gets better, but its expensive to have this for every application. What hardware/infrasctructure are you validating this? |
This is simply a fresh install of docker on a DigitalOcean droplet, nothing fancy; Fedora 23 (was preparing to reproduce another issue), 2 GB Memory / 40 GB Disk |
That's why I mentioned that using RAM or SSD might get a different results. If I look at the plans offered by DigitalOceans, they are selling SSD cloud server plans... Currently I am running virtual machines with regular disks and physical ones all running on openSUSE. |
But SSD or not; it's about the difference between in a container and outside. @cyphar can you reproduce this on OpenSUSE? |
That's why I am worried... Even if I setup it fine on my environment, its not like I could ask everybody to adopt this SSD disk solution in order to have the same hardware as I recommend... I am investigating this on Ubuntu as well just to make sure its not openSUSE's specific... But it also happens on SLES 12. |
So, on Ubuntu I got results closer to yours, @thaJeztah, thanks for looking... There was not much impact when running on a host vs a container. Unfortunately there is no aufs driver on docker for openSUSE/SLES... Looks like something related with the storage driver, either btrfs I that am experiencing and devicemapper that @alkmim posted when this issue was reported. Here is another VM (Ubuntu 14-04LTS) I have set on the same hardware as the openSUSE 13.2's:
|
Basically, there should be no impact; when using a bind-mounted directory, or a volume, there's nothing between the process and the disk, it's just a mounted directory. The only thing that docker can do, is set a constraint (but these are disabled by default), such as;
|
There is nothing special with the directory I am using as a volume to share, its just a regular folder on the host. The only difference I could think of was the storage-driver that docker was using. So I am clueless then how to get this fixed on SuSE. I tried using the constrains, but there was no difference on the transfer rates:
Changing "--device-write-bps", etc. makes it hang, so I could not test this one. |
Mounting the shared folder (/workspace) on RAM makes it run instantaneously, but then again, it's an expensive resource like SSD. I'm still having performance issues when running applications on HDD storages... What puzzles me is how come docker, as just like a regular process writing on my folder could be so much slower?
|
@ipeoshir I can't reproduce this on Tumbleweed. I believe it's probably a kernel issue, since Docker doesn't do anything special with bindmounts. Can you try to reproduce this on an openSUSE distribution with a newer kernel (for example openSUSE Leap or Tumbleweed)? openSUSE 13.2 has very old packages.
|
Can you run |
@ipeoshir I have some proposed fixes from our kernel team, which were mirrored in the internal ticket. Basically it boils down to three options that can help the performance:
|
@cyphar, thanks! |
Suggestions for:
However the overall performance is still slower, I can noticed that as described in #23137. In the bug id 980615 we expect to fix the performance in general, I believe the root cause is not addressed in this case. Perhaps we can update it to not mention "ext3 and ext4 journaled filesystems", but then we would have to open another bugzilla anyway... So let's try to fix the root cause and figure out why it's impacting docker on SuSE.. |
The problem @ipeoshir is that the only solution from the Docker (runC + libcontainer) side is non-trivial (I describe it in opencontainers/runc#861). And from the kernel side as far as I understand it's a fundamental design of how the CFQ IO scheduler works when weighting different cgroups (this is an upstream kernel thing). I'm not sure why it doesn't appear to happen on Ubuntu, but I'm going to look at it to see why that's the case. To be clear, the filesystem isn't the cause. It's because of how IO scheduling works in the kernel. |
Well, we better wait for a good fix then. I have a more detailed spreasheet with the same use case running on ext2 on containers, ext3 on containers and ext3 on host and during a certain step (package installation) the time measure was this: 6812, 7206, 887 respectively, so it's really a bottleneck to proceed using docker. |
@cyphar, @flavio, I added more detailed information on: bugzilla number 983015. Tracing the versions of docker that can be installed on SLES12, this bug first appeared in "docker-1.5.0-23.1" while version "docker-1.5.0-20.1" and older had no issue with performance lags. Installing just 34 packages on containers is taking "1m12.571s" (1.5.0-23.1 and newer) against "0m3.614s" (1.5.0-20.1 and older) when this issue is not there. Version 1.5.0-20.1 has the same performance when running on the host, so there could be some way to fix this on docker as this was working fine at some point. |
This appears to be something we changed in the SUSE package (my guess is that we backported a patch that caused this). I'm trying to pin down what revision caused this. |
Not sure if it was a patch... I downloaded the binaries directly from docker, extracted them and it also had the issue. |
@ipeoshir But the |
Yes, on the bugzilla I used solely packages from SLES12 to get the results for you. But to test the binaries I downloaded from: ** And replaced the RPM binary (in this case it was an openSUSE 13.2) with those non-patched binaries, just to make sure it was not something from the distribution... So it's probably on docker's source code. In there (openSUSE) we can detect the latency problems between 1.5.0-21.1 and 1.6.0-25.1 available on the update repo (http://download.opensuse.org/repositories/openSUSE:/13.2:/Update/standard). On SLES12 the difference is on those two package versions I pointed out... |
This issue resulted in #24307 (which fixes the odd regression between 1.5.0 packages). In addition, we discovered that the reason that Ubuntu doesn't have this problem is because Ubuntu uses the In any case, this issue can be closed (everything has been done on the Docker side that is possible). /cc @thaJeztah |
thanks @cyphar, and thanks for doing the research |
Why the test outside the container/cgroup is not impacted by the bug/slow performance? Isn't the I/O scheduler always in the data path, cgroup or not? |
@mimizone According to the kernel guys at SUSE, the reason is that the CFQ IO scheduler will add latency to requests in order to make sure that two racing cgroups don't starve one another. I don't fully understand the code behind it, but that's what they told me and the experimental results back this up (deadline scheduler would never dream of adding latency). |
Output of
docker version
:Output of
docker info
:Additional environment details (AWS, VirtualBox, physical, etc.):
Steps to reproduce the issue:
Describe the results you received:
Below is a table showing the results. For all tests, the performance inside the container was around 40% of the performance of the host.
Describe the results you expected:
I expected the performance of the container be closer to the host.
The text was updated successfully, but these errors were encountered: