Performance Tuning Techniques

This whitepaper gives performance tuning tips for OpenX ad server administrators.

If you are a publisher with a single web server managing both your website and your OpenX ad server, performance is probably not an issue. But as your website grows, server performance becomes increasingly important. If you use OpenX to display ads on websites for a number of publishers, performance is of deeper concern because they must be confident that you can deliver acceptable performance levels as their businesses grow. This document describes a range of mechanisms you can use to improve performance:

Using PHP cache

OpenX recommends that you use a PHP cache, such as APC cache. Implementation is easy and is likely to provide the single largest improvement in ad serving performance (primarily CPU performance) of any of the techniques described here.

Monitoring routines

It is essential to have good monitoring routines in place for your server operation. It is not sufficient to log in occasionally and gather general information. Effective server monitoring requires that you know the following information at all times:

  • CPU utilisation
  • server load
  • RAM usage
  • level of disk I/O
  • frequency of swapping RAM to disk

Without this information, you will not know where bottlenecks occur in the system and you will not have enough information to increase server capacity at the correct times to cope effectively with growth.

Many excellent network monitoring tools are available, such as:

  • Cricket is a high-performance flexible system for monitoring trends in time-series data.
  • Nagios is an enterprise-class monitoring solution for hosts, services, and networks.
  • OpenNMS is an enterprise-grade network performance platform.

For monitoring the database performance, mytop is a console-based tool which monitors the threads and overall performance of the MySQL server.

Managing disk input/output

OpenX is different to other open source PHP applications which deliver database-driven websites. OpenX delivers content to websites, but most of the server load occurs from logging all impressions and clicks. With so much data to write to the database, it is essential that you manage disk I/O.

If you are expanding OpenX capacity, consider getting a separate, stand-alone database server. This server requires powerful write-capacity so purchase the fastest drives you can afford. The more drives you have in a RAID 0 or RAID 10 configuration, the better. Write operations are faster when you can stripe them across more spindles.

Important: RAID 5 is not recommended.

Storage engine

If you are running OpenX on MySQL, make sure that you use an appropriate storage engine for your tables.

Storing creative content

You can improve performance by serving banners from a separate server or cluster of servers (for banners that are not text ads or ads delivered by a third-party server). With OpenX, you can load banners onto an FTP server where they can be distributed by a web server configured specifically for high-speed file delivery or, for even higher performance, by a content delivery network.

Delivery caching

OpenX provides a number of options for delivery engine caching. The easiest options is to use file-based caching.

MySQL sort buffer memory

Whenever MySQL runs a SQL statement, such as SELECT COUNT(*) FROM ... GROUP BY ..., sorting is necessary to ensure that everything is counted correctly. If this sort is performed "in memory", the process is fast. However, if there is more data than can be put in memory, sorting is performed "on disk", which is a very slow process.

The amount of memory MySQL can use for sorting is set in the my.cnf file. If you increase this value, every thread that runs in MySQL is allocated this amount of memory. If you make this value larger than the default, you run the risk of crashing MySQL when hundreds (or possibly thousands) of MySQL threads all attempt to allocate this much memory.

However, some parts of the maintenance script in OpenX do require more memory to work fast, for example, if you see the following type of information in your debug log:
Jul 12 13:01:02 Max [debug] Summarising ad requests from the data_raw_ad_impression table.
Jul 12 13:16:20 Max [debug] Summarised 387 request rows in 918 seconds.

In this example, MySQL takes 15 minutes to count impressions.

If this issue occurs, you can configure OpenX to give more sort buffer memory to the maintenance process thread only by editing the configuration file and setting the number of bytes of RAM to allocate for this process. For example:
[databaseMysql]
statisticsSortBufferSize = 536868864

This value is 500MB of RAM, so your MySQL server must have at least this much free RAM at all times, otherwise MySQL can crash.

TCP/IP stack tuning

With a dedicated MySQL server, you may notice in mytop that you have lots of idle connections because, generally, PHP is not very good at ensuring that connections from web servers to MySQL are closed.

To resolve this issue, you can tune your TCP/IP stack to reduce the amount of time the stack waits before closing inactive connections. In Linux, you can do this, for example, by entering:
echo 10 > /proc/sys/net/ipv4/tcp_fin_timeout

On a RedHat system, to make sure this happens at boot time, enter the following in the /etc/sysctl.conf file:
net.ipv4.tcp_fin_timeout = 10