Monday, February 09, 2009

Speaking at Mysql Conf 2009: Architecture and Technology, Cloud Computing, LAMP, Replication and Scale-Out

I'll be going into detail what is Sharding, how to Shard, pitfalls of Sharding, performance/throughput gains, shard roles, and performance scaling in general. I hope to make this the most comprehensive talk to date on the subject in 45 min.

The topic is called Scaling a Widget Company. I'll detail how I setup the data layer for Rockyou. How many transactions per second Rockyou is at, what the infrastructure is comprised of, how 99.999% uptime is achieved and hopefully get into BCP which I probably will not have time to go over.

If you want me to focus on specific aspects on the subject of shard'ing let me know and I will :).

Tuesday, February 03, 2009

How to reduce load and response time in PHP in five minutes

Request time is proportional to server load. If the application response time is big so will be the server's load. To reduce server load, reduce the wait time in the application's response time to serve the request. Below are some steps that I took to remove 1.8 ms overhead on every request to my web server farm.


Tools Needed:
vi
strace
top

Use vi to look at your include path in php.init.
Next use top to find which apache process is consuming the most cpu resources.
Use strace -p [TOP HTTPD PROCESS] -T (-T is for deltas).

In my example the include path is
/usr/share/pear:/usr/lib64/pear:.:/var/www/html/httdocs/


lstat("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000033>
lstat("/usr/share", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000034>
lstat("/usr/share/pear", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000034>
lstat("/usr/share/pear/ams", 0x7fbfff1690) = -1 ENOENT (No such file or directory) <0.000033>
open("/usr/share/pear/ams/include/FreqCapInfo.php", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000036>
lstat("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000037>
lstat("/usr/lib64", {st_mode=S_IFDIR|0755, st_size=65536, ...}) = 0 <0.000034>
lstat("/usr/lib64/php", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000034>
lstat("/usr/lib64/php/pear", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000038>
lstat("/usr/lib64/php/pear/ams", 0x7fbfff1690) = -1 ENOENT (No such file or directory) <0.000037>
open("/usr/lib64/php/pear/ams/include/FreqCapInfo.php", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000038>
open("/var/www/html/ams/include/FreqCapInfo.php", O_RDONLY) = 24 <0.000043>
fstat(24, {st_mode=S_IFREG|0775, st_size=6707, ...}) = 0 <0.000031>
stat("./ams/include/FreqCapInfo.php", 0x7fbfff4778) = -1 ENOENT (No such file or directory) <0.000037>
stat("/usr/share/pear/ams/include/FreqCapInfo.php", 0x7fbfff4778) = -1 ENOENT (No such file or directory) <0.000038>
stat("/usr/lib64/php/pear/ams/include/FreqCapInfo.php", 0x7fbfff4778) = -1 ENOENT (No such file or directory) <0.000036>
stat("/var/www/html/ams/include/FreqCapInfo.php", {st_mode=S_IFREG|0775, st_size=6707, ...}) = 0 <0.000040>
close(24) = 0 <0.000033>
mlock(0x552b876be0, 24) = 0 <0.000092>
mlock(0x552b8df910, 10624) = 0 <0.000038>
munlock(0x552b876be0, 24) = 0 <0.000036>
munlock(0x552b8df910, 10624) = 0 <0.000032>
mlock(0x552b876be0, 24) = 0 <0.001707>
mlock(0x552b8df910, 10624) = 0 <0.000009>
munlock(0x552b876be0, 24) = 0 <0.000007>
munlock(0x552b8df910, 10624) = 0 <0.000007>



Looking at the strace, 15 unneeded system calls are made on every request, each request roughly takes 30 micro seconds, for a total of a few ms wasted on every request. False positives are adding overhead to ever requests since the include path is not optimized. A Bloom Filter in Shared Memory would be perfect for for this part of PHP-but that's besides the point.


So, change your include path
.:/var/www/html/httdocs/:/usr/share/pear:/usr/lib64/pear



For my example I changed the include path to the above. In my environment we don't do many PEAR loads, so it makes sense to use our directories 1st.

By doing this 15 erroneous system calls have been removed. Note: If you use the php feature __autoload make sure to protect your calls with file exist or you may be doing a require once on a file that is in a different directory which is a PHP fatal Error.


UPDATED: Some more goodies to reduce load on PHP boxes:

For PHP 5.2 there is a nice new feature that you can play with

realpath_cache_size. This is a directive native to PHP by default it's set to 16K, this means that PHP expects there to be very few files, but big files. In most environments I have been in this is not the case. The case is there are a lot of files, a lot of directories thus 16K is not enough.

I've tested a few values but 128K seems to be my sweet spot.

realpath_cache_size = 128K