Archive for the ‘Apache’ Category
Continued: MySQL connection benchmarking
Posted by Robert Swarthout | Filed under Apache, Benchmarking, MySQL, PHP
I was asked by a fellow Schematicer to see if there was a performance difference if the fourth parameter of mysql_connect was set to true if it would make any difference. I would assume that it would not make any difference but I went ahead and ran the variation to be sure, the results are below.
Run #1:
11409 fetches, 20 max parallel, 45636 bytes, in 600.011 seconds
4 mean bytes/connection
19.0146 fetches/sec, 76.0586 bytes/sec
msecs/connect: 0.211857 mean, 39.668 max, 0.029 min
msecs/first-response: 1050.65 mean, 2662.53 max, 323.514 min
HTTP response codes: code 200 — 11409
Run #2:
11141 fetches, 20 max parallel, 44564 bytes, in 600.005 seconds
4 mean bytes/connection
18.5682 fetches/sec, 74.2727 bytes/sec
msecs/connect: 0.206869 mean, 30.293 max, 0 min
msecs/first-response: 1076.17 mean, 2317.13 max, 350.16 min
HTTP response codes: code 200 — 11141
Run #3:
11183 fetches, 20 max parallel, 44732 bytes, in 600 seconds
4 mean bytes/connection
18.6383 fetches/sec, 74.5533 bytes/sec
msecs/connect: 0.201182 mean, 24.691 max, 0.03 min
msecs/first-response: 1071.81 mean, 2448.18 max, 366.686 min
HTTP response codes: code 200 — 11183
Results Analysis
- Average requests per second: 18.7043
- Average requests completed: 11,244
These results can be compared to the previous post on this topic.
Benchmarking of MySQL Persistent Connections vs Non-Persistent Connections
Posted by Robert Swarthout | Filed under Apache, Benchmarking, PHP
This post will be about the what always seems to be a hot topic among PHPers about what connection type to use when connection to a MySQL database.
I used MySQL 5.0.45, PHP 5.2.4 for this benchmarking. You can download the same sample MySQL database that is used for this set of benchmarking by visiting http://dev.mysql.com/doc/#sampledb. In the list of example databases, choose the one named ’sakila’.
For each connection type I will run three tests to see compensate for variations in tests. I will be using http_load to do the benchmarking of the connection file. To view each of the connection files, download the file bundle at the end of this post.
Below is the benchmark command with the options used for each run.
./http_load -verbose -parallel 20 -seconds 600 urls.txt
The urls.txt file contains the following:
http://127.0.0.1/mysql_connection_bench_{CONNECT_TYPE}.php
Between each benchmark run I will restart both Apache and MySQL.
Results for the standard MySQL functions in PHP using mysql_connect.
Run #1:
11024 fetches, 20 max parallel, 44096 bytes, in 600.007 seconds
4 mean bytes/connection
18.3731 fetches/sec, 73.4925 bytes/sec
msecs/connect: 0.22087 mean, 48.992 max, 0.03 min
msecs/first-response: 1087.74 mean, 2880.95 max, 355.012 min
HTTP response codes: code 200 — 11024
Run #2:
10895 fetches, 20 max parallel, 43580 bytes, in 600.004 seconds
4 mean bytes/connection
18.1582 fetches/sec, 72.6328 bytes/sec
msecs/connect: 0.219867 mean, 48.58 max, 0.031 min
msecs/first-response: 1100.1 mean, 2623.47 max, 369.341 min
HTTP response codes: code 200 — 10895
Run #3:
11134 fetches, 20 max parallel, 44536 bytes, in 600.003 seconds
4 mean bytes/connection
18.5566 fetches/sec, 74.2264 bytes/sec
msecs/connect: 0.217796 mean, 42.036 max, 0.03 min
msecs/first-response: 1076.59 mean, 3079.73 max, 270.734 min
HTTP response codes: code 200 — 11134
Results for the standard MySQL functions in PHP using mysql_pconnect.
Run #1:
10982 fetches, 20 max parallel, 43928 bytes, in 600.025 seconds
4 mean bytes/connection
18.3026 fetches/sec, 73.2103 bytes/sec
msecs/connect: 0.216663 mean, 69.795 max, 0 min
msecs/first-response: 1091.52 mean, 3166.82 max, 254.36 min
HTTP response codes: code 200 — 10982
Run #2:
11002 fetches, 20 max parallel, 44008 bytes, in 600.001 seconds
4 mean bytes/connection
18.3366 fetches/sec, 73.3465 bytes/sec
msecs/connect: 0.20555 mean, 47.176 max, 0.031 min
msecs/first-response: 1089.51 mean, 2953.82 max, 414.826 min
HTTP response codes: code 200 — 11002
Run #3:
11196 fetches, 20 max parallel, 44784 bytes, in 600 seconds
4 mean bytes/connection
18.66 fetches/sec, 74.6399 bytes/sec
msecs/connect: 0.2013 mean, 22.478 max, 0.03 min
msecs/first-response: 1070.5 mean, 2506.02 max, 448.161 min
HTTP response codes: code 200 — 11196
Results for non-persistent connections with PDO_MYSQL.
Run #1:
10995 fetches, 20 max parallel, 43980 bytes, in 600.008 seconds
4 mean bytes/connection
18.3248 fetches/sec, 73.299 bytes/sec
msecs/connect: 0.203731 mean, 17.309 max, 0.029 min
msecs/first-response: 1090.44 mean, 2852.34 max, 358.45 min
HTTP response codes: code 200 — 10995
Run #2:
10971 fetches, 20 max parallel, 43884 bytes, in 600.002 seconds
4 mean bytes/connection
18.285 fetches/sec, 73.1398 bytes/sec
msecs/connect: 0.21357 mean, 32.036 max, 0 min
msecs/first-response: 1092.36 mean, 3515.71 max, 456.688 min
HTTP response codes: code 200 — 10971
Run #3:
11161 fetches, 20 max parallel, 44644 bytes, in 600.001 seconds
4 mean bytes/connection
18.6016 fetches/sec, 74.4065 bytes/sec
msecs/connect: 0.20571 mean, 31.679 max, 0.031 min
msecs/first-response: 1073.96 mean, 2539.06 max, 351.236 min
HTTP response codes: code 200 — 11161
Results for persistent connections with PDO_MYSQL.
Run #1:
10347 fetches, 20 max parallel, 41388 bytes, in 600.006 seconds
4 mean bytes/connection
17.2448 fetches/sec, 68.9793 bytes/sec
msecs/connect: 0.253049 mean, 96.354 max, 0 min
msecs/first-response: 1158.52 mean, 2596.78 max, 282.647 min
HTTP response codes: code 200 — 10347
Run #2:
11106 fetches, 20 max parallel, 44424 bytes, in 600.008 seconds
4 mean bytes/connection
18.5098 fetches/sec, 74.0391 bytes/sec
msecs/connect: 0.226898 mean, 51.29 max, 0.03 min
msecs/first-response: 1079.29 mean, 2393.4 max, 311.85 min
HTTP response codes: code 200 — 11106
Run #3:
10978 fetches, 20 max parallel, 43912 bytes, in 600.029 seconds
4 mean bytes/connection
18.2958 fetches/sec, 73.1831 bytes/sec
msecs/connect: 0.210895 mean, 30.339 max, 0 min
msecs/first-response: 1091.98 mean, 3455.6 max, 373.751 min
HTTP response codes: code 200 — 10978
Results Analysis
- mysql_connect
- Average requests per second: 18.3626
- Average requests completed: 11,017
- mysql_pconnect
- Average requests per second: 18.4330
- Average requests completed: 11,060
- PDO_MySQL non-persistent
- Average requests per second: 18.4038
- Average requests completed: 11,042
- PDO_MySQL persistent
- Average requests per second: 18.0168
- Average requests completed: 10,810
Basically what the numbers above shows us is that in an isolated environment it makes no difference which connection type you are going to use. My past experience in live heavily trafficked environment says that using non-persistent connections is better than using persistent connections. Where this difference comes shows itself the most is when an apache thread will hang and still hold the persistent connection to mysql preventing other apache processes from connecting. By tweaking your apache and mysql settings you can achieve very good performance with non-persistent connections.
Source files for this benchmarking test.
PHP Subversion Frontend – Part 1
Posted by Robert Swarthout | Filed under Apache, PHP, Subversion
Update: I no longer own/work for the company where I did this work. I do not have access to this code or the rights to distribute it, sorry.
——-
I am going to begin the process of explaining how to setup a PHP frontend to a remote subversion (SVN) working copy. The post today will talk about how to correctly setup apache to work in a multi-user setup.
One of the the nice things about SVN is that it keeps track of who changes what line and what changes they made on that line. SVN bases the username it stores on who committed the file. The trick in getting a PHP frontend to SVN to work correctly is that the user that apache is running as needs to be the user who is performing the commit action. To do this and make it work in a multiple user environment I have setup apache to proxy through requests to a specific URL to another instance of apache running as the needed user. In this setup you will need to have mod_proxy either loaded or compiled into your apache setup.
For example a request sent to http://rswarthout.svn.dummydomain.com would be routed through a proxy in apache to another instance of apache at http://127.0.0.1:8001. This internal address will handle the apache requests and pass it back to the web facing apache server instance.
The apache virtual host config below is for the web facing apache instance:
<VirtualHost 12.34.56.78:80>
ServerName rswarthout.svn.dummydomain.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8001/
ProxyPassReverse / http://127.0.0.1:8001/
<VirtualHost>
You will need to start a seperate instance of apache and pass it the config file to run. The config file below will start apache and have it listen on IP 127.0.0.1 only on port 8001.
Listen 127.0.0.1:8001
LoadModule php5_module modules/libphp5.so
AddType application/x-httpd-php .phpDocumentRoot “/home/svn.dummydomain.com/public_html”
<Directory “/home/svn.dummydomain.com/public_html”>
Options -Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>User rswarthout
Group rswarthoutDirectoryIndex index.php index.html
php_admin_value include_path “.:/home/svn.dummydomain.com/:/usr/share/pear”
In the above apache config you will see that I am setting the include path for PHP as well in the last line. This is not a requirement but it is good practice to only have files accessible through apache that need to be. To start a seperate instance of apache with the above config run the following command.
/path/to/apache/httpd -f /path/to/above/config/file.conf
That is all for this piece of the puzzle. Next time I will begin to explain the PHP side of the puzzle. When this puzzle is broken up into its smaller pieces it is quite easy to work through.
IE 6, Apache mod_deflate, blank pages…
Posted by Robert Swarthout | Filed under Apache, IE
I just ran across an interesting bug in IE 6 when a page is loading an external javascript file. If Apache is outputting the external javascript compressed (gzip) IE will do one of the following things:
- Return a blank page
- Try loading the page forever
Prior to finding this bug, our apache settings for mod_deflate looked like…
AddOutputFilterByType DEFLATE text/html text/css text/xml text/plain application/x-javascript
Now it looks like…
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.[0678] no-gzip
BrowserMatch \bMSIE\s7Â !no-gzip !gzip-only-text/html
Making these changes seemed to have fixed the issue. Now when a page is loaded in IE6, any external javascript file will not be gzipped and their page load will be slower. I suppose that is punishment for not upgrading to IE7 or getting Firefox.
PHP frontend to Subversion (SVN)
Posted by Robert Swarthout | Filed under Apache, PHP, Subversion
So over the last week I have been working on and off with a PHP frontend to SVN. The frontend needed to be designed in such a way that each developer could access their working copies and make the full range of actions against them. I decided to also use an AJAX setup so that pages would be quickly loaded and updated by a single toggle of a folder. The first issue that I had to deal with was when a SVN command was issues it needed to be issued as the owner of the code so that SVN could track edits correctly. After googling around for a bit I quickly realized that there was not a viable Apache MPM that would serve virtual hosts under different users and groups. Then the light bulb flipped on, setup a proxy and redirect requests to developer.dev.domain.com to its own instance of apache running as the user and group ‘developer’. This would ensure that all SVN commands would run as ‘developer’ when executed. I then moved onto setting up the interface. The features that are working at this time are:
- create working copy from repository (svn checkout)
- delete working copy
- svn add
- svn blame
- svn commit
- svn copy
- svn delete
- svn diff
- svn move
- svn propset
- search files (via a grep/find combination, omitting .svn folders)
- svn log
- svn rename
- svn status
- update local working copy
- update stage environment
- publish stage environment
A few things that I learned while working with doing the SVN commands was that when executing a command via the php function exec() I need to add the flag –config-dir=$USER_HOME_DIR/.subversion (or where ever the users .subversion folder is located). Also if a command does not seem to be executing correctly you can add “2>&1″ without quotations to the command being run and it will return any error messages through the $ouput variable for exec();