Archive for the ‘HTTP accelerators’ category

Optimize and Tweak High-Traffic Servers

June 30th, 2010

Summary

If you are reaching the limits of your server running Apache serving a lot of dynamic content, you can either spend thousands on new equipment or reduce bloat to increase your server capacity by anywhere from 2 to 10 times. This article concentrates on important and poorly-documented ways of increasing capacity without additional hardware.

Problems
There are a few common things that can cause server load problems, and a thousand uncommon. Let’s focus on the common:

1. Drive Swapping – Too many processes (or runaway processes) using too much RAM
2. CPU – poorly optimized DB queries, poorly optimized code, runaway processes
3. Network – Hardware limits, moron attacks

Solutions:
Briefly, and for completeness, here are the most obvious solutions:
1. Use “TOP” and “PS axu” to check for processes that are using too much CPU or RAM.
2. Use “netstat -anp | sort -u” to check for network problems.

Solutions: Apache’s RAM Usage
First and most obvious, Apache processes use a ton a RAM. This minor issue becomes a major issue when you realize that after each process has done its job, the bloated process sits and spoon-feed data to the client, instead of moving on to bigger and better things. This is further compounded by a bit of essential info that should really be more common knowledge:

If you serve 100% static files with Apache, each httpd process will use around 2-3 megs of RAM.
If you serve 99% static files & 1% dynamic files with Apache, each httpd process will use from 3-20 megs of RAM (depending on your MOST complex dynamic page).

This occurs because a process grows to accommodate whatever it is serving, and NEVER decreases again unless that process happens to die. Quickly, unless you have very few dynamic pages and major traffic fluctuation, most of your httpd processes will take up an amount of RAM equal to the largest dynamic script on your system. A smart web server would deal with this automatically. As it is, you have a few options to manually improve RAM usage.

Reduce wasted processes by tweaking KeepAlive
This is a tradeoff. KeepAliveTimeout is the amount of time a process sits around doing nothing but taking up space. Those seconds add up in a HUGE way. But using KeepAlive can increase speed for both you and the client – disable KeepAlive and the serving of static files like images can be a lot slower. I think it’s best to have KeepAlive on, and KeepAliveTimeout very low (like 1-2 seconds).

Limit total processes with MaxClients
If you use Apache to serve dynamic content, your simultaneous connections are severely limited. Exceed a certain number, and your system begins cannibalistic swapping, getting slower and slower until it dies. A web server should automatically take steps to prevent this, but instead they seem to assume you have unlimited resources. Use trial & error to figure out how many Apache processes your server can handle, and set this value in MaxClients. Note: the Apache docs on this are misleading – if this limit is reached, clients are not “locked out”, they are simply queued, and their access slows. Based on the value of MaxClients, you can estimate the values you need for StartServers, MinSpareServers, & MaxSpareServers.

Force processes to reset with MaxRequestsPerChild
Forcing your processes to die after a while makes them start over with low RAM usage, and this can reduce total memory usage in many situations. The less dynamic content you have, the more useful this will be. This is a game of catch-up, with your dynamic files constantly increasing total RAM usage, and restarting processes constantly reducing it. Experiment with MaxRequestsPerChild – even values as low as 20 may work well. But don’t set it too low, because creating new processes does have overhead. You can figure out the best settings under load by examining “ps axu –sort:rss”. A word of warning, using this is a bit like using heroin. The results can be impressive, but are NOT consistent – if the only way you can keep your server running is by tweaking this, you will eventually run into trouble. That being said, by tweaking MaxRequestsPerChild you may be able to increase MaxClients as much as 50%.

Apache Further Tweaking
For mixed purpose sites (say image galleries, download sites, etc.), you can often improve performance by running two different apache daemons on the same server. For example, we recently compiled apache to just serve up images (gifs,jpegs,png etc). This way for a site that has thousands of stock photos. We put both the main apache and the image apache on the same server and noticed a drop in load and ram usage. Consider a page had about 20-50 image calls — the were all off-loaded to the stripped down apache, which could run 3x more servers with the same ram usage than the regular apache on the server.

Finally, think outside the box: replace or supplement Apache

Use a 2nd server
You can use a tiny, lightning fast server to handle static documents & images, and pass any more complicated requests on to Apache on the same machine. This way Apache won’t tie up its multi-megabyte processes serving simple streams of bytes. You can have Apache only get used, for example, when a php script needs to be executed.

Try Turck MMCache
Turck MMCache is a free open source PHP accelerator, optimizer, encoder and dynamic content cache for PHP. It increases performance of PHP scripts by caching them in compiled state, so that the overhead of compiling is almost completely eliminated. Also it uses some optimizations to speed up execution of PHP scripts. Turck MMCache typically reduces server load and increases the speed of your PHP code by 1-10 times. More details please see this article http://onaxer.com/blog/?p=530

Try HAproxy
You can use some open source or hardware loadblancer to devide the load among multiple servers. For open source Haproxy is best options (http://haproxy.1wt.eu/) as I am using Haproxy past couple of yesrs and i have very -2 good experience. There so many types of hardware Loadblancer like Cisco Local Director etc..

Try Varnish
We cab also use caching server like Varnish. Varnish is an HTTP accelerator designed for content-heavy dynamic web sites. In contrast to other HTTP accelerators, many of which began life as client-side proxies or origin servers, Varnish was designed from the ground up as an HTTP accelerator.
http://en.wikipedia.org/wiki/Varnish_%28software%29. Using Varnish we can handle thousands of users without any problems, most of company using caching technologies to enhance their performance.

Try lingerd
Lingerd takes over the job of feeding bytes to the client after Apache has fetched the document, but requires kernel modification. Sounds pretty good, haven’t tried it. lingerd – http://www.iagora.com/about/software/lingerd/

Use a proxy cache
A proxy cache can keep a duplicate copy of everything it gets from Apache, and serve the copy instead of bothering Apache with it. This has the benefit of also being able to cache dynamically generated pages, but it does add a bit of bloat.

Solutions: PHP’s CPU & RAM Usage
Compiling PHP scripts is usually more expensive than running them. So why not use a simple tool that keeps them precompiled? I highly recommend Turck MMCache. Alternatives include PHP Accelerator, APC, & Zend Accelerator. You will see a speed increase of 2x-10x, simple as that. I have no stats on the RAM improvement at this time.

Solutions: Optimize Database Queries
This is covered in detail everywhere, so just keep in mind a few important notes: One bad query statement running often can bring your site to its knees. Two or three bad query statements don’t perform much different than one. In other words, if you optimize one query you may not see any server-wide speed improvement. If you find & optimize ALL your bad queries you may suddenly see a 5x server speed improvement. The log-slow-queries feature of MySQL can be very helpful.

How to log slow queries:
# vi /etc/rc.d/init.d/mysqld

Find this line:
SAFE_MYSQLD_OPTIONS=”–defaults-file=/etc/my.cnf”

change it to:
SAFE_MYSQLD_OPTIONS=”–defaults-file=/etc/my.cnf –log-slow-queries=/var/log/slow-queries.log”

As you can see, we added the option of logging all slow queries to /var/log/slow-queries.log
Close and save mysqld. Shift + Z + Z

touch /var/log/slow-queries.log
chmod 644 /var/log/slow-queries.log

restart mysql
service myslqd restart
mysqld will log all slow queries to this file.

Cheers!!
Manoj Chauhan

Great Strategies for Using Memcached and MySQL Better Together

June 28th, 2010

The primero recommendation for speeding up a website is almost always to add cache and more cache. And after that add a little more cache just in case. Memcached is almost always given as the recommended cache to use.

What is Memcached?

Memcached is a general-purpose distributed memory caching system that was originally developed by Danga Interactive for LiveJournal, but is now used by many other sites. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read. Memcached runs on Unix, Windows and MacOS and is distributed under a permissive free software license.

Memcached’s APIs provide a giant hash table distributed across multiple machines. When the table is full, subsequent inserts cause older data to be purged in least recently used (LRU) order. Applications using Memcached typically layer requests and additions into core before falling back on a slower backing store, such as a database.

Architecture

The system uses a client–server architecture. The servers maintain a key–value associative array; the clients populate this array and query it. Keys are up to 250 bytes long and values can be at most 1 megabyte large.

Clients use client side libraries to contact the servers which, by default, expose their service at port 11211. Each client knows all servers; the servers do not communicate with each other. If a client wishes to set or read the value corresponding to a certain key, the client’s library first computes a hash of the key to determine the server that will be used. Then it contacts that server. The server will compute a second hash of the key to determine where to store or read the corresponding value.

The servers keep the values in RAM; if a server runs out of RAM, it discards the oldest values. Therefore, clients must treat Memcached as a transitory cache; they cannot assume that data stored in Memcached is still there when they need it. A Memcached-protocol compatible product known as MemcacheDB provides persistent storage. There is also a solution called Membase from NorthScale that provides persistence, replication and clustering.

If all client libraries use the same hashing algorithm to determine servers, then clients can read each other’s cached data; this is obviously desirable.

A typical deployment will have several servers and many clients. However, it is possible to use Memcached on a single computer, acting simultaneously as client and server.

Security

Most deployments of Memcached exist within trusted networks where clients may freely connect to any server. There are cases, however, where Memcached is deployed in untrusted networks or where administrators would like to exercise control over the clients that are connecting. For this purpose Memcached can be compiled with optional SASL authentication support. The SASL support requires the binary protocol.

Example code

Note that all functions described on this page are pseudocode only. Memcached calls and programming languages may vary based on the API used.

Converting a database or object creation queries to use Memcached is simple. Typically, when using straight database queries, example code would be as follows:

function get_foo(int userid) {
result = db_select(“SELECT * FROM users WHERE userid = ?”, userid);
return result;
}

After conversion to Memcached, the same call might look like the following

function get_foo(int userid) {
/* first try the cache */
data = memcached_fetch(“userrow:” + userid);
if (!data) {
/* not found : request database */
data = db_select(“SELECT * FROM users WHERE userid = ?”, userid);
/* then store in cache until next get */
memcached_add(“userrow:” + userid,  data);
}
return data;
}

The server would first check whether a Memcached value with the unique key “userrow:userid” exists, where userid is some number. If the result does not exist, it would select from the database as usual, and set the unique key using the Memcached API add function call.

However, if only this API call were modified, the server would end up fetching incorrect data following any database update actions: the Memcached “view” of the data would become out of date. Therefore, in addition to creating an “add” call, an update call would be also needed, using the Memcached set function.

function update_foo(int userid, string dbUpdateString) {
/* first update database */
result = db_execute(dbUpdateString);
if (result) {
/* database update successful : fetch data to be stored in cache */
data = db_select(“SELECT * FROM users WHERE userid = ?”, userid);
/* last line could also look like   data = createDataFromDBString(dbUpdateString);   */
/* then store in cache until next get */
memcached_set(“userrow:” + userid, data);
}
}

This call would update the currently cached data to match the new data in the database, assuming the database query succeeds. An alternative approach would be to invalidate the cache with the Memcached delete function, so that subsequent fetches result in a cache miss. Similar action would need to be taken when database records were deleted, to maintain either a correct or incomplete cache.

Memcached and MySQL Go Better Together

There’s a little embrace and extend in the webinar as MySQL cluster is presented several times as doing much the same job as memcached, but more reliably. However, the recommended approach for using memcached and MySQL is:

1. Write scale the database by sharding. Partition data across multiple servers so more data can be written in parallel. This avoids a single server becoming the bottleneck.

2. Front MySQL with a memcached farm to scale reads. Applications access memcached first for data and if the data is not in memcached then the application tries the database. This removes a great deal of the load on a database so it can continue to perform it’s transactional duties for writes. In this architecture the database is still the system of record for the true value of data.

3. Use MySQL replication for reliability and read query scaling. There’s an effective limit to the number of slaves that can be supported so just adding slaves won’t work as scaling strategy for larger sites.

Using this approach you get scalable reads and writes along with high availability.

Given that MySQL has a cache, why is memcached needed at all?

1. The MySQL cache is associated with just one instance. This limits the cache to the maximum address of one server. If your system is larger than the memory for one server then using the MySQL cache won’t work. And if the same object is read from another instance its not cached.
2. The query cache invalidates on writes. You build up all that cache and it goes away when someone writes to it. Your cache may not be much of a cache at all depending on usage patterns.
3. The query cache is row based. Memcached can cache any type of data you want and it isn’t limited to caching database rows. Memcached can cache complex complex objects that are directly usable without a join.

Thanks
Manoj Chauhan

Turck MMCache for PHP

April 20th, 2010

Introduction:
Turck MMCache is a free open source PHP accelerator, optimizer, encoder and dynamic content cache for PHP. It increases performance of PHP scripts by caching them in compiled state, so that the overhead of compiling is almost completely eliminated. We sho

Turck MMCache is a free open source PHP accelerator, optimizer, encoder and dynamic content cache for PHP. It increases performance of PHP scripts by caching them in compiled state, so that the overhead of compiling is almost completely eliminated. Also it uses some optimizations to speed up execution of PHP scripts. Turck MMCache typically reduces server load and increases the speed of your PHP code by 1-10 times.

Turck MMCache stores compiled PHP scripts in shared memory and execute code directly from it. It creates locks only for short time while search compiled PHP script in the cache, so one script can be executed simultaneously by several engines. MM shared memory library (http://www.engelschall.com/sw/mm/) was used by Turck MMCache before version 2.3.13 for management of shared memory and locking. Files those can’t fit in shared memory are cached on disk only.

Important: If you have ionCube Loader installed this will render it usless and cause all ionCube loader scripts to stop working!

Since version 2.3.10, Turck MMCache contains a PHP encoder and loader. You can encode PHP scripts using encoder.php in order to distribute them without sources. Encoded files can be run on any site which runs PHP with Turck MMCache 2.3.10 or above. The sources of encoded scripts can’t be restored because they are stored in a compiled form and the encoded version doesn’t contain the source. Of course, some internals of the scripts can be restored with different reverse engineering tools (disassemblers, debuggers, etc), but it is not trivial.

Since version 2.3.15, Turck MMCache is compatible with Zend Optimizer’s loader. Zend Optimizer must be installed after Turck MMCache in php.ini. If you don’t use scripts encoded with Zend Encoder then we do not recommend you install Zend Optimizer with Turck MMCache.

Turck MMCache does not work in CGI mode.

Turck MMCache now BEATS Zend Accelerator and all other PHP accelerators in benchmark tests. So it’s currently the BEST PHP accelerator around, even against commercial products, despite being free.

Click here for benchmark tests results:
http://turck-mmcache.sourceforge.net/#bench

Follow the instructions and you will uninstall PHPA or ZEND, and replace it with Turck MMCache.

Installation:
Upgrade instructions are the same as installation. Note the lines in red which are different to previous instructions.
1) Login as root in SSH
2) Run the following commands in the following order:
cd /
mkdir mmcache
cd mmcache

wget http://unc.dl.sourceforge.net/sourceforge/turck-mmcache/turck-mmcache-2.4.6.tar.gz
tar xvzf turck-mmcache-2.4.6.tar.gz
cd turck-mmcache-2.4.6
export PHP_PREFIX=”/usr”

Note: This could also be: export PHP_PREFIX=”/usr/local”
$PHP_PREFIX/bin/phpize
./configure –enable-mmcache=shared –with-php-config=$PHP_PREFIX/bin/php-config
make
make install

3) Edit php.ini – usually it’s /etc/php.ini or /usr/local/lib/php.ini

Find this:

;Windows Extensions
Above this, comment out the PHPA or ZEND lines if you have them. Replace them with this:
To install as a ZEND extension:
zend_extension=”/mmcache/turck-mmcache-2.4.6/modules/mmcache.so”
mmcache.shm_size=”16″
mmcache.cache_dir=”/tmp/mmcache”
mmcache.enable=”1″
mmcache.optimizer=”1″
mmcache.check_mtime=”1″
mmcache.debug=”0″
mmcache.filter=”"
mmcache.shm_max=”0″
mmcache.shm_ttl=”0″
mmcache.shm_prune_period=”0″
mmcache.shm_only=”0″
mmcache.compress=”1″

OR to install as a PHP extension:
extension=”/mmcache/turck-mmcache-2.4.6/modules/mmcache.so”
mmcache.shm_size=”16″
mmcache.cache_dir=”/tmp/mmcache”
mmcache.enable=”1″
mmcache.optimizer=”1″
mmcache.check_mtime=”1″
mmcache.debug=”0″
mmcache.filter=”"
mmcache.shm_max=”0″
mmcache.shm_ttl=”0″
mmcache.shm_prune_period=”0″
mmcache.shm_only=”0″
mmcache.compress=”1″

4) Create the cache directory by doing the following at the command line
mkdir /tmp/mmcache
chmod 0777 /tmp/mmcache

5) Restart Apache
service httpd restart
Done!

Copy the mmcache.php file in the mmcache directory to a directory that is web-accessible, and run it.
You should be able to see a list of cached scripts as well as the above information.

Turck MMCache 2.4.6
MMCache support enabled
Caching Enabled true
Optimizer Enabled true
Memory Size 33,554,392 Bytes
Memory Available 23,737,176 Bytes
Memory Allocated 9,817,216 Bytes
Cached Scripts 110
Removed Scripts 0
Cached Keys 0

You should see the following:
This program makes use of the Zend Scripting Language Engine:
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies with Turck MMCache v2.4.6, Copyright (c) 2002-2003 TurckSoft, St. Petersburg, by Dmitry Stogov

Thanks
Manoj Chauhan

How to install mod_gzip

April 20th, 2010

Introduction:-

I recently needed to speed up the load time of one of my websites, Ramprage.com – a popular sports website, while I didn’t want to change the content itself I could change how fast it was delivered with mod_gzip. This tutorial features dynamic integration of mod_gzip with Apache, no recompile necessary.

mod_gzip is an Internet Content Acceleration module for the popular Apache Web Server. It compresses the contents delivered to the client. There is no need to install any additional software on the client!
Project website: http://sourceforge.net/projects/mod-gzip/

There is also static integration where gzip is compiled directly into the Apache binary but we do not feature that here.

Test Your Current Website for mod_gzip or compression
http://www.desilva.biz/gzip-test.php
http://leknor.com/code/gziped.php

They should say not compressed, meaning you od not have mod_gzip turned on or installed.

Lets Begin!

Login to your server and su to root.
Download the file to a directory of your choice.
wget http://easynews.dl.sourceforge.net/sourceforge/mod-gzip/mod_gzip-1.3.26.1a.tgz

tar -zxvf mod_gzip-1.3.26.1a.tgz

cd mod_gzip-1.3.26.1a/

Open the makefile to edit the path of Apache builder.
pico Makefile

FIND:
APXS?=/usr/local/sbin/apxs

CHANGE TO:
APXS?=/usr/local/apache/bin/apxs

Save and exit the file, Ctrl+X then Y

Lets compile the module, this will NOT affect your current Apache binary.

make

Now the next command will place the files into your folders such as the .so and .c mod_gzip files and add two lines to your httpd.conf file, it will backup the config file first.

make install

Lets take a look at the config file to see what happened and what we need to do.

pico /usr/local/apache/conf/httpd.conf

Find the mod_gzip which was added: Remove comments # from

FIND:
#LoadModule gzip_module libexec/mod_gzip.so

CHANGE TO:
LoadModule gzip_module libexec/mod_gzip.so

FIND:
#AddModule mod_gzip.c

CHANGE TO:
AddModule mod_gzip.c

Save and close the file, Ctrl+x then Y

Run Test
Now everything should be good to go but we want to do a dry run of how Apache is going to handle this new addition.
This will do a test to Apache but won’t restart the live server itself, isn’t Apache smart like that eh!

/usr/local/apache/bin/apachectl configtest

It might spit our no VirtualDirective or error that some directories are missing, this is normal and fine.

Restart the Live Server to enabled mod_gzip
/etc/init.d/httpd restart

Test It Again, Now you should have compression enabled giving you faster load times.

Cheers!!!
Manoj Chauhan

Memcached with php

April 17th, 2010

Introduction:

memcached (pronunciation: mem-cash-dee) is a general-purpose distributed memory caching system that was originally developed by Danga Interactive for LiveJournal, but is now used by many other sites. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read. Memcached runs on Unix, Windows and MacOS and is distributed under a permissive free software license.

Memcached’s APIs provide a giant hash table distributed across multiple machines. When the table is full, subsequent inserts cause older data to be purged in least recently used (LRU) order. Applications using memcached typically layer memcached requests and additions into core before falling back on a slower backing store, such as a database.

Architecture:

The system architecture follows a client-server model. The servers maintain a key-value associative array; the clients populate this array and query it. Keys are up to 250 bytes long and values can be at most 1 megabyte large.

Clients use client side libraries to contact the servers which, by default, expose their service at port 11211. Each client knows all servers; the servers do not communicate with each other. If a client wishes to set or read the value corresponding to a certain key, the client’s library first computes a hash of the key to determine the server that will be used. Then it contacts that server. The server will compute a second hash of the key to determine where to store or read the corresponding value.

The servers keep the values in RAM; if a server runs out of RAM, it discards the oldest values. Therefore, clients must treat memcached as a transitory cache; they cannot assume that data stored in memcached is still there when they need it. An extension of memcached known as memcacheDB provides persistent storage.

If all client libraries use the same hashing algorithm to determine servers, then clients can read each other’s cached data; this is obviously desirable.

A typical deployment will have several servers and many clients. However, it is possible to use memcached on a single computer, acting simultaneously as client and server.

Security:

Most deployments of memcached exist within trusted networks where clients may freely connect to any server. There are cases, however, where memcached is deployed in untrusted networks or where administrators would like to exercise control over the clients that are connecting. For this purpose memcached can be compiled with optional SASL authentication support. The SASL support requires the binary protocol.

Example code:

Note that all functions described on this page are pseudocode only. Memcached calls and programming languages may vary based on the used API.

Converting a database or object creation queries to use memcached is simple. Typically, when using straight database queries, example code would be as follows:

function get_foo(int userid) {
result = db_select(“SELECT * FROM users WHERE userid = ?”, userid);
return result;
}

After conversion to memcached, the same call might look like the following

function get_foo(int userid) {
/* first try the cache */
data = memcached_fetch(“userrow:” + userid);
if (!data) {
/* not found : request database */
data = db_select(“SELECT * FROM users WHERE userid = ?”, userid);
/* then store in cache until next get */
memcached_add(“userrow:” + userid,  data);
}
return data;
}

The server would first check whether a memcached value with the unique key “userrow:userid” exists, where userid is some number. If the result does not exist, it would select from the database as usual, and set the unique key using the memcached API add function call.

However, if only this API call were modified, the server would end up fetching incorrect data following any database update actions: the memcached “view” of the data would become out of date. Therefore, in addition to creating an “add” call, an update call would be also needed, using the memcached set function.

function update_foo(int userid, string dbUpdateString) {
/* first update database */
result = db_execute(dbUpdateString);
if (result) {
/* database update successful : fetch data to be stored in cache */
data = db_select(“SELECT * FROM users WHERE userid = ?”, userid);
/* last line could also look like   data = createDataFromDBString(dbUpdateString);   */
/* then store in cache until next get */
memcached_set(“userrow:” + userid, data);
}
}

This call would update the currently cached data to match the new data in the database, assuming the database query succeeds. An alternative approach would be to invalidate the cache with the memcached delete function, so that subsequent fetches result in a cache miss. Similar action would need to be taken when database records were deleted, to maintain either a correct or incomplete cache.

How to compile memcached with php:

cd /tmp
wget http://opensource.dynamoid.com/igbinary-1.0.2.tar.gz
tar xvzf igbinary-1.0.2.tar.gz
cd igbinary-1.0.2
phpize
./configure && make && make install
edit /etc/php.d/igbinary.ini
extension=igbinary.so

cd /tmp
wget http://download.tangent.org/libmemcached-0.31.tar.gz
tar xvzf libmemcached-0.31.tar.gz
cd libmemcached-0.31
./configure –prefix=/usr/local/
make && make install

pecl download memcached
tar xvzf memcached<-verson>.tar.gz
phpize
./configure –with-libmemcached-dir=/usr/local/
make && make install

edit /etc/php.d/memcached.ini
extension=memcached.so

Thanks
Manoj Chauhan

Load balancing with Varnish

April 11th, 2010

Introduction:-

Varnish has a built in load balancer. Use this if you have more then one origin server. Using this is quite easy. You start up by declaring more then one backend server. We add a probe object to each backend to let varnish check the health of the objects.
{{{
backend foo {
  .host = “foo.example.com”;
  .probe = {
                .url = “/”;
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
}

backend bar {
  .host = “bar.example.com”;
  .probe = {
                .url = “/”;
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
}
}}}
Here we have two, ”foo” and ”bar”. The probe specifies that Varnish should fetch the / object every 5s. If it takes more then a second it is considered a failure. If more then 3 out of the 5 last probes are OK the backend is considered healthy. For details on health checking see the [wiki:BackendPolling backend health polling] page.

Now these two backends need to be wrapped in a single logical director, sort of a virtual backend. Lets call it baz.
{{{
director baz round-robin {
        {
                .backend = foo;
        }
        {
                .backend = bar;
        }
}
}}}

Thats it, really. The keyword ”round-robin” indicates that requests will be distributed among the backends in a round-robin fashion. Currently there also exists a ”random” director. You can probably guess how it works. :-)

You can send traffic to your brand new director in vcl_recv, like this:
{{{
sub vcl_recv {
   if (req.http.host ~ “^(www.)?mysite.com$“) {
       set req.backend = baz;
   }
}

There are more options documentet on the VCL manual page.

Thanks
Manoj chauhan