May 272010
 

Introduction

We all know that backups are awesome … until we try to find the time to set them up or the space to store them. We all know that without backups we “may” see that day when we boot up our computer and our data isn’t there for whatever reason. How can we simplify backups and more importantly initiate them client side?

rdiff-backup

The backup utility that I use to accomplish backing up roaming clients is rdiff-backup. This simple python wrapper for rsync simplifies keeping incremental backups and backup sets for a historical set of backups. By default rdiff-backup is pretty versatile and its documentation is fairly extensive.

What they don’t mention is how to automate these backups with an ssh key to a remote system and a cron job as a scheduler.

The cron job

The cron job is very very simple and highly adaptable:

/usr/bin/rdiff-backup –remote-schema ‘ssh -i /home/alunduil/.ssh/backup_dsa %s rdiff-backup –server’ –exclude-other-filesystems –print-statistics /home/alunduil daneel.alunduil.com::elijah-backup && /usr/bin/rdiff-backup –remote-schema ‘ssh -i /home/alunduil/.ssh/backup_dsa %s rdiff-backup –server’ –remove-older-than 7D –force daneel.alunduil.com::elijah-backup

Now let’s break this down so you can make it yours:

  • /usr/bin/rdiff-backup – Our script of course
  • –remote-schema – The trick that makes it work. This actually allows you to specify the way ssh is called by rdiff-backup allowing a lot of control over how it authenticates and what happens on the server
  • –exclude-other-filesystems – Specifies to stay on the mountpoint it started on
  • –print-statistics – Prints some nice information about the backup when it finishes
  • /home/alunduil daneel.alunduil.com::elijah-backup – The source and destination of the backup
  • && – Just making sure we don’t delete old backups without having a good one (trust me you want it this way)
  • –remove-older-than 7D –force – Force the removal of any backups that are older than one week

Conclusion

Creating a backup of a roaming client should be easy and with rdiff-backup with cron it certainly is. You have complete control over when and where your backups reside and it can be set to run on boot or any other condition. This is ideal for hosts that don’t always have an internet connection or who have uptimes of less than 50%.

APC Caching PHP

 Linux Guides  Comments Off
May 262010
 

Introduction

Making PHP run faster is usually pretty easy when you see some of the code that people can write (myself included) but what if we either don’t want to look at their code or don’t want to fix the code? What else can we do to improve the runtime and the load time of PHP web sites (this website included)?

We’ll cover how to use APC (Alternative PHP Cache) to help alleviate some of the issues of a slow web site. Just like last time we optimized MySQL and talked about optimizing Apache we’ll continue on the path to getting PHP applications as fast as we can (without touching a line of code).

Enter APC

APC is PEAR project and a PHP module that after installed and a restart of Apache is already doing some work to make life better. By default APC turns on op-code caching which saves on the compile and execution times of PHP. The configuration for this module is pretty straight forward, but let’s look at a copy of the one I’m using:

; /etc/php/apache2-php5/ext-active/apc.ini (On Gentoo anyways …)
extension=apc.so
apc.enabled=”1″
apc.shm_segments=”4″
apc.shm_size=”128″
apc.num_files_hint=”1024″
apc.ttl=”7200″
apc.user_ttl=”7200″
apc.gc_ttl=”3600″
apc.cache_by_default=”1″
;apc.filters=”"
;apc.mmap_file_mask=”/tmp/apcphp5.XXXXXX”
apc.slam_defense=”0″
apc.file_update_protection=”2″
apc.enable_cli=”0″
apc.max_file_size=”1M”
apc.stat=”1″
apc.write_lock=”1″
apc.report_autofilter=”0″
apc.include_once_override=”0″
apc.rfc1867=”0″
apc.rfc1867_prefix=”upload_”
apc.rfc1867_name=”APC_UPLOAD_PROGRESS”
apc.rfc1867_freq=”0″
apc.localcache=”0″
apc.localcache.size=”512″
apc.coredump_unmap=”0″

Zooming In

These options are documented fairly thoroughly in the APC PHP Manual.

Most of these options can stay at their defaults and provide a pleasant experience but if we have the memory we should probably tweak these to get more out of them:

  • apc.shm_segments – The number of chunks to use from /dev/shm.
  • apc.shm_size – The size of aforementioned chunks.

These two parameters are the heart of APC and dictate the memory usage you’ll get out of it. If you take segments*size you’ll get the maximum amount of shm space used by APC for the cache. A limitation on shm_size is usually in place through the kernel and to determine what this is you can simply `cat /proc/sys/kernel/shmmax` (remember this command prints out B and APC expects MB).

Further Caching

APC also has an object cache available which can be used for just about anything but the application has to be modified to support this. If you’re using WordPress to host your site an excellent plugin for doing this is W3 Total Cache.

Conclusion

APC can help you get an edge out of your server but, without careful tuning, won’t get you more than the last inch of performance. Play with the memory settings until it isn’t over-utilizing memory (have a larger cache than your code base needs) or under-utilizing memory (having a smaller cache than your code base needs) but don’t forget you don’t want it to run into your swap space.

 

A hot topic for anyone running MySQL and Apache on any machine is optimization and I hope to quickly explain how to optimize MySQL and where to tweak Apache to help with it’s operational efficiency as well.

First things first …

A few common things to possibly turn on, install, or enable:

  • APC (Another PHP Cache)
  • Memcached

MySQL Optimization

The easiest way (and the quickest) to determine what can be done to optimize MySQL is to use a script called mysqltuner.pl. The really interesting thing about this script is that to get it you simply run the following:

wget mysqltuner.pl

After you’ve gotten this script run it with your perl interpreter:

perl mysqltuner.pl

It will prompt you for your username and password for mysql and then print out a nice report outlining how your mysql daemon has been running. Here’s an example of this output:

>> MySQLTuner 1.0.1 – Major Hayden
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/
>> Run with ‘–help’ for additional options and output filtering
Please enter your MySQL administrative login: root
Please enter your MySQL administrative password:

——– General Statistics ————————————————–
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.0.90-log
[OK] Operating on 32-bit architecture with less than 2GB RAM

——– Storage Engine Statistics ——————————————-
[--] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 28M (Tables: 96)
[--] Data in InnoDB tables: 1M (Tables: 55)
[!!] Total fragmented tables: 2

——– Performance Metrics ————————————————-
[--] Up for: 1h 39m 49s (24K q [4.163 qps], 354 conn, TX: 9M, RX: 34M)
[--] Reads / Writes: 60% / 40%
[--] Total buffers: 148.6M global + 960.0K per thread (100 max threads)
[OK] Maximum possible memory usage: 242.3M (11% of installed RAM)
[OK] Slow queries: 0% (0/24K)
[OK] Highest usage of available connections: 28% (28/100)
[OK] Key buffer size / total MyISAM indexes: 64.0K/6.3M
[OK] Key buffer hit rate: 99.6% (164K cached / 682 reads)
[OK] Query cache efficiency: 81.3% (14K cached / 17K selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 463 sorts)
[!!] Joins performed without indexes: 42
[OK] Temporary tables created on disk: 12% (54 on disk / 417 total)
[OK] Thread cache hit rate: 70% (106 created / 354 connections)
[!!] Table cache hit rate: 2% (48 open / 2K opened)
[OK] Open file limit used: 9% (95/1K)
[OK] Table locks acquired immediately: 98% (7K immediate / 7K locks)
[!!] Connections aborted: 7%
[OK] InnoDB data size / buffer pool: 1.0M/4.0M

——– Recommendations —————————————————–
General recommendations:
Run OPTIMIZE TABLE to defragment tables for better performance
MySQL started within last 24 hours – recommendations may be inaccurate
Adjust your join queries to always utilize indexes
Increase table_cache gradually to avoid file descriptor limits
Your applications are not closing MySQL connections properly
Variables to adjust:
join_buffer_size (> 128.0K, or always use indexes with joins)
table_cache (> 48)

The first thing to notice is that mysql should be running for 24 to 48 hours before you trust the results of this script. The second thing to acknowledge is that it isn’t omniscient. Understanding how these parameters affect your memory footprint and your runtime efficiency are what we’re most interested in though.

Glossary of Parameters

The best source of my.cnf parameters is of course the MySQL documentation, but I’ll clarify a few of the more pertinent items from the above output.

  • Maximum Possible Memory – This is not the actual hard limit on your memory usage but a calculated theoretical maximum based on the parameters in your my.cnf and if this is over ~90% you may use your swap more than you want to. After making any changes I suggest you check this to make sure you haven’t over-allocated yourself.
  • Highest Usage of Available Connections – This is the historical max connections used by mysql and if it’s at 100% this isn’t a guarantee that you need to increase max_connections but may just indicate that your connections spiked once. That being said I recommend following its advice if you have the memory for it.
  • Query Cache Efficiency – The hit rate for the cache on your queries (I hope you have enabled). As with any hash table if you’re not hitting what’s in the top bucket you need to increase the number of buckets.
  • Temporary Tables Created on Disk – This can be a finicky parameter to get right and is the first place I would recommend cutting if you don’t have the memory to run mysql like you would want, but if you do have the memory then up this as far as you can within reason.
  • Thread Cache Hit Rate – Just like any other cache.
  • Table Cache Hit Rate – Just like any other cache.

Fragmented Tables

If you noticed the fragmented tables along with the recommendation to run OPTIMIZE TABLE that’s not something that will typically slow mysql down noticeably with today’s disks, but if you want to defragment them I recommend reading this article on the topic.

Apache Tweaking

The following parameters are usually in httpd.conf unless you run a distribution that organizes apache in an easier to work with manner (my preference of course is Gentoo which stores these parameters in: 00_mpm.conf).

The parameters for tweaking apache’s processes depend on which worker module you have in use. The following is the pertinent sections from my configuration:

#prefork MPM
# This is the default MPM if USE=-threads
#
# MinSpareServers: Minimum number of idle child server processes
# MaxSpareServers: Maximum number of idle child server processes

StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 50
MaxRequestsPerChild 500

# worker MPM
# This is the default MPM if USE=threads
#
# MinSpareThreads: Minimum number of idle threads available to handle request spikes
# MaxSpareThreads: Maximum number of idle threads
# ThreadsPerChild: Number of threads created by each child process

StartServers 2
MinSpareThreads 15
MaxSpareThreads 50
ThreadsPerChild 25
MaxClients 150
MaxRequestsPerChild 1000

These parameters are pretty self explanatory but just for completeness’ sake I’ll do a small recap on these here:

* StartServers – The number of servers to have running and handling connections at first launch.
* MinSpareServers – The minimum number of servers to have running not currently handling connections.
* MaxSpareServers – The maximum number of servers to have running not currently handling connections.
* MaxClients – The maximum number of clients that can simultaneously connect to Apache.
* MaxRequestsPerChild – The maximum number of requests that a child will respond to before terminating.

Using these parameters we can control the amount of memory that Apache will consume at the cost of other things we may want to have like lots of connections or many sequential requests.

Conclusion

There are a lot of different things that can be done for a server that seems to be performing less than ideally and I’ve only covered a fraction of things that can happen. As always with this topic the situation will change based on your needs and how your server runs, but at least now you may have a starting point for what to modify after you’ve troubleshooted every other thing that could go wrong.

© 2011 Alunduil's Hosting Suffusion theme by Sayontan Sinha