You are here

Part VIII: Drupal

When it comes to Drupal most of the easy performance gains comes from making the right settings in settings.php and enable the right modules to support the cache technologies installed on the server.

Drupal Caching

Drupal comes with build in caching support for pages, blocks and a other content implemented in contribute modules. See the code section for information about using caches in your own code.

The following lines can be added to settings.php to enable all Drupal core caching.

$conf['cache'] = 1;
$conf['block_cache'] = 1;
$conf['preprocess_css'] = 1;
$conf['preprocess_js'] = 1;

When using forms in Drupal they are cached in the database and should not be moved into volatile storage as this could corrupt the forms if cache is cleared. So to ensure that this do not happen add the following line to settings.php.

$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';

Logging

Drupal normally logs watchdog messages to the database, which can introduce an extra load on the database. So sending these to the servers system logging system and not the database can have a huge impact on performance.

First step is to enable the sys-logger and disable the database logger.

~$ drush en syslog -y
~$ drush dis dblog -y

You can configure the syslog by adding this line to settings.php thereby setting the identity used be the server to hit the right log file. You should change SITENAME in the following paragraphs to you sites name.

$conf['syslog_identity'] = 'SITENAME';

Next you have to tell your syslog where to log message from Drupal by adding a file to /etc/rsyslog.d/SITENAME.conf,

$template DRUPAL,"<%PRI%> %TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag% -- %msg%\n"
:syslogtag, contains, "SITENAME" /var/log/drupal/SITENAME.log;DRUPAL

Lastly restart the sys-logger to read the new configuration.

~$ /etc/init.d/rsyslog restart

Memcache(d)

Memcache is a key/value store that lives in memory only and can be used to move temporary data from the database server (cache tables) and direct into memory. This gives a significant performance boots and gives the database server more power to do want it does best.

To enable Drupal to use Memcache for its cache tables you simply install memcached and the PHP integration extension.

~$ apt-get install memcached php5-memcache

To configure memcached edit the file /etc/memcache.conf where the important options are -m (memory) and -l (list). Its important that you protect memcache, by link it to the local interface (127.0.0.1) because memcache have no data protection, so every one can read its contents.

Next download the Memcache module from Drupal.org but you should not enable the module. It contains a new cache backend for Drupal, which you configure via the sites settings.php.

// Memcache configuration.
$conf += array(
  'memcache_extension' => 'Memcache',
  'show_memcache_statistics' => 0,
  'memcache_persistent' => TRUE,
  'memcache_stampede_protection' => TRUE,
  'memcache_stampede_semaphore' => 15,
  'memcache_stampede_wait_time' => 5,
  'memcache_stampede_wait_limit' => 3,
  'memcache_key_prefix' => basename(realpath(conf_path())),
);

// Include cache backends.
include_once('./includes/cache.inc');
include_once('./sites/all/modules/contrib/memcache/memcache.inc');

$conf['cache_backends'][] = 'sites/all/modules/contrib/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';

// Configure cache servers.
$conf['memcache_servers'] = array(
  '127.0.0.1:11211' => 'default',
);
$conf['memcache_bins'] = array(
  'cache' => 'default',
);

Memcached profiling

Memcache may not be performing optimal and you can profile and investigate its performance using tcpdump and the Percona toolkits mk-query-digest program to analyse the communication to your installation of memcache.

See Memcached server profiling with mk-query-digest article for more information about profiling memcache. There are also information available in the documentation at Percona just search for memcache on the page.

Used memory

The PHP script below can be used to find the current usage of memory and thereby help finding the right amount of memory that you should allocate to memcache.

<?php
// Print sizes in a pretty format.
function bsize($size) {
  foreach (array('', 'K', 'M', 'G') as $k) {
    if ($size < 1024) {
      break;
    }
    $size /= 1024;
  }
  return sprintf("%5.1f %sBytes", $size, $k);
}

// Connect to memcache.
$memcache = new Memcache();
$memcache->addServer('localhost', 11211, false);

// Get stats.
$stats = $memcache->getExtendedStats();
$stats = $stats['localhost:11211'];

// Print information about memcache usage.
echo 'Size: ', bsize((real)$stats['limit_maxbytes']), "\n";
echo 'Used: ', bsize((real)$stats['bytes']), "\n";
echo 'Free: ', bsize($stats['limit_maxbytes'] - $stats['bytes']), "\n";
echo 'Read: ', bsize((real)$stats['bytes_read']), "\n";
echo 'Written: ', bsize((real)$stats['bytes_written']), "\n";

echo "\n",'Used percent',"\n";
$used = ((real)$stats['bytes']/(real)$stats['limit_maxbytes']) * 100;
echo 'Used: ', sprintf('%01.2f', $used), "%\n";
echo 'Free: ', sprintf('%01.2f', 100-$used), "%\n";

You can also use the performance report module to look at the memcache usage from inside Drupal.

Another solution to look into the performance of Memcached is the PHPMemcacheAdmin, which gives you a graphical administration interface (like phpMyAdmin for MySQL).

Varnish (Not completed)

// Varnish.
$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
$conf['page_cache_invoke_hooks'] = FALSE;
$conf['varnish_flush_cron'] = 1;
$conf['varnish_version'] = 3;
$conf['varnish_control_key'] = 'FOUND IN VARNISH SECRET FILE';

APC

The fastest cache that you can use in relation to PHP have to by the Op-code cache, so this would be a good place to store the bootstrap cache table. We could in theory use APC for all cache tables but we would ran into problems because APC is really bad at flushing/removing entries from its cache. So it would get fragmented and thereby trashing the performance.

$conf['cache_backends'][] = 'sites/all/modules/contrib/apc/drupal_apc_cache.inc';
$conf['cache_class_cache'] = 'DrupalAPCCache';
$conf['cache_class_cache_bootstrap'] = 'DrupalAPCCache';

Entity cache

Drupal 7 uses the concept of entities under the hood, so caching the load of these will import performance (specially in combination with memcached). So simply download the module and activate it. That's it.

The final settings.php

<?php
// Drupal cache.
$conf['cache'] = 1;
$conf['block_cache'] = 1;
$conf['preprocess_css'] = 1;
$conf['preprocess_js'] = 1;

// Forms cache table.
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';

// Memcache configuration.
$conf += array(
  'memcache_extension' => 'Memcache',
  'show_memcache_statistics' => 0,
  'memcache_persistent' => TRUE,
  'memcache_stampede_protection' => TRUE,
  'memcache_stampede_semaphore' => 15,
  'memcache_stampede_wait_time' => 5,
  'memcache_stampede_wait_limit' => 3,
  'memcache_key_prefix' => basename(realpath(conf_path())),
);

include_once('./includes/cache.inc');
include_once('./sites/all/modules/contrib/memcache/memcache.inc');

$conf['cache_backends'][] = 'sites/all/modules/contrib/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['memcache_servers'] = array(
  '127.0.0.1:11211' => 'default',
);
$conf['memcache_bins'] = array(
  'cache' => 'default',
);

// APC.
$conf['cache_backends'][] = 'sites/all/modules/contrib/apc/drupal_apc_cache.inc';
$conf['cache_class_cache'] = 'DrupalAPCCache';
$conf['cache_class_cache_bootstrap'] = 'DrupalAPCCache';

// Logging.
$conf['syslog_identity'] = 'SITENAME';

// Varnish.
$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
$conf['page_cache_invoke_hooks'] = FALSE;
$conf['varnish_flush_cron'] = 1;
$conf['varnish_version'] = 3;
$conf['varnish_control_key'] = 'FOUND IN VARNISH SECRET FILE';

$conf['cache_lifetime'] = 0;
$conf['page_cache_maximum_age'] = 21600;

References

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.