Improving mod_perl Driven Site's Performance -- Part V: Sharing Memory Page 2

I won't show any benchmarks here, since the effect is absolutely the same as with preloading modules.

Modules Initializing at Server Startup

We have just learned that it's important to preload the modules and scripts at the server startup. It turns out that it's not enough for some modules and you have to prerun their initialization code to get more memory pages shared. Basically you will find an information about specific modules in their respective manpages. I will present a few examples of widely used modules where the code can be initialized.

Initializing DBI.pm

The first example is the DBI module. As you know DBI works with many database drivers falling into the DBD:: category, e.g. DBD::mysql. It's not enough to preload DBI, you should initialize DBI with driver(s) that you are going to use (usually a single driver is used), if you want to minimize memory use after forking the child processes. Note that you want to do this under mod_perl and other environments where the shared memory is very important. Otherwise you shouldn't initialize drivers.

You probably know already that under mod_perl you should use the Apache::DBI module to get the connection persistence, unless you open a separate connection for each user -- in this case you should not use this module. Apache::DBI automatically loads DBI and overrides some of its methods, so you should continue coding like there is only a DBI module.

Just as with modules preloading, our goal is to find the startup environment that will lead to the smallest ''difference'' between the shared and normal memory reported, therefore a smaller total memory usage.

And again in order to have an easy measurement I will use only one child process, therefore I will use this setting in httpd.conf:

  MinSpareServers 1
  MaxSpareServers 1
  StartServers 1
  MaxClients 1
  MaxRequestsPerChild 100

I'm going to run memory benchmarks on five different versions of the startup.pl file. I always preload these modules:

  use Gtop();
  use Apache::DBI(); # preloads DBI as well
option 1
Leave the file unmodified.

option 2
Install MySQL driver (I will use MySQL RDBMS for our test):

It's safe to use this method, since just like with use(), if it can't be installed it'll die().

option 3
Preload MySQL driver module:
  use DBD::mysql;

option 4
Tell Apache::DBI to connect to the database when the child process starts (ChildInitHandler), no driver is preload before the child gets spawned!
                              PrintError => 1, # warn() on errors
                              RaiseError => 0, # don't die on error
                              AutoCommit => 1, # commit executes
                              # immediately
  or die "Cannot connect to database: ::errstr";

This article was originally published on Jan 24, 2001

Thanks for your registration, follow us on our social networks to keep up-to-date