Now that we have our Percona Server Docker images, I wanted to measure the performance overhead when we run the database in the container. Since Docker promises to use a lightweight container, in theory there should be very light overhead. We need to verify that claim, however. In this post I will show the numbers for CPU and network intensive workloads, and later I will take a look at IO.
For the CPU-bound load, I will use a sysbench OLTP read-only workload with data fitting into memory (so there is no IO performed, and the execution path only goes through the network and CPU).
My server is 24 cores (including hyper-threads), with Intel(R) Xeon(R) CPU E5-2643 v2 @ 3.50GHz CPUs, RAM: 256GB, OS: Ubuntu 14.04. The Docker version is the latest on the day of publishing, which is 1.9.1.
First, I measured the throughput on a bare server, without containers – this will be the baseline. For reference, the command I used is the following:
/opt/sysbench/sysbench --test=/opt/tests/db/oltp.lua --oltp_tables_count=8 --oltp_table_size=10000000 --num-threads=16 --mysql-host=172.18.0.2 --mysql-user=root --oltp-read-only=on --max-time=1800 --max-requests=0 --report-interval=10 run
On the bare metal system, the throughput is 7100 transactions per second (tps).
In the next experiment, I started Percona Server in a Docker container and connect to it from the host:
docker run -e MYSQL_ALLOW_EMPTY_PASSWORD=1 --name ps13 -p 3306:3306 -v /data/flash/d1/:/var/lib/mysql -v /data/flash/my.cnf:/etc/my.cnf percona/percona-server:5.6.28
In this case, the container exposed port 3306 to the host, and we used that as an access point in sysbench.
The throughput in this scenario is 2200 tps!!! That is a significant overhead. I suspect it comes from the Docker gateway, which is added to the execution path when we connect through port forwarding.
So to avoid the Docker gateway, in the next run I used the host network by running the container with --net=host:
docker run -e MYSQL_ALLOW_EMPTY_PASSWORD=1 --name ps13 -v /data/flash/d1/:/var/lib/mysql -v /data/flash/my.cnf:/etc/my.cnf --net=host percona/percona-server:5.6.28
In this case the container ran directly in the host network stack, so this should exclude any Docker network overhead. In this case, the throughput is basically back to 7100 tps.
From these tests, I can make an important conclusion. There is NO measurable CPU overhead when running Percona Server in a Docker container. But the network path raises some questions.
So in the next experiment I ran both sysbench and MySQL in two different containers, connected over the Docker network bridge.
I created a sysbench container, which you can get from:
To run sysbench:
docker run --name sb -t percona/sysbench
Just for the reference, I created a Docker network:
docker network create sysbenchnet
and connected both containers to the same network:
docker network connect sysbenchnet ps13; docker network connect sysbenchnet sb;
In this configuration, the throughput I’ve observed is 6300 tps.
So there is still some network overhead, but not as significant as with the port gateway case.
For the last example, I again excluded the network path and ran the sysbench container inside the MySQL container network stack using the following command:
docker run --name sb --net container:ps13 -t percona/sysbench
The throughput in this configuration is back to 7100 tps.
And the conclusion, again, is that there is no CPU overhead even if we run both client and server inside containers, but there is some network overhead – even when running on the same host. It will be interesting to measure the network overhead when the containers are on different physical hosts.
The following chart summarizes the results:
Next time I will try to measure IO overhead in Docker containers.