In this blog post, we’ll look at how ProxySQL improves MySQL SSL connection performance.
When deploying MySQL with SSL, the main concern is that the initial handshake causes significant overhead if you are not using connection pools (i.e., mysqlnd-mux with PHP, mysql.connector.pooling in Python, etc.). Closing and making new connections over and over can greatly impact on your total query response time. A customer and colleague recently educated me that although you can improve SSL encryption/decryption performance with the AES-NI hardware extension on modern Intel processors, the actual overhead when creating SSL connections comes from the handshake when multiple roundtrips between the server and client are needed.
With ProxySQL’s support for SSL on its backend connections and connection pooling, we can have it sit in front of any application, on the same server (illustrated below):
With this setup, ProxySQL is running on the same server as the application and is connected to MySQL though local socket. MySQL data does not need to go through the TCP stream unsecured.
To quickly verify how this performs, I used a PHP script that simply creates 10k connections in a single thread as fast it can:
<?php $i = 10000; $user = 'percona'; $pass = 'percona'; while($i>=0) { $mysqli = mysqli_init(); // Use SSL //$link = mysqli_real_connect($mysqli, "192.168.56.110", $user, $pass, "", 3306, "", MYSQL_CLIENT_SSL) // No SSL //$link = mysqli_real_connect($mysqli, "192.168.56.110", $user, $pass, "", 3306 ) // OpenVPN //$link = mysqli_real_connect($mysqli, "10.8.99.1", $user, $pass, "", 3306 ) // ProxySQL $link = mysqli_real_connect($mysqli, "localhost", $user, $pass, "", 6033, "/tmp/proxysql.sock") or die(mysqli_connect_error()); $info = mysqli_get_host_info($mysqli); $i--; mysqli_close($mysqli); unset($mysqli); } ?>
Direct connection to MySQL, no SSL:
[root@ad ~]# time php php-test.php real 0m20.417s user 0m0.201s sys 0m3.396s
Direct connection to MySQL with SSL:
[root@ad ~]# time php php-test.php real 1m19.922s user 0m29.933s sys 0m9.550s
Direct connection to MySQL, no SSL, with OpenVPN tunnel:
[root@ad ~]# time php php-test.php real 0m15.161s user 0m0.493s sys 0m0.803s
Now, using ProxySQL via the local socket file:
[root@ad ~]# time php php-test.php real 0m2.791s user 0m0.402s sys 0m0.436s
Below is a graph of these numbers:
As you can see, the difference between SSL and no SSL performance overhead is about 400% – pretty bad for some workloads.
Connections through OpenVPN are also better than MySQL without SSL. While this is interesting, the OpenVPN server needs to be deployed on another server, separate from the MySQL server and application. This approach allows the application servers and MySQL servers (including replica/cluster nodes) to communicate on the same secured network, but creates a single point of failure. Alternatively, deploying OpenVPN on the MySQL server means if you have an additional high availability layer in place and it gets quite complicated when a new master is promoted. In short, OpenVPN adds many additional moving parts.
The beauty with ProxySQL is that you can just run it from all application servers and it works fine if you simply point it to a VIP that directs it to the correct MySQL server (master), or use the replication group feature to identify the authoritative master.
Lastly, it is important to note that these tests were done on CentOS 7.3 with OpenSSL 1.0.1e, Percona Server for MySQL 5.7.19, ProxySQL 1.4.1, PHP 5.4 and OpenVPN 2.4.3.
Happy ProxySQLing!