Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
63
Добавлен:
14.03.2016
Размер:
12.64 Mб
Скачать

CHAPTER 23 OPTIMIZING DRUPAL

Often the system takes a performance hit when data must be moved to or from a slower device such as a hard disk drive. What if you could bypass this operation entirely for data that you could afford to lose (like session data)? Enter memcached, a system that reads and writes to memory. Memcached is more complicated to set up than other solutions proposed in this chapter, but it is worth talking about when scalability enhancements are needed in your system.

Drupal has a built-in database cache to cache pages, menus, and other Drupal data, and the MySQL database is capable of caching common queries, but what if your database is straining under the load? You could buy another database server, or you could take the load off of the database altogether by storing some things directly in memory instead of in the database. The memcached library (see www.danga.com/memcached/) and the PECL Memcache PHP extension (see http://pecl.php.net/ package/memcache) are just the tools to do this for you.

The memcached system saves arbitrary data in random access memory and serves the data as fast as possible. This type of delivery will perform better than anything that depends on hard disk access. Memcached stores objects and references them with a unique key for each object. It is up to the programmer to determine what objects to put into memcached. Memcached knows nothing about the type or nature of what is put into it; to its eyes, it is all a pile of bits with keys for retrieval.

The simplicity of the system is its advantage. When writing code for Drupal to leverage memcached, developers can decide to cache whatever is seen as the biggest cause of bottlenecks. This might be the results of database queries that get run very often, such as path lookups, or even complex constructions such as fully built nodes and taxonomy vocabularies, both of which require many database queries and generous PHP processing to produce.

A memcache module for Drupal and a Drupal-specific API for working with the PECL Memcache interface can be found at http://drupal.org/project/memcache.

Optimizing PHP

On Apache servers, you have two ways to execute PHP code: Fastcgi (mod_fcgid, mod_fastcgi, or PHPFPM) or mod_php. The key difference between them is mod_php will execute PHP code directly in Apache, whereas the Fastcgi variants will pass each PHP request to an external php-cgi process, which executes PHP outside of Apache and then pipes its output back to Apache.

On an Nginx web server (more about Nginx later in this chapter), the choice is made simpler because you’re limited to using only the NginxHttpFcgiModule (Fastcgi), as Nginx does not have a builtin PHP interpreter module such as mod_php.

mod_php and the Fastcgi variants perform marginally the same—after all they’re really using the same underlying PHP interpreter running the same PHP code underneath. The only key difference is where their inputs and outputs are being redirected. Unsurprisingly, benchmarking equally sized mod_php and Fastcgi process pools shows nearly the same server loads and Drupal delivery performance. An Apache+mod_php process pool with 25 child processes and an Apache+Fastcgi process pool with 25 PHP processes will have the same overall memory footprint and performance characteristics. However, the Fastcgi variants offer the option of sizing your PHP process pool independently from your Apache process pool, while with mod_php your pool of PHP interpreters is equal to the number of Apache processes. For this reason, some may advocate a Fastcgi approach over mod_php because Fastcgi “saves memory.” This might be true if you ignored APC opcode cache size considerations (also explained here) and you chose to restrict the total number of Fastcgi processes to be dramatically fewer than the number of Apache child processes. However, severely limiting the size of your PHP process pool can severely bottleneck your PHP throughput: that’d be similar to closing three lanes of a busy four-lane highway for no better reason than to “save space” and thereby cause traffic jams.

501

CHAPTER 23 OPTIMIZING DRUPAL

There’s another important memory usage consideration: PHP’s APC opcode cache is shared across mod_php processes (all mod_php processes refer to the same APC cache block), but APC cache is not shared across php-cgi processes when using mod_fcgid. Given that the typical size of an APC opcode cache for a Drupal server could be 50MB or more, this means when using an APC opcode cache (as any reasonable Drupal server should), the entire process pool of Apache and php-cgi processes will altogether use a lot more memory than the same size pool of Apache and mod_php processes.

So which performs better? The answer is neither mod_php nor Fastcgi performs dramatically better than the other when given the same amount of resources. However, you may consider using a Fastcgi option if you want to tune your Apache process pool size differently than your PHP process pool, for other reasons, such as on multi-tenant web servers, because Fastcgi offers user-level separation of processes.

Setting PHP Opcode Cache File to /dev/zero

Both APC and XCache offer an option to set the path of the opcode cache. In APC the path of cache storage, the apc.mmap_file_mask setting, determines which shared memory mechanism it uses. System V IPC shared memory is a decent choice but limited to only 32MB on most Linux systems, which can be raised, but by default it’s not enough opcode cache for typical Drupal sites. POSIX mmap shared memory can share memory blocks of any size; however, it performs quite poorly if that memory is backed by a disk file, as frequent shared memory I/O operations will translate into large and frequent disk I/O operations, which is especially noticeable on slow disks.

The solution is to set your memory map path to /dev/zero, which tells mmap not to back the memory region with disk storage. Fortunately APC uses this mode by default, unless you’ve explicitly set apc.mmap_file_mask to any path other than /dev/zero.

PHP Process Pool Settings

By “PHP process pool” I’m referring to the entire PHP execution process pool on your web server, which determines how many concurrent PHP requests your server can deliver without queuing up requests. The PHP process pool is managed either by Apache+mod_php or some variant of Fastcgi: mod_fcgid, mod_fastcgi, or PHP-FPM (FastCGI Process Manager). The PHP process pool tuning considerations are as follows:

Run as many PHP interpreters as memory will allow. If you’re running mod_php, then your PHP pool size is the number of Apache child processes, which is determined by the Apache config settings StartServers, MinSpareServers, MaxSpareServers, and MaxClients, which can all be set to the same amount to keep the pool size constant. If you’re running a Fastcgi variant, such as mod_fcgid, then your PHP pool size MaxProcessCount, DefaultMaxClassProcessCount, and DefaultMinClassProcessCount, should all be set to the same amount to keep the pool size constant. For an 8GB web server, you may try setting your PHP process pool size to 50, then load test the server by requesting many different Drupal pages with a user client concurrency of 50, and set the think time between page requests of least 1 second per client. If the server runs out of memory and/or begins to scrape swap space, then decrease the number for PHP process pool size and try again. Server load may inevitably climb during such a load load test, but it’s not an issue to be concerned with during this tuning test.

502

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]