<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>IScale &#187; proxy</title>
	<atom:link href="http://dotimes.com/iscale/category/proxy/feed" rel="self" type="application/rss+xml" />
	<link>http://dotimes.com/iscale</link>
	<description>Living within Dot Times</description>
	<pubDate>Tue, 18 Nov 2008 06:04:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Standalone MoinMoin Wiki with Nginx Proxy</title>
		<link>http://dotimes.com/iscale/2008/10/standalone-moinmoin-wiki-with-nginx-proxy.html</link>
		<comments>http://dotimes.com/iscale/2008/10/standalone-moinmoin-wiki-with-nginx-proxy.html#comments</comments>
		<pubDate>Fri, 31 Oct 2008 03:12:21 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[proxy]]></category>

		<category><![CDATA[webserver]]></category>

		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/?p=86</guid>
		<description><![CDATA[Long time since last post here. Yeah, I&#8217;m alive.
For wiking with moin on nginx, I tried a lot and finally got it work. I&#8217;m using Moin 1.7.2 with Nginx 0.7.19 on Slackware linux.
As you may know, there is a mod called mod_wsgi which is an implementation of the Python Web Server Gateway Interface for the [...]]]></description>
			<content:encoded><![CDATA[<p>Long time since last post here. Yeah, I&#8217;m alive.</p>
<p>For wiking with moin on nginx, I tried a lot and finally got it work. I&#8217;m using Moin 1.7.2 with Nginx 0.7.19 on Slackware linux.</p>
<p>As you may know, there is a mod called mod_wsgi which is an implementation of the Python Web Server Gateway Interface for the nginx web server. However, mod_wsgi code is about 7 months old and only tested with nginx 0.5.x, currently cannot be built with nginx 0.7.x. I didn&#8217;t test it with nginx 0.6.x, but there are some patches. For more information, check http://hg.mperillo.ath.cx/nginx/mod_wsgi/file/tip/README (CANNOT access from m^therf^cking China mainland network).</p>
<p>I intended to use the public wiki mode, but unfortunately, haven&#8217;t work it out on fastcgi. Any help is welcome. :-)</p>
<p>It was <a href="http://wiki.codemongers.com/cliff" target="blank">Cliff</a> who illumined me that nginx can proxy to moin standalone server. Thanks to Cliff.</p>
<p>After some test, here is a block of the working nginx configuration on moinmoin wiki.</p>
<blockquote>
<pre>
...snip...
    server {
	listen       127.0.0.1:80;
	server_name	localhost;
	server_tokens	off;
	root	/srv;

# Begin Core MoinMoin:
	rewrite	^/moin_static[0-9]*/(.*)$	/moin/$1	last;
	rewrite ^/(favicon\.ico)$		/moin/$1	last;

### temporary use
	location = / {
		rewrite .*	/wiki/	redirect;
	}
###

	location /wiki {
		proxy_redirect		http://localhost:8000	/;
		proxy_pass		http://localhost:8000;
		proxy_set_header	X-Real-IP	$remote_addr;
		proxy_set_header	X-Forwarded-For	$proxy_add_x_forwarded_for;
		proxy_set_header	Host		$http_host;
		<strong>proxy_set_header        X-Moin-Location /wiki/;</strong>
	}
# End Core MoinMoin.

	location  ~* \.(jpg|jpeg|gif|png|ico|css|js|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mov|avi|mkv|srt|idx|sub)$ {
	    access_log	off;
	    expires	30d;
	}

	location ~* /\.ht {
            deny  all;
	}
    }
...snip...
</pre>
</blockquote>
<p>Then, http://localhost/wiki is ready.<br />
It&#8217;s an important point of the X-Moin-Location header. Moin will add that path to the output link.<br />
So far, so good.</p>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2008/10/standalone-moinmoin-wiki-with-nginx-proxy.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Benchmark Caching of Varnish and Squid Again</title>
		<link>http://dotimes.com/iscale/2008/04/benchmark-caching-of-varnish-and-squid-again.html</link>
		<comments>http://dotimes.com/iscale/2008/04/benchmark-caching-of-varnish-and-squid-again.html#comments</comments>
		<pubDate>Tue, 01 Apr 2008 08:06:35 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[linux]]></category>

		<category><![CDATA[proxy]]></category>

		<category><![CDATA[nginx]]></category>

		<category><![CDATA[squid]]></category>

		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/?p=40</guid>
		<description><![CDATA[About two weeks ago, I did a simple benchmark on varnish and squid, and wrote this Benchmark Caching of Varnish and Squid post.
Today Willy Tarreau gave me some advise. So I took a short time re-ran this benchmark. Here follows the detail.
platform
Everything kept unchanged except for the proxy_server, I replaced it with this new one:

 [...]]]></description>
			<content:encoded><![CDATA[<p>About two weeks ago, I did a simple benchmark on varnish and squid, and wrote this <a href="http://dotimes.com/iscale/2008/03/benchmark-caching-of-varnish-and-squid.html">Benchmark Caching of Varnish and Squid</a> post.</p>
<p>Today <a href="http://1wt.eu/">Willy Tarreau</a> gave me <a href="http://dotimes.com/iscale/2008/03/benchmark-caching-of-varnish-and-squid.html#comment-55">some advise</a>. So I took a short time re-ran this benchmark. Here follows the detail.</p>
<p><strong>platform</strong><br />
Everything kept unchanged except for the <em>proxy_server</em>, I replaced it with this new one:</p>
<pre>
    o OS: Linux 2.6.21.5-smp i686 (Slackware 12.0)
    o CPU:  Intel(R) Xeon(TM) CPU 3.06GHz x 2
    o MEM: 1024M x 6
    o DISK: RAID 5
    o Ethernet controller:  Intel Corporation 82546EB Gigabit Ethernet Controller
</pre>
<p><strong>file pool</strong><br />
This time, I generated 2 sets of 10Mbyte files, one is 1,000 files of 10kbyte size, and the other is 10 files of 1MByte size.</p>
<p><strong>benchmark</strong></p>
<pre>
    * client: http_load
    * proxy server: varnish 1.1.2, squid 2.6.STABLE18, and squid 3.0.STABLE2.
    * http server: nginx/0.6.28
</pre>
<p>Using the same configurations of nginx, varnish, and squid 2/3, got the results below:<br />
<br />
+++ 10KByte +++<br />
<br />
$ <code>http_load -verbose -parallel 100 -fetches 100000 ./10k.urls</code><br />
</p>
<blockquote><p>
100000 fetches, 100 max parallel, 1.024e+09 bytes, in 14.7505 seconds<br />
10240 mean bytes/connection<br />
6779.43 fetches/sec, 6.94213e+07 bytes/sec<br />
msecs/connect: 0.400918 mean, 11.452 max, 0.067 min<br />
msecs/first-response: 14.0161 mean, 1779.32 max, 0.24 min<br />
HTTP response codes:<br />
  code 200 &#8212; 100000
</p></blockquote>
<p>* Squid 2.6.STABLE18:</p>
<blockquote><p>
100000 fetches, 100 max parallel, 1.024e+09 bytes, in 26.1771 seconds<br />
10240 mean bytes/connection<br />
3820.13 fetches/sec, 3.91181e+07 bytes/sec<br />
msecs/connect: 0.497665 mean, 2990.79 max, 0.055 min<br />
msecs/first-response: 21.0663 mean, 3018.84 max, 4.071 min<br />
HTTP response codes:<br />
  code 200 &#8212; 100000
</p></blockquote>
<p>* Squid 3.0.STABLE2:</p>
<blockquote><p>
&#8212; 60.0027 secs, 100000 fetches started, 96249 completed, 0 current<br />
100000 fetches, 100 max parallel, 9.85651e+08 bytes, in 102.375 seconds<br />
9856.51 mean bytes/connection<br />
976.8 fetches/sec, 9.62785e+06 bytes/sec<br />
msecs/connect: 2.56114 mean, 91.428 max, 0.061 min<br />
msecs/first-response: 27.8048 mean, 94.563 max, 1.288 min<br />
3751 timeouts<br />
3745 bad byte counts<br />
HTTP response codes:<br />
  code 200 &#8212; 96255
</p></blockquote>
<p>+++ 1MByte +++<br />
<br />
$ <code>http_load -verbose -parallel 100 -fetches 1000 ./1m.urls</code><br />
<br />
* Varnish 1.1.2:</p>
<blockquote><p>
&#8212; 60 secs, 6640 fetches started, 6540 completed, 100 current<br />
10000 fetches, 100 max parallel, 1.04858e+10 bytes, in 91.1719 seconds<br />
1.04858e+06 mean bytes/connection<br />
109.683 fetches/sec, 1.15011e+08 bytes/sec<br />
msecs/connect: 36.9187 mean, 9019.28 max, 0.08 min<br />
msecs/first-response: 26.7986 mean, 475.462 max, 18.781 min<br />
HTTP response codes:<br />
  code 200 &#8212; 10000
</p></blockquote>
<p>* Squid 2.6.STABLE18:</p>
<blockquote><p>
&#8212; 60 secs, 5856 fetches started, 5756 completed, 100 current<br />
10000 fetches, 100 max parallel, 1.04858e+10 bytes, in 103.829 seconds<br />
1.04858e+06 mean bytes/connection<br />
96.3126 fetches/sec, 1.00991e+08 bytes/sec<br />
msecs/connect: 2.4862 mean, 2994.65 max, 0.063 min<br />
msecs/first-response: 15.9743 mean, 134.817 max, 8.222 min<br />
HTTP response codes:<br />
  code 200 &#8212; 10000
</p></blockquote>
<p>* Squid 3.0.STABLE2:</p>
<blockquote><p>
&#8212; 60 secs, 6083 fetches started, 5983 completed, 100 current<br />
10000 fetches, 100 max parallel, 1.04858e+10 bytes, in 103.054 seconds<br />
1.04858e+06 mean bytes/connection<br />
97.0367 fetches/sec, 1.0175e+08 bytes/sec<br />
msecs/connect: 6.6513 mean, 3022.23 max, 0.089 min<br />
msecs/first-response: 16.0642 mean, 787.308 max, 0.741 min<br />
HTTP response codes:<br />
  code 200 &#8212; 10000
</p></blockquote>
<p><strong>proxy server system status</strong></p>
<p>+++ 10KByte +++</p>
<p><a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-varnish-iostat_xm5.log'>10k-varnish-iostat_xm5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid2-iostat_xm5.log'>10k-squid2-iostat_xm5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid3-iostat_xm5.log'>10k-squid3-iostat_xm5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-varnish-vmstat5.log'>10k-varnish-vmstat5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid2-vmstat5.log'>10k-squid2-vmstat5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid3-vmstat5.log'>10k-squid3-vmstat5</a></p>
<p>+++ 1MByte +++</p>
<p><a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-varnish-iostat_xm5.log'>1m-varnish-iostat_xm5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid2-iostat_xm5.log'>1m-squid2-iostat_xm5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid3-iostat_xm5.log'>1m-squid3-iostat_xm5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-varnish-vmstat5.log'>1m-varnish-vmstat5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid2-vmstat5.log'>1m-squid2-vmstat5</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid3-vmstat5.log'>1m-squid3-vmstat5</a></p>
<p><strong>proxy status</strong></p>
<p><a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-varnishstat.png'><img src="http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-varnishstat-150x150.png" alt="" title="10k-varnishstat" width="150" height="150" class="alignnone size-thumbnail wp-image-75" /></a> <a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid2.png'><img src="http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid2-150x150.png" alt="" title="10k-squid2" width="150" height="150" class="alignnone size-thumbnail wp-image-79" /></a> <a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid3.png'><img src="http://dotimes.com/iscale/wp-content/uploads/2008/04/10k-squid3-150x150.png" alt="" title="10k-squid3" width="150" height="150" class="alignnone size-thumbnail wp-image-80" /></a><br />
<br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-varnishstat.png'><img src="http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-varnishstat-150x150.png" alt="" title="1m-varnishstat" width="150" height="150" class="alignnone size-thumbnail wp-image-78" /></a> <a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid2.png'><img src="http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid2-150x150.png" alt="" title="1m-squid2" width="150" height="150" class="alignnone size-thumbnail wp-image-76" /></a> <a href='http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid3.png'><img src="http://dotimes.com/iscale/wp-content/uploads/2008/04/1m-squid3-150x150.png" alt="" title="1m-squid3" width="150" height="150" class="alignnone size-thumbnail wp-image-77" /></a><br />
<br />
)-: Hmm, I&#8217;m still not satisfied with these results, especially the something about squid3.<br />
Maybe I need to optimize the configuration of the proxies?</p>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2008/04/benchmark-caching-of-varnish-and-squid-again.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Fasting Domain Name Resolution with Dnsmasq</title>
		<link>http://dotimes.com/iscale/2008/03/fasting-domain-name-resolution-with-dnsmasq.html</link>
		<comments>http://dotimes.com/iscale/2008/03/fasting-domain-name-resolution-with-dnsmasq.html#comments</comments>
		<pubDate>Sat, 22 Mar 2008 08:22:21 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[proxy]]></category>

		<category><![CDATA[dnsmasq]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/2008/03/fasting-domain-name-resolution-with-dnsmasq.html</guid>
		<description><![CDATA[Dnsmasq is a lightweight DNS forwarder, DHCP server, and BOOTP/TFTP server for a small network (up to 1000 clients is known to work). It&#8217;s easy to configure and low resource cost.
I just use the DNS forward(cache) function here, which only serves with the systems of internal network, as the configuration file of the dnsmasq server [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.thekelleys.org.uk/dnsmasq/doc.html" target="_blank">Dnsmasq</a> is a lightweight DNS forwarder, DHCP server, and BOOTP/TFTP server for a small network (up to 1000 clients is known to work). It&#8217;s easy to configure and low resource cost.</p>
<p>I just use the DNS forward(cache) function here, which only serves with the systems of internal network, as the configuration file of the dnsmasq server below:</p>
<p><code>$ cat /etc/dnsmasq.conf</code></p>
<blockquote><p>
no-hosts<br />
neg-ttl=3600<br />
#log-queries<br />
log-facility=/var/log/dnsmasq.log<br />
pid-file=/var/run/dnsmasq.pid<br />
user=nobody<br />
group=nogroup<br />
port=53<br />
edns-packet-max=1280<br />
interface=eth0 # internal network<br />
except-interface=eth1 # external network<br />
#no-dhcp-interface=eth1<br />
listen-address=192.168.0.10<br />
bind-interfaces<br />
resolv-file=/etc/dnsmasq.resolv.conf<br />
strict-order<br />
#all-servers<br />
stop-dns-rebind<br />
#no-poll<br />
cache-size=2048<br />
no-negcache
</p></blockquote>
<p><code>$ cat /etc/resolv.conf</code></p>
<blockquote><p>nameserver 127.0.0.1</p></blockquote>
<p>On another system:</p>
<p><code>$ cat /etc/resolv.conf</code></p>
<blockquote><p>
nameserver 192.168.0.10<br />
nameserver 192.168.0.11
</p></blockquote>
<p>I think it&#8217;s a good choice to effect fault tolerance with setting up two dnsmasq servers. As the two lines above.</p>
<p>the <strong>first</strong> time:</p>
<p><code>$ dig dotimes.com</code></p>
<blockquote><p>
;; Query time: <strong>258 msec</strong><br />
;; SERVER: 192.168.0.10#53(192.168.0.10)
</p></blockquote>
<p>the <strong>second</strong> time:</p>
<p><code>$ dig dotimes.com</code></p>
<blockquote><p>
;; Query time: <strong>1 msec</strong><br />
;; SERVER: 192.168.0.10#53(192.168.0.10)
</p></blockquote>
<p>As you can see the difference in the above example.<br />
Yes, this is only one request, but what about surfing, or sending mails on mail server? It&#8217;s really worth the effort.</p>
<p><a href="http://cr.yp.to/djbdns.html" target="_blank">djbdns</a>, <a href="http://www.phys.uu.nl/~rombouts/pdnsd.html" target="_blank">pdnsd</a> are also good DNS cache (proxy) programs, which yep worth a try.<br />
The only thing I&#8217;m wondering that whether djbdns is still under maintainence.</p>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2008/03/fasting-domain-name-resolution-with-dnsmasq.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Abstract of HAProxy Architecture</title>
		<link>http://dotimes.com/iscale/2008/03/abstract-of-haproxy-architecture.html</link>
		<comments>http://dotimes.com/iscale/2008/03/abstract-of-haproxy-architecture.html#comments</comments>
		<pubDate>Fri, 21 Mar 2008 15:53:12 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[proxy]]></category>

		<category><![CDATA[haproxy]]></category>

		<category><![CDATA[ipvs]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/2008/03/abstract-of-haproxy-architecture.html</guid>
		<description><![CDATA[Two of the projects of which the systems I&#8217;m maintaining currently are running IPVS (IP Virtual Server), an software from the LVS (Linux Virtual Server) Project, which implements transport-layer load balancing inside the Linux kernel, also called Layer-4 switching.
I really got impressed with its stability, scalability and high performance. It doesn&#8217;t cost any system resource [...]]]></description>
			<content:encoded><![CDATA[<p>Two of the projects of which the systems I&#8217;m maintaining currently are running IPVS (<a href="http://www.linuxvirtualserver.org/software/ipvs.html" target="_blank" title="IP Virtual Server">IP Virtual Server</a>), an software from the LVS (<a href="http://www.linuxvirtualserver.org/" target="_blank" title="Linux Virtual Server Project">Linux Virtual Server</a>) Project, which implements transport-layer load balancing inside the Linux kernel, also called Layer-4 switching.</p>
<p>I really got impressed with its stability, scalability and high performance. It doesn&#8217;t cost any system resource except memory usage, which depends on the connection number. And yet it&#8217;s very low-cost, for each connection entry consumes about 128bytes or so. It&#8217;s easy for you to figure it out that 100,000 unique connections/s, only 12.8M memory will be used. On the other hand, as a 4th-layer implement, IPVS just direct packages.</p>
<p>So, a question raised, what if I need layer-7 switching?</p>
<p>Yeah, IPVS no longer sucks. Here goes <a href="http://haproxy.1wt.eu/" target="_blank" title="The Reliable, High Performance TCP/HTTP Load Balancer">HAProxy</a>, the reliable, high performance TCP/HTTP load balancer. Although there are other solutions, e.g., F5, pound, XLB, pen, and so on, I would like to chose HAProxy and introduce it here.</p>
<p>HAProxy is written by <a href="http://1wt.eu/" target="_blank">Willy TARREAU</a>, the new Linux Kernel 2.4 maintainer since August 2006, who also maintains patches against the 2.6.20 branch since August of 2007.</p>
<p>Today I glanced my eye over the <a href="http://haproxy.1wt.eu/download/1.2/doc/architecture.txt" target="_blank" title="HAProxy architecture guide">HAProxy Architecture Guide</a>. I&#8217;d like to take a note here.</p>
<p>This note is so annoyed that you would better go for a drink, then <a href="http://youtube.com/" target="_blank">YouTube</a>. Yeah, I&#8217;m serious. :-) Otherwise, it&#8217;s better to check the link in the line above for original detail if you are interested in the architecture. Okay, here I go, see you&#8230;</p>
<p><strong>1. Simple HTTP load-balancing with cookie insertion</strong></p>
<pre>
  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     haproxy        4 cheap web servers
</pre>
<p>Flows :</p>
<pre>
(client)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
               ( the proxy now adds the server cookie in return )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: SERVERID=A           |
  >-- GET /URI2 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
      ( the proxy sees the cookie. it forwards to server A and deletes it )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
   ( the proxy does not add the cookie in return because the client knows it )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
                                    ( ... )
</pre>
<p>If clients use keep-alive (HTTP/1.1), only the first response will have a cookie inserted, and only the first request of each session will be analyzed. The added server cookie will not be removed from the requests forwarded to the servers, so the server must not be sensitive to unknown cookies. If this causes trouble, keep-alive can be disabled by adding the following option :</p>
<blockquote><p>option httpclose</p></blockquote>
<p>If for some reason the clients cannot learn more than one cookie, and the application already produces a cookie, &#8220;prefix&#8221; mode could be used(see below).</p>
<p>Backing LB1 up using keepalived for healthcheck &amp; failover(see below)</p>
<p>If the application needs to log the original client&#8217;s IP, use the &#8220;forwardfor&#8221; option which will add an &#8220;X-Forwarded-For&#8221; header with the original client&#8217;s IP address. Also use &#8220;httpclose&#8221; to rewrite every requests and not only the first one of each session :</p>
<blockquote><p>     option httpclose<br />
option forwardfor</p></blockquote>
<p>The web server will have to be configured to use this header instead. For example, on apache:</p>
<blockquote><p>     LogFormat &#8220;%{X-Forwarded-For}i %l %u %t \&#8221;%r\&#8221; %&gt;s %b &#8221; combined<br />
CustomLog /var/log/httpd/access_log combined</p></blockquote>
<p>In the situation of clients disable cookies on their browser, use the &#8220;source&#8221; balancing algorithm instead of the &#8220;roundrobin&#8221;. So a given IP address will always reaches the same server. (as long as the number of servers remains unchanged.) Never use this behind a proxy or in a small network, because the distribution will be unfair. However, in large internal networks, and on the internet, it works quite well. Clients<br />
which have a dynamic address will not be affected as long as they accept the cookie, because the cookie always has precedence over load balancing.</p>
<p><strong>2. HTTP load-balancing with cookie prefixing and high availability</strong></p>
<p>Backed load-balancer up with a second one in VRRP mode using keepalived.</p>
<blockquote><p>        http://www.keepalived.org/</p></blockquote>
<p>Allow the proxy to bind to the shared IP:</p>
<p><code># echo 1 &gt;/proc/sys/net/ipv4/ip_nonlocal_bind</code></p>
<pre>
    shared IP=192.168.1.1
  192.168.1.3  192.168.1.4    192.168.1.11-192.168.1.14   192.168.1.2
 -------+------------+-----------+-----+-----+-----+--------+----
        |            |           |     |     |     |       _|_db
     +--+--+      +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | LB2 |      | A | | B | | C | | D |    (___)
     +-----+      +-----+      +---+ +---+ +---+ +---+    (___)
     haproxy      haproxy        4 cheap web servers
     keepalived   keepalived
</pre>
<p>Set the &#8220;httpclose&#8221; option to disable keep-alive (HTTP/1.1), so the proxy can access to all cookies in all requests for each session, because the proxy will modify EVERY cookie sent by the client and the server.</p>
<p>Flows :</p>
<pre>
(client)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       |     X-Forwarded-For: 10.1.2.3
                                       | <-- HTTP/1.0 200 OK -------------<
                        ( no cookie, nothing changed )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI2 HTTP/1.0 ------------> |
    ( no cookie, haproxy forwards in lb mode, possibly to another server. )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       |     X-Forwarded-For: 10.1.2.3
                                       | <-- HTTP/1.0 200 OK -------------<
                                       |     Set-Cookie: JSESSIONID=123
    ( the cookie is identified, it will be prefixed with the server name )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: JSESSIONID=A~123     |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: JSESSIONID=A~123         |
       ( the proxy sees the cookie, removes the server name and forwards
          to server A which sees the same cookie as it previously sent )
                                       | >-- GET /URI3 HTTP/1.0 ---------->
                                       |     Cookie: JSESSIONID=123
                                       |     X-Forwarded-For: 10.1.2.3
                                       | <-- HTTP/1.0 200 OK -------------<
                        ( no cookie, nothing changed )
  <-- HTTP/1.0 200 OK ---------------< |
                                    ( ... )
</pre>
<p>Setting &#8220;weight&#8221;(values between 1 and 256) to inform haproxy to spread the load of backends the most smoothly possible respecting those ratios:</p>
<blockquote><p>        server webA 192.168.1.11:80 cookie A weight 12 check<br />
server webC 192.168.1.13:80 cookie C weight 26 check</p></blockquote>
<p><strong>2.1 Variations involving external layer 4 load-balancers</strong></p>
<p>Can the haproxies be load-balanced?<br />
Yeah, by a layer4 load-balancer (eg: Alteon) which will check the services:</p>
<pre>
              | VIP=192.168.1.1
         +----+----+
         | Alteon  |
         +----+----+
              |
 192.168.1.3  |  192.168.1.4  192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----+------+-----------+-----+-----+-----+--------+----
        |            |           |     |     |     |       _|_db
     +--+--+      +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | LB2 |      | A | | B | | C | | D |    (___)
     +-----+      +-----+      +---+ +---+ +---+ +---+    (___)
     haproxy      haproxy        4 cheap web servers
</pre>
<p>What if the Alteon fails? Want relay generic TCP protocols (SMTP, TSE, VNC, etc&#8230;)? (see below)</p>
<p><strong>2.2 Generic TCP relaying and external layer 4 load-balancers</strong></p>
<p>Using the &#8220;monitor-net&#8221; keyword to specify a network which will be dedicated to monitoring systems and must not lead to a forwarding connection nor to any log. This expects a version of haproxy greater than or equal to 1.1.32 or 1.2.6.</p>
<pre>
                |  VIP=172.16.1.1   |
           +----+----+         +----+----+
           | Alteon1 |         | Alteon2 |
           +----+----+         +----+----+
 192.168.1.252  |  GW=192.168.1.254 |  192.168.1.253
                |                   |
          ------+---+------------+--+-----------------> TSE farm : 192.168.1.10
       192.168.1.1  |            | 192.168.1.2
                 +--+--+      +--+--+
                 | LB1 |      | LB2 |
                 +-----+      +-----+
                 haproxy      haproxy
</pre>
<p><strong>3. Simple HTTP/HTTPS load-balancing with cookie insertion</strong></p>
<pre>
  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     apache         4 cheap web servers
     mod_ssl
     haproxy
</pre>
<p>Do not cache inserted cookies for security measures.</p>
<p>If the cookie works in &#8220;prefix&#8221; mode, there is no need to add the &#8220;nocache&#8221; option because it is an application cookie which will be modified, and the application flags will be preserved.</p>
<p>If apache 1.3 is used as a front-end before haproxy, it always disables HTTP keep-alive on the back-end, so the &#8220;httpclose&#8221; is needn&#8217;t.</p>
<p>To log client&#8217;s IP, configure apache to set the X-Forwarded-For header not on haproxy.</p>
<p>Flows :</p>
<pre>
(apache)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
               ( the proxy now adds the server cookie in return )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: SERVERID=A           |
      Cache-Control: private           |
  >-- GET /URI2 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
      ( the proxy sees the cookie. it forwards to server A and deletes it )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
   ( the proxy does not add the cookie in return because the client knows it )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
                                    ( ... )
</pre>
<p>What if only SSL is required and cache is not needed? (see below)</p>
<p><strong>3.1. Alternate solution using Stunnel</strong></p>
<p>Stunnel is a cheaper solution than Apache+mod_ssl. It doesn&#8217;t process HTTP or add X-Forwarded-For header by default. (there is a patch on the official haproxy site to provide this feature to recent stunnel versions.)</p>
<p>Stunnel will only process HTTPS. Haproxy will get all HTTP traffic, so add the X-Forwarded-For header for HTTP traffic in haproxy, but not for HTTPS traffic since stunnel will already have done it.</p>
<p>Use the &#8220;except&#8221; keyword to tell haproxy that connections from local host already have a valid header.</p>
<pre>
  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     stunnel        4 cheap web servers
     haproxy
</pre>
<p>Description :<br />
- stunnel on LB1 will receive clients requests on port 443<br />
- it forwards them to haproxy bound to port 80<br />
- haproxy will receive HTTP client requests on port 80 and decrypted SSL<br />
requests from Stunnel on the same port.<br />
- stunnel will add the X-Forwarded-For header<br />
- haproxy will add the X-Forwarded-For header for everyone except the local<br />
address (stunnel).</p>
<p><strong>4. Soft-stop for application maintenance</strong><br />
<strong>4.1 Soft-stop using a file on the servers</strong></p>
<p>Put a file on the server which will be checked by the proxy. Remove this file so that the proxy will treat this server as dead, and won&#8217;t send any new sessions, only old ones if the &#8220;persist&#8221; option is used. Wait a bit then stop the server when there isn&#8217;t http connection anymore. And then it&#8217;s time to do backend server maintenance.</p>
<p>This solution will effect the clients, not so good.</p>
<p><strong>4.2 Soft-stop using backup servers</strong></p>
<p>Set two different names to one server checked on different port(one is 80), they share the exact same cookies. Those servers will only be used when no other server is available for the same cookie.</p>
<p>When the web servers are started, only one named server is seen as available. On the web server, redirect the other different port to local port 80(e.g., use iptables).</p>
<p>When need maintenance, simply stop the server from responding on port 81 so that its standard instance will be seen as failed, but the other will still work. This won&#8217;t effect the clients.</p>
<p><strong>4.2.1 Variations for operating systems without any firewall software</strong></p>
<p>Beside the iptables solution above, this redirection can also be handled by a simple haproxy in tcp mode :</p>
<blockquote><p>     global<br />
daemon<br />
quiet<br />
pidfile /var/run/haproxy-checks.pid<br />
listen 0.0.0.0:81<br />
mode tcp<br />
dispatch 127.0.0.1:80<br />
contimeout 1000<br />
clitimeout 10000<br />
srvtimeout 10000</p></blockquote>
<p>Starting an haproxy instance with this configuration to start the web service, and killing this instance will make the port 81 stopping responding so that the web service could be stopped.</p>
<p><strong>4.2.2 Centralizing the server management</strong></p>
<p>It&#8217;s also an solution to do the port redirection on the load-balancer.</p>
<p>Another solution is to use the &#8220;COMAFILE&#8221; patch provided by Alexander Lazic, which is available for download here :</p>
<blockquote><p>    http://w.ods.org/tools/haproxy/contrib/</p></blockquote>
<p><strong>4.3 Hot reconfiguration</strong></p>
<p>Send a SIGTTOU signal to the proxy and it will release the ports so that a new instance can be started.</p>
<p>If the new instance fails to start, sending a SIGTTIN signal back to the original processes will restore the listening ports.</p>
<p>Otherwise, sending a SIGUSR1 signal to the old one and it will exit after its last session ends.</p>
<p>If the old process still exists, sending a SIGTERM to the old process.</p>
<p><strong>5. Multi-site load-balancing with local preference</strong><br />
<strong>5.1 Network diagram</strong></p>
<p>Note : offices 1 and 2 are on the same continent as site 1, while office 3 is on the same continent as site 3. Each production site can reach the second one either through the WAN or through a dedicated link.</p>
<pre>
        Office1         Office2                          Office3
         users           users                            users
192.168  # # #   192.168 # # #                            # # #
.1.0/24  | | |   .2.0/24 | | |             192.168.3.0/24 | | |
  --+----+-+-+-   --+----+-+-+-                   ---+----+-+-+-
    |      | .1     |      | .1                      |      | .1
    |    +-+-+      |    +-+-+                       |    +-+-+
    |    |OP1|      |    |OP2|                       |    |OP3|  ...
  ,-:-.  +---+    ,-:-.  +---+                     ,-:-.  +---+
 (  X  )         (  X  )                          (  X  )
  `-:-'           `-:-'             ,---.          `-:-'
  --+---------------+------+----~~~(  X  )~~~~-------+---------+-
                           |        `---'                      |
                           |                                   |
                 +---+   ,-:-.                       +---+   ,-:-.
                 |SD1|  (  X  )                      |SD2|  (  X  )
   ( SITE 1 )    +-+-+   `-:-'         ( SITE 2 )    +-+-+   `-:-'
                   |.1     |                           |.1     |
   10.1.1.0/24     |       |     ,---. 10.2.1.0/24     |       |
        -+-+-+-+-+-+-+-----+-+--(  X  )------+-+-+-+-+-+-+-----+-+--
         | | | | |   |       |   `---'       | | | | |   |       |
      ...# # # # #   |.11    |.12         ...# # # # #   |.11    |.12
          Site 1   +-+--+  +-+--+              Site 2  +-+--+  +-+--+
          Local    |S1L1|  |S1L2|              Local   |S2L1|  |S2L2|
          users    +-+--+  +--+-+              users   +-+--+  +--+-+
                     |        |	                         |        |
   10.1.2.0/24    -+-+-+--+--++--      10.2.2.0/24    -+-+-+--+--++--
                   |.1       |.4                       |.1       |.4
                 +-+-+     +-+-+                     +-+-+     +-+-+
                 |W11| ~~~ |W14|                     |W21| ~~~ |W24|
                 +---+     +---+                     +---+     +---+
              4 application servers               4 application servers
                    on site 1                           on site 2
</pre>
<p><strong>5.2 Description</strong><br />
<strong>5.2.1 Local users</strong></p>
<p>- Office 1 users connect to OP1 = 192.168.1.1<br />
- Office 2 users connect to OP2 = 192.168.2.1<br />
- Office 3 users connect to OP3 = 192.168.3.1<br />
- Site 1 users connect to SD1 = 10.1.1.1<br />
- Site 2 users connect to SD2 = 10.2.1.1</p>
<p><strong>5.2.2 Office proxies</strong></p>
<p>- Office 1 connects to site 1 by default and uses site 2 as a backup.<br />
- Office 2 connects to site 1 by default and uses site 2 as a backup.<br />
- Office 3 connects to site 2 by default and uses site 1 as a backup.</p>
<p><strong>6. Source balancing</strong></p>
<p>Sometimes it may reveal useful to access servers from a pool of IP addresses instead of only one or two. Some equipments (NAT firewalls, load-balancers) are sensible to source address, and often need many sources to distribute the load evenly amongst their internal hash buckets.</p>
<p><strong>7. Managing high loads on application servers</strong></p>
<p>Limiting the number of connections between the clients and the servers. Setting haproxy to limit the number of connections on a per-server basis. It will then fill all the servers up to the configured connection limit, and will put the remaining connections in a queue, waiting for a connection to be released on a server.</p>
<p>So that,</p>
<p>* all clients can be served whatever their number without crashing the servers, the only impact it that the response time can be delayed.</p>
<p>* the servers can be used at full throttle without the risk of stalling, and fine tuning can lead to optimal performance.</p>
<p>* response times can be reduced by making the servers work below the congestion point, effectively leading to shorter response times even under moderate loads.</p>
<p>* no domino effect when a server goes down or starts up. Requests will be queued more or less, always respecting servers limits.</p>
<p>* it&#8217;s easy to achieve high performance even on memory-limited hardware. Indeed, heavy frameworks often consume huge amounts of RAM and not always all the CPU available. In case of wrong sizing, reducing the number of concurrent connections will protect against memory shortages while still ensuring optimal CPU usage.</p>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2008/03/abstract-of-haproxy-architecture.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Benchmark Caching of Varnish and Squid</title>
		<link>http://dotimes.com/iscale/2008/03/benchmark-caching-of-varnish-and-squid.html</link>
		<comments>http://dotimes.com/iscale/2008/03/benchmark-caching-of-varnish-and-squid.html#comments</comments>
		<pubDate>Mon, 17 Mar 2008 16:45:01 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[linux]]></category>

		<category><![CDATA[proxy]]></category>

		<category><![CDATA[nginx]]></category>

		<category><![CDATA[squid]]></category>

		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/2008/03/benchmark-caching-of-varnish-and-squid.html</guid>
		<description><![CDATA[#
#   Readme
#
# I re-ran this benchmark and got new results in another post, which are more reasonable.
# Thanks to Willy Tarreau for pointing out the inadequacy in this benchmark.
# It&#8217;s recommended that you skimming this post and then referring to this fresh one.
#
&#8212;&#8212;&#8211;
Today, I finished a benchmark to compare the caching performance and [...]]]></description>
			<content:encoded><![CDATA[<p>#<br />
#   Readme<br />
#<br />
# I re-ran this benchmark and got new results in another post, which are more reasonable.<br />
# Thanks to <a href="http://1wt.eu/" target="_blank">Willy Tarreau</a> for pointing out the inadequacy in this benchmark.<br />
# It&#8217;s recommended that you skimming this post and then referring to <a href="http://dotimes.com/iscale/2008/04/benchmark-caching-of-varnish-and-squid-again.html" target="_blank">this fresh one</a>.<br />
#<br />
&#8212;&#8212;&#8211;</p>
<p>Today, I finished a benchmark to compare the caching performance and status between Varnish and Squid, which get widely focused on as reverse proxies.<br />
Here we go.</p>
<p><strong>platform</strong></p>
<p>The test-network is made up of:</p>
<pre>
    * D-Link 1024R, a 24-port Gigabit Switch
    * http_server:
          o OS: Linux 2.6.21.5-smp i686 (Slackware 12.0)
          o CPU: Intel(R) Xeon(TM) CPU 2.80GHz x 2
          o MEM: 1024M x 6
          o DISK: SEAGATE ST373405LC SCSI Disk
          o Ethernet controller: Intel 82546EB PRO/1000 MT Dual Port Server Adapter
    * proxy_server:
          o OS: Linux 2.6.21.5-smp i686 (Slackware 12.0)
          o CPU:  Intel(R) Pentium(R) III CPU family 1133MHz GenuineIntel
          o MEM: 1024M
          o DISK: SEAGATE ST318406LC SCSI Disk
          o Ethernet controller:  Intel 82557/8/9 PRO/100+ Server Adapter
    * client
          o OS: Linux 2.4.31 i686 (Slackware 10.2)
          o CPU: Intel(R) Xeon(TM) CPU 2.80GHz x 2
          o MEM: 1024M x 6
          o Ethernet controller: Intel 82546EB Gigabit Ethernet Controller
</pre>
<p><strong>file pool</strong></p>
<blockquote><p>
<i><br />
#!/bin/sh<br />
#<br />
# Written for generating 2 sets of 100Mbyte files,<br />
# one is 1,000 files of 100kbyte size, and<br />
# the other is 10 files of 10MByte size.<br />
# by Cherife Li <cherife@dotimes.com><br />
#</p>
<p>docroot=/home/wwwroot/</p>
<p># generate the first set<br />
mkdir -p $docroot/100k<br />
cd $docroot/100k<br />
for i in `seq 1 10`; do<br />
   mkdir -p files-$i;<br />
   for j in `seq 1 100`; do<br />
      dd if=/dev/zero of=files-$i/$j bs=100K count=1 2> /dev/null;<br />
   done;<br />
done</p>
<p># generate the second set<br />
mkdir -p $docroot/10m<br />
cd $docroot/10m<br />
for i in `seq 1 5`; do<br />
   mkdir -p files-$i;<br />
   for j in `seq 1 2`; do<br />
      dd if=/dev/zero of=files-$i/$j bs=10M count=1 2> /dev/null;<br />
   done;<br />
done<br />
</i></p></blockquote>
<p>$ <code>cd /home/wwwroot/</code><br />
$ <code>find ./100k/ | grep 'files.*/.' | sed 's#./#http://benchmark.lo/#' > 100k.urls</code><br />
$ <code>find ./10m/ | grep 'files.*/.' | sed 's#./#http://benchmark.lo/#' > 10m.urls</code></p>
<p><strong>benchmark</strong></p>
<pre>
 ______        ____________        ___________
|      |--A-->|            |--B-->|           |
|client|      |proxy server|      |http server|
|______|<--D--|____________|<--C--|___________|

    * client: http_load
    * proxy server: varnish 1.1.2, squid 2.6.STABLE18, and squid 3.0.STABLE2.
    * http server: nginx/0.6.28
</pre>
<p>The Nginx http server only ran the stand alone http service.<br />
The proxy server ran the proxy service only the one been benchmarking at a time.</p>
<p><strong>http_load</strong><br />
It&#8217;s a good load-generator as it</p>
<pre>
    * allows random fetches from a list of URLs
    * allows a large number of parallel requests
    * is portable.
</pre>
<p>There are also other test tools, check <a href="http://www.softwareqatest.com/qatweb1.html#LOAD" target="_blank" rel="nofollow">this page</a> for detail.<br />
<br />
+++ 100KByte +++<br />
<br />
$ <code>http_load -verbose -parallel 100 -fetches 100000 ./100k.urls</code><br />
<br />
* Varnish 1.1.2:</p>
<blockquote><p>
    &#8212; 60 secs, 6868 fetches started, 6768 completed, 100 current<br />
    &#8212; 120 secs, 13720 fetches started, 13620 completed, 100 current<br />
    &#8212; 180 secs, 20570 fetches started, 20470 completed, 100 current<br />
    &#8212; 240 secs, 27432 fetches started, 27332 completed, 100 current<br />
    &#8212; 300 secs, 34285 fetches started, 34185 completed, 100 current<br />
    &#8212; 360 secs, 41140 fetches started, 41040 completed, 100 current<br />
    &#8212; 420 secs, 47996 fetches started, 47896 completed, 100 current<br />
    &#8212; 480 secs, 54854 fetches started, 54754 completed, 100 current<br />
    &#8212; 540 secs, 61709 fetches started, 61609 completed, 100 current<br />
    &#8212; 600 secs, 68565 fetches started, 68465 completed, 100 current<br />
    &#8212; 660 secs, 75419 fetches started, 75319 completed, 100 current<br />
    &#8212; 720 secs, 82279 fetches started, 82179 completed, 100 current<br />
    &#8212; 780 secs, 89131 fetches started, 89031 completed, 100 current<br />
    &#8212; 840 secs, 95989 fetches started, 95889 completed, 100 current<br />
    100000 fetches, 100 max parallel, 1.024e+10 bytes, in 876.794 seconds<br />
    102400 mean bytes/connection<br />
    114.052 fetches/sec, 1.16789e+07 bytes/sec<br />
    msecs/connect: 116.758 mean, 9111.16 max, 0.256 min<br />
    msecs/first-response: 120.03 mean, 2494.66 max, 0.614 min<br />
    HTTP response codes:<br />
      code 200 &#8212; 100000
</p></blockquote>
<p>* Squid 2.6.STABLE18:</p>
<blockquote><p>
    &#8212; 60 secs, 6898 fetches started, 6798 completed, 100 current<br />
    &#8212; 120 secs, 13748 fetches started, 13648 completed, 100 current<br />
    &#8212; 180 secs, 20595 fetches started, 20495 completed, 100 current<br />
    &#8212; 240 secs, 27439 fetches started, 27339 completed, 100 current<br />
    &#8212; 300 secs, 34287 fetches started, 34187 completed, 100 current<br />
    &#8212; 360 secs, 41136 fetches started, 41036 completed, 100 current<br />
    &#8212; 420 secs, 47983 fetches started, 47883 completed, 100 current<br />
    &#8212; 480 secs, 54829 fetches started, 54729 completed, 100 current<br />
    &#8212; 540 secs, 61675 fetches started, 61575 completed, 100 current<br />
    &#8212; 600 secs, 68523 fetches started, 68423 completed, 100 current<br />
    &#8212; 660 secs, 75371 fetches started, 75271 completed, 100 current<br />
    &#8212; 720 secs, 82221 fetches started, 82121 completed, 100 current<br />
    &#8212; 780 secs, 89065 fetches started, 88965 completed, 100 current<br />
    &#8212; 840 secs, 95909 fetches started, 95809 completed, 100 current<br />
    100000 fetches, 100 max parallel, 1.024e+10 bytes, in 878.411 seconds<br />
    102400 mean bytes/connection<br />
    113.842 fetches/sec, 1.16574e+07 bytes/sec<br />
    msecs/connect: 116.02 mean, 9114.65 max, 0.224 min<br />
    msecs/first-response: 115.596 mean, 619.381 max, 0.86 min<br />
    HTTP response codes:<br />
      code 200 &#8212; 100000
</p></blockquote>
<p>* Squid 3.0.STABLE2:</p>
<blockquote><p>
    &#8212; 60 secs, 6885 fetches started, 6785 completed, 100 current<br />
    &#8212; 120 secs, 13720 fetches started, 13620 completed, 100 current<br />
    &#8212; 180 secs, 20577 fetches started, 20477 completed, 100 current<br />
    &#8212; 240 secs, 27418 fetches started, 27318 completed, 100 current<br />
    &#8212; 300 secs, 34266 fetches started, 34166 completed, 100 current<br />
    &#8212; 360 secs, 41111 fetches started, 41011 completed, 100 current<br />
    &#8212; 420 secs, 47957 fetches started, 47857 completed, 100 current<br />
    &#8212; 480 secs, 54812 fetches started, 54712 completed, 100 current<br />
    &#8212; 540 secs, 61656 fetches started, 61556 completed, 100 current<br />
    &#8212; 600 secs, 68503 fetches started, 68403 completed, 100 current<br />
    &#8212; 660 secs, 75346 fetches started, 75246 completed, 100 current<br />
    &#8212; 720 secs, 82198 fetches started, 82098 completed, 100 current<br />
    &#8212; 780 secs, 89040 fetches started, 88940 completed, 100 current<br />
    &#8212; 840 secs, 95891 fetches started, 95791 completed, 100 current<br />
    100000 fetches, 100 max parallel, 1.024e+10 bytes, in 876.658 seconds<br />
    102400 mean bytes/connection<br />
    114.07 fetches/sec, 1.16807e+07 bytes/sec<br />
    msecs/connect: 115.858 mean, 9111.16 max, 0.26 min<br />
    msecs/first-response: 116.423 mean, 3318.18 max, 29.481 min<br />
    HTTP response codes:<br />
      code 200 &#8212; 100000
</p></blockquote>
<p>+++ 10MByte +++<br />
<br />
$ <code>http_load -verbose -parallel 100 -fetches 1000 ./10m.urls</code><br />
<br />
* Varnish 1.1.2:</p>
<blockquote><p>
    &#8212; 60 secs, 100 fetches started, 0 completed, 100 current<br />
    &#8212; 120 secs, 196 fetches started, 96 completed, 100 current<br />
    &#8212; 180 secs, 231 fetches started, 131 completed, 100 current<br />
    &#8212; 240 secs, 304 fetches started, 204 completed, 100 current<br />
    &#8212; 300 secs, 389 fetches started, 289 completed, 100 current<br />
    &#8212; 360 secs, 434 fetches started, 334 completed, 100 current<br />
    &#8212; 420 secs, 509 fetches started, 409 completed, 100 current<br />
    &#8212; 480 secs, 585 fetches started, 485 completed, 100 current<br />
    &#8212; 540 secs, 637 fetches started, 537 completed, 100 current<br />
    &#8212; 600 secs, 714 fetches started, 614 completed, 100 current<br />
    &#8212; 660 secs, 786 fetches started, 686 completed, 100 current<br />
    &#8212; 720 secs, 844 fetches started, 744 completed, 100 current<br />
    &#8212; 780 secs, 915 fetches started, 815 completed, 100 current<br />
    &#8212; 840 secs, 987 fetches started, 887 completed, 100 current<br />
    1000 fetches, 100 max parallel, 1.04858e+10 bytes, in 899.718 seconds<br />
    1.04858e+07 mean bytes/connection<br />
    1.11146 fetches/sec, 1.16545e+07 bytes/sec<br />
    msecs/connect: 129.428 mean, 3128.09 max, 0.291 min<br />
    msecs/first-response: 1003.12 mean, 9619.7 max, 120.662 min<br />
    HTTP response codes:<br />
      code 200 &#8212; 1000
</p></blockquote>
<p>* Squid 2.6.STABLE18:</p>
<blockquote><p>
    &#8212; 60 secs, 103 fetches started, 3 completed, 100 current<br />
    &#8212; 120 secs, 178 fetches started, 78 completed, 100 current<br />
    &#8212; 180 secs, 255 fetches started, 155 completed, 100 current<br />
    &#8212; 240 secs, 322 fetches started, 222 completed, 100 current<br />
    &#8212; 300 secs, 379 fetches started, 279 completed, 100 current<br />
    &#8212; 360 secs, 458 fetches started, 358 completed, 100 current<br />
    &#8212; 420 secs, 518 fetches started, 418 completed, 100 current<br />
    &#8212; 480 secs, 583 fetches started, 483 completed, 100 current<br />
    &#8212; 540 secs, 661 fetches started, 561 completed, 100 current<br />
    &#8212; 600 secs, 721 fetches started, 621 completed, 100 current<br />
    &#8212; 660 secs, 786 fetches started, 686 completed, 100 current<br />
    &#8212; 720 secs, 863 fetches started, 763 completed, 100 current<br />
    &#8212; 780 secs, 926 fetches started, 826 completed, 100 current<br />
    &#8212; 840 secs, 984 fetches started, 884 completed, 100 current<br />
    1000 fetches, 100 max parallel, 1.04858e+10 bytes, in 894.062 seconds<br />
    1.04858e+07 mean bytes/connection<br />
    1.11849 fetches/sec, 1.17282e+07 bytes/sec<br />
    msecs/connect: 137.644 mean, 9128.16 max, 0.283 min<br />
    msecs/first-response: 131.811 mean, 3509.99 max, 28.891 min<br />
    HTTP response codes:<br />
      code 200 &#8212; 1000
</p></blockquote>
<p>* Squid 3.0.STABLE2:</p>
<blockquote><p>
    &#8212; 60 secs, 105 fetches started, 5 completed, 100 current<br />
    &#8212; 120 secs, 190 fetches started, 90 completed, 100 current<br />
    http://benchmark.lo/10m/files-2/2: timed out<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: timed out<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-5/2: timed out<br />
    http://benchmark.lo/10m/files-5/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: timed out<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: timed out<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    &#8212; 180 secs, 260 fetches started, 160 completed, 100 current<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-1/1: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-3/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/1: byte count wrong<br />
    http://benchmark.lo/10m/files-4/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    http://benchmark.lo/10m/files-2/2: byte count wrong<br />
    &#8212; 240 secs, 315 fetches started, 215 completed, 100 current<br />
    &#8212; 300 secs, 395 fetches started, 295 completed, 100 current<br />
    &#8212; 360 secs, 464 fetches started, 364 completed, 100 current<br />
    &#8212; 420 secs, 521 fetches started, 421 completed, 100 current<br />
    &#8212; 480 secs, 596 fetches started, 496 completed, 100 current<br />
    &#8212; 540 secs, 664 fetches started, 564 completed, 100 current<br />
    &#8212; 600 secs, 725 fetches started, 625 completed, 100 current<br />
    &#8212; 660 secs, 798 fetches started, 698 completed, 100 current<br />
    &#8212; 720 secs, 865 fetches started, 765 completed, 100 current<br />
    &#8212; 780 secs, 929 fetches started, 829 completed, 100 current<br />
    &#8212; 840 secs, 997 fetches started, 897 completed, 100 current<br />
    1000 fetches, 100 max parallel, 1.03922e+10 bytes, in 886.272 seconds<br />
    1.03922e+07 mean bytes/connection<br />
    1.12832 fetches/sec, 1.17258e+07 bytes/sec<br />
    msecs/connect: 130.639 mean, 3127.72 max, 0.21 min<br />
    msecs/first-response: 186.15 mean, 3578.41 max, 34.601 min<br />
    5 timeouts<br />
    53 bad byte counts<br />
    HTTP response codes:<br />
      code 200 &#8212; 1000
</p></blockquote>
<p><strong>proxy server status</strong></p>
<p>+++ 100KByte +++</p>
<p><a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/100kvarnishiostat_xm5.log' title='varnish.iostat_xm5.log'>100k.varnish.iostat_xm5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/100kvarnishvmstat5.log' title='varnish.vmstat5.log'>100k.varnish.vmstat5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/100ksquid2iostat_xm5.log' title='squid2.iostat_xm5.log'>100k.squid2.iostat_xm5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/100ksquid2vmstat5.log' title='squid2.vmstat5.log'>100k.squid2.vmstat5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/100ksquid3iostat_xm5.log' title='squid3.iostat_xm5.log'>100k.squid3.iostat_xm5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/100ksquid3vmstat5.log' title='squid3.vmstat5.log'>100k.squid3.vmstat5.log</a></p>
<p>+++ 10MByte +++</p>
<p><a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/10mvarnishiostat_xm5.log' title='varnish.iostat_xm5.log'>10m.varnish.iostat_xm5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/10mvarnishvmstat5.log' title='10m.varnish.vmstat5.log'>10m.varnish.vmstat5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/10msquid2iostat_xm5.log' title='10m.squid2.iostat_xm5.log'>10m.squid2.iostat_xm5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/10msquid2vmstat5.log' title='10m.squid2.vmstat5.log'>10m.squid2.vmstat5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/10msquid3iostat_xm5.log' title='10m.squid3.iostat_xm5.log'>10m.squid3.iostat_xm5.log</a><br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/10msquid3vmstat5.log' title='10m.squid3.vmstat5.log'>10m.squid3.vmstat5.log</a></p>
<p>After finished each benchmark, the status is as follow:<br />
<a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/bench_varnishstat.png' title='varnishstat'><img src='http://dotimes.com/iscale/wp-content/uploads/2008/03/bench_varnishstat.thumbnail.png' alt='varnishstat' /></a>    <a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/bench_squid2_mgr_info.png' title='squid2_mgr_info'><img src='http://dotimes.com/iscale/wp-content/uploads/2008/03/bench_squid2_mgr_info.thumbnail.png' alt='squid2_mgr_info' /></a>    <a href='http://dotimes.com/iscale/wp-content/uploads/2008/03/bench_squid3_mgr_info.png' title='squid3_mgr_info'><img src='http://dotimes.com/iscale/wp-content/uploads/2008/03/bench_squid3_mgr_info.thumbnail.png' alt='squid3_mgr_info' /></a></p>
<p><strong>conclusion</strong></p>
<p>The data here, the reference in your mind.<br />
That which is the better choice as a caching proxy, depends on your own judgement.</p>
<p><strong>notes</strong></p>
<p>1. Varnish can cache files immediately.<br />
I found this while comparing the fetching of 10MB files.<br />
Varnish just request the nginx server for the file only once, but Squid will requests them for about<br />
10 times of varnish does.</p>
<p>2. Varnish provides easier access to proxy status.</p>
<p>3. Squid is more than a web proxy, while Varnish is more than an http accelerator (cache proxy).<br />
The Varnish web site claims that Varnish is ten to twenty times faster than the popular Squid<br />
cache on the same hardware.</p>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2008/03/benchmark-caching-of-varnish-and-squid.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>an example of Varnish and Lighttpd</title>
		<link>http://dotimes.com/iscale/2007/12/an-example-of-varnish-and-lighttpd.html</link>
		<comments>http://dotimes.com/iscale/2007/12/an-example-of-varnish-and-lighttpd.html#comments</comments>
		<pubDate>Thu, 13 Dec 2007 12:36:52 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[proxy]]></category>

		<category><![CDATA[webserver]]></category>

		<category><![CDATA[lighttpd]]></category>

		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/2007/12/an-example-of-varnish-and-lighttpd.html</guid>
		<description><![CDATA[Lighttpd on server 192.168.123.248 vhost config:

[...]
simple-vhost.server-root = "/var/web"
simple-vhost.default-host = "test.lo"
simple-vhost.document-root = "/www"
$HTTP["host"] =~ "^(www\.)?test\.lo$" {
        server.document-root = "/var/web/www"
}
$HTTP["host"] =~ "^blog\.test\.lo$" {
        server.document-root = "/var/web/blog"
}
[...]

Varnish on server 192.168.123.249 VCL file:

backend test {
set backend.host = "192.168.123.248";
set backend.port = "80";
}

acl purge {
"localhost";
"127.0.0.1";
}

sub vcl_recv {
if [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lighttpd.net/" title="Security, speed, compliance, and flexibility webserver">Lighttpd</a> on server 192.168.123.248 vhost config:</p>
<pre>
[...]
simple-vhost.server-root = "/var/web"
simple-vhost.default-host = "test.lo"
simple-vhost.document-root = "/www"
$HTTP["host"] =~ "^(www\.)?test\.lo$" {
        server.document-root = "/var/web/www"
}
$HTTP["host"] =~ "^blog\.test\.lo$" {
        server.document-root = "/var/web/blog"
}
[...]
</pre>
<p><a href="http://varnish.projects.linpro.no/" title="state-of-the-art, high-performance HTTP accelerator">Varnish</a> on server 192.168.123.249 VCL file:</p>
<pre>
backend test {
set backend.host = "192.168.123.248";
set backend.port = "80";
}

acl purge {
"localhost";
"127.0.0.1";
}

sub vcl_recv {
if (req.http.host ~ "^(www|blog\.)?test\.lo$") {
set req.backend = test;
}

else {
error 404 "Unknown virtual host";
}
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
}
if (req.http.Cache-Control ~ "no-cache") {
pass;
}
if (req.request != "GET" &amp;&amp; req.request != "HEAD") {
pipe;
}
if (req.http.Expect) {
pipe;
}
if (req.http.Authenticate || req.http.Cookie) {
pass;
}
lookup;
}

sub vcl_pipe {
pipe;
}

sub vcl_pass {
pass;
}

sub vcl_hash {
set req.hash += req.url;
set req.hash += req.http.host;
set req.hash += req.http.cookie;
hash;
}

sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
if (!obj.cacheable) {
pass;
}
deliver;
}

sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
fetch;
}

sub vcl_fetch {
if (!obj.valid) {
error;
}
if (!obj.cacheable || obj.http.Set-Cookie|| \
        obj.http.Pragma ~ "no-cache" || \
        obj.http.Cache-Control ~ "no-cache" || \
        obj.http.Cache-Control ~ "private") {
pass;
}
if (req.request == "GET" &amp;&amp; req.url ~ "\.(txt|js)$") {
set obj.ttl = 3600s;
}
else {
set obj.ttl = 30d;
}
insert;
}

sub vcl_deliver {
deliver;
}

sub vcl_timeout {
discard;
}

sub vcl_discard {
discard;
}
</pre>
<p>Above is just a simple example, it works for me currently.<br />
Many people want to see the performance comparison between varnish and squid. Sorry but for now I couldn&#8217;t give that, maybe one day;)<br />
I&#8217;m afraid that there&#8217;s going to be a variety of  troubles to shooting, yeah, definitely.</p>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2007/12/an-example-of-varnish-and-lighttpd.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Varnish cache intro</title>
		<link>http://dotimes.com/iscale/2007/12/varnish-cache-intro.html</link>
		<comments>http://dotimes.com/iscale/2007/12/varnish-cache-intro.html#comments</comments>
		<pubDate>Wed, 12 Dec 2007 03:53:59 +0000</pubDate>
		<dc:creator>Cherife Li</dc:creator>
		
		<category><![CDATA[proxy]]></category>

		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://dotimes.com/iscale/2007/12/varnish-cache-intro.html</guid>
		<description><![CDATA[Varnish is a high performance 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. The Varnish web site claims that Varnish is ten to twenty times faster than [...]]]></description>
			<content:encoded><![CDATA[<p>Varnish is a high performance <a href="http://en.wikipedia.org/wiki/HTTP" title="HTTP" rel="鈥漬ofollow鈥?>HTTP</a> 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. The Varnish web site claims that Varnish is ten to twenty times faster than the popular <a href="http://en.wikipedia.org/wiki/Squid_cache" title="Squid cache" rel="鈥漬ofollow鈥?>Squid cache</a> on the same hardware.</p>
<table id="toc" class="toc" summary="Contents" width="180">
<tr>
<td>
<h4>Contents</h4>
<ul>
<li class="toclevel-1"><a href="http://dotimes.com/iscale/2007/12/varnish-cache-intro.html#History"><span class="tocnumber">1</span> <span class="toctext">History</span></a></li>
<li class="toclevel-1"><a href="http://dotimes.com/iscale/2007/12/varnish-cache-intro.html#Architecture"><span class="tocnumber">2</span> <span class="toctext">Architecture</span></a></li>
<li class="toclevel-1"><a href="http://dotimes.com/iscale/2007/12/varnish-cache-intro.html#Performance"><span class="tocnumber">3</span> <span class="toctext">Performance</span></a></li>
<li class="toclevel-1"><a href="http://dotimes.com/iscale/2007/12/varnish-cache-intro.html#External_links"><span class="tocnumber">4</span> <span class="toctext">External links</span></a></li>
</ul>
</td>
</tr>
</table>
<p><a title="History" name="History" id="History"></a></p>
<h2><span class="editsection"></span><span class="mw-headline">History</span></h2>
<p>The project was initiated by the online branch of the Norwegian tabloid newspaper <a href="http://en.wikipedia.org/wiki/Verdens_Gang" title="Verdens Gang" rel="鈥漬ofollow鈥?>Verdens Gang</a>. The architect and lead developer is Danish independent consultant <a href="http://en.wikipedia.org/wiki/Poul-Henning_Kamp" title="Poul-Henning Kamp" rel="鈥漬ofollow鈥?>Poul-Henning Kamp</a>, with management, infrastructure and additional development being provided by the Norwegian Linux consulting company <a href="http://en.wikipedia.org/wiki/Linpro" title="Linpro" rel="鈥漬ofollow鈥?>Linpro</a>.</p>
<p>Varnish is <a href="http://en.wikipedia.org/wiki/Open_source" title="Open source" rel="鈥漬ofollow鈥?>open source</a> (specifically, it is distributed under a two-clause <a href="http://en.wikipedia.org/wiki/BSD_license" title="BSD license" rel="鈥漬ofollow鈥?>BSD license</a>), but commercial support is available from <a href="http://en.wikipedia.org/wiki/Linpro" title="Linpro" rel="鈥漬ofollow鈥?>Linpro</a>, amongst others. Currently, the rights to the code are jointly held by <a href="http://en.wikipedia.org/wiki/Verdens_Gang" title="Verdens Gang" rel="鈥漬ofollow鈥?>Verdens Gang</a> and <a href="http://en.wikipedia.org/wiki/Linpro" title="Linpro" rel="鈥漬ofollow鈥?>Linpro</a>, but work is under way to transfer them to an independent foundation.</p>
<p><a title="Architecture" name="Architecture" id="Architecture"></a></p>
<h2><span class="editsection"></span><span class="mw-headline">Architecture</span></h2>
<p>Varnish is heavily <a href="http://en.wikipedia.org/wiki/Thread_%28computer_science%29" title="Thread (computer science)" rel="鈥漬ofollow鈥?>threaded</a>, with each client connection being handled by a separate worker thread. When the configured limit on the number of active worker threads is reached, incoming connections are placed in an overflow queue; only when this queue reaches its configured limit will incoming connections be rejected.</p>
<p>The principal configuration mechanism is VCL (<em>Varnish Configuration Language</em>), a <a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language" title="Domain-specific programming language" rel="鈥漬ofollow鈥?>DSL</a> used to write hooks which are called at critical points in the handling of each request. Most policy decisions are left to VCL code, making Varnish far more configurable and adaptable than most other HTTP accelerators. When a VCL script is loaded, it is translated to C, compiled to a shared object by the system compiler, and linked directly into the accelerator.</p>
<p>A number of run-time parameters control things such as the maximum and minimum number of worker threads, various timeouts etc. A command-line management interface allows these parameters to be modified, and new VCL scripts to be compiled, loaded and activated, without restarting the accelerator.</p>
<p>In order to reduce the number of system calls in the fast path to a minimum, log data is stored in <a href="http://en.wikipedia.org/wiki/Shared_memory" title="Shared memory" rel="鈥漬ofollow鈥?>shared memory</a>, and the task of filtering, formatting and writing log data to disk is delegated to a separate application.</p>
<p><a title="Performance" name="Performance" id="Performance"></a></p>
<h2><span class="editsection"></span><span class="mw-headline">Performance</span></h2>
<p>While Varnish is designed to reduce contention between threads to a minimum, its performance will only be as good as that of the system&#8217;s <a href="http://en.wikipedia.org/wiki/POSIX_threads" title="POSIX threads" rel="鈥漬ofollow鈥?>pthreads</a> implementation. Additionally, a poor <a href="http://en.wikipedia.org/wiki/Malloc" title="Malloc" rel="鈥漬ofollow鈥?>malloc</a> implementation may add unnecessary contention and thereby limit performance. On <a href="http://en.wikipedia.org/wiki/FreeBSD" title="FreeBSD" rel="鈥漬ofollow鈥?>FreeBSD</a> (using libthr) and <a href="http://en.wikipedia.org/wiki/Linux" title="Linux" rel="鈥漬ofollow鈥?>Linux</a> (using native threads), it is believed that performance is limited only by hardware.</p>
<p>When the requested document is in cache, response time is typically measured in microseconds. This is significantly better than most HTTP servers, so even sites consisting mostly of static content will benefit from Varnish.</p>
<p><a title="External_links" name="External_links" id="External_links"></a></p>
<h2><span class="mw-headline">External links</span></h2>
<ul>
<li><a href="http://varnish.projects.linpro.no/" class="external text" title="http://varnish.projects.linpro.no/" rel="nofollow">official web site</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dotimes.com/iscale/2007/12/varnish-cache-intro.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
