<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[No Downtime Reality]]></title><description><![CDATA[The road to sysadmin glory!]]></description><link>https://blog.anine.io/</link><generator>Ghost 0.11</generator><lastBuildDate>Wed, 04 Oct 2023 18:52:24 GMT</lastBuildDate><atom:link href="https://blog.anine.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[VARNISHSTAT – VARNISH PERFORMANCE TUNING (PART II)]]></title><description><![CDATA[How to use varnishstat to achieve highest Varnish performance. Explains all important variables and what they are affected by.]]></description><link>https://blog.anine.io/varnishstat-varnish-performance-tuning-part-ii-2/</link><guid isPermaLink="false">47086a21-44e5-40da-b73b-9a42bdf8bf52</guid><category><![CDATA[varnish]]></category><category><![CDATA[performance]]></category><category><![CDATA[tuning]]></category><category><![CDATA[sysadmin]]></category><category><![CDATA[linux]]></category><category><![CDATA[kernel]]></category><category><![CDATA[varnishstat]]></category><dc:creator><![CDATA[Nenad Merdanovic]]></dc:creator><pubDate>Mon, 16 May 2016 20:31:33 GMT</pubDate><content:encoded><![CDATA[<h3 id="usingvarnishstat">Using varnishstat</h3>

<p>In <a href="https://blog.anine.io/varnish-performance-tuning-part-i/">Part I</a> of this series, we talked about basic variables that can be used to tune performance of Varnish.  In this part of the series, we will discuss tools that can help us understand what to optimize and by how much.</p>

<p>The single most important tool for tuning Varnish performance is varnishstat. The tool comes bundled with Varnish and shows you a number of counters and rates which, when interpreted, will show you which variables you must tune further to get the most out of your Varnish installation. There are two ways to run varnishstat, with or without the ‘-1’ flag. If you run it without the flag, you will get a continuously updating display which will show you rates. If you run it with the flag, you will just get a static output over the last update interval.  We will show just the important variables and explain some of them.</p>

<p>To better explain what each metric is and what are the most important ones, we will group them to the following groups:</p>

<ul>
<li>Client and backend related</li>
<li>Worker thread related</li>
<li>ESI related</li>
<li>Storage backend related</li>
<li>Client and Backend Related</li>
</ul>

<pre><code># varnishstat -1
client_conn        4234206     41.27   Client connections accepted  
client_drop        0       0.00    Connection dropped, no sess/wrk  
client_req        29233157    284.94  Client requests received  
cache_hit        32093887    312.82  Cache hits  
cache_hitpass        921         0.01    Cache hits for pass  
cache_miss         422706      4.12    Cache misses  
backend_conn        57122       0.56    Backend conn. success  
backend_unhealthy    0       0.00    Backend conn. not attempted  
backend_busy         0       0.00    Backend conn. too many  
backend_fail         0       0.00    Backend conn. failures  
</code></pre>

<p>The most important variables to watch are client_drop, backend_busy, backend_unhealthy and backend_fail. The first one usually happens when you go over session_max or queue_max. The default values for those two variable are good enough and if you see client_drop increasing you should look into other things (thread workers, queue sizes, backend speed, cache hit ratio, etc.) and not blindly increase those two.  The backend_busy variable indicates that you have reached the maximum amount of connections to your backend. Do not blindly increase that variable either as you may overload your backend. Last two variables, backend_unhealthy and backend_fail, indicate that either your backend was declared unhealthy by Varnish due to failing checks or it was a pure connection failure (network issue for example). <br>
Worker Threads Related</p>

<pre><code># varnishstat -1
n_wrk               100         .       N worker threads  
n_wrk_create         2853            0.03    N worker threads created  
n_wrk_failed           0           0.00    N worker threads not created  
n_wrk_max               0           0.00    N worker threads limited  
n_wrk_lqueue           0           0.00    work request queue length  
n_wrk_queued           13614           0.13    N queued work requests  
n_wrk_drop             0           0.00    N dropped work requests  
</code></pre>

<p>Worker thread related metrics give you insight if you have  properly tuned your thread pools and their sizes. n_wrk_max metric will show you how many times you have exhausted your thread pools and threads failed to be created. Queue metric, n_wrk_lqueue, shows you the current queue length (requests waiting on worker thread to become available). Two metrics, n_wrk_queued and n_wrk_drop show you how many times a request has been queued and how many times it was dropped due exceeding queue length. <br>
ESI Related</p>

<pre><code># varnishstat -1
esi_errors              0           0.00    ESI parse errors (unlock)  
esi_warnings            0           0.00    ESI parse warnings (unlock)  
</code></pre>

<p>If you are using Edge Side Includes [1], esi<em>errors and esi</em>warnings will give you information about the validity of your ESI syntax. If you see them increasing, inspect what is returned by the backend regarding ESI and fix any errors found. <br>
Storage Backend Related</p>

<pre><code># varnishstat -1
n_lru_nuked            128154          .       N LRU nuked objects  
SMA.s0.c_req               1129966         10.98   Allocator requests  
SMA.s0.c_fail           128616             1.25    Allocator failures  
SMA.s0.g_bytes            4294824024      .       Bytes outstanding  
SMA.s0.g_space          143272          .       Bytes available  
SMA.Transient.c_req     24264             0.24    Allocator requests  
SMA.Transient.c_fail    0             0.00    Allocator failures  
SMA.Transient.g_bytes   27464              .       Bytes outstanding  
SMA.Transient.g_space   0              .       Bytes available  
</code></pre>

<p>Here we have an example of the malloc storage backend and you can see that there are two types of storage, s0 and Transient. Transient storage is used by Varnish to store short-lived objects. What Varnish considers short-lived is defined by the shortlived variable – value is in seconds and it defaults to 10. Storage s0 is the storage defined with the -s flag and it is used to store all other objects. Varnishstat displays information about failed allocations in s0.c_fail and this is usually a result of reaching the cache size limit. The last variables, g_bytes and g_bytes show you the amount of used and free space. One of the most important variables found in varnishstat is the n_lru_nuked variable, which tells you how many objects got removed from cache based on the LRU algorithm. If this number is increasing fast, consider raising your cache size. <br>
Conclusion</p>

<p>We have explained how varnishstat works and how it can be used to debug your Varnish installation. Hopefully this will be enough for you to start using varnishstat and understand where your Varnish might be bottlenecking or working non-optimally.</p>

<p>[1] ESI specification – <a href="http://www.w3.org/TR/esi-lang">http://www.w3.org/TR/esi-lang</a></p>]]></content:encoded></item><item><title><![CDATA[VARNISH PERFORMANCE TUNING (PART I)]]></title><description><![CDATA[Learn all about tuning Varnish for maximum performance. Understand thread pool tuning, memory usage, storage engines, kernel parameters ]]></description><link>https://blog.anine.io/varnish-performance-tuning-part-i/</link><guid isPermaLink="false">edca8fd6-7741-48b6-b939-6c572bc7611d</guid><category><![CDATA[varnish]]></category><category><![CDATA[kernel]]></category><category><![CDATA[sysadmin]]></category><category><![CDATA[performance]]></category><category><![CDATA[linux]]></category><category><![CDATA[tuning]]></category><dc:creator><![CDATA[Nenad Merdanovic]]></dc:creator><pubDate>Sat, 14 May 2016 20:40:26 GMT</pubDate><content:encoded><![CDATA[<h3 id="introduction">Introduction</h3>

<p>Varnish is a caching engine that is installed in front of a website to speed up delivery. It is used in front of many high traffic sites to do just that without requiring high number of backend servers.</p>

<p>Reading this article series will get you through basic Varnish performance tuning as well as monitoring crucial metrics. You will also learn how to use Varnish effectively with other popular software (like HAproxy and Nginx) and what the common pitfalls are. Last thing to keep in mind when building large scale infrastructures, like the ones managed by A-nine, is to never over-engineer or over-optimize a solution.</p>

<h3 id="varnishstorageengines">Varnish Storage Engines</h3>

<p>Varnish has three main storage engines: malloc, file and persistent. The last one is experimental and will likely be removed from future versions of Varnish, so we will not consider it.</p>

<p>File based storage engine is, well, a file.  mmap(2) is called to map the file to Varnish’s virtual memory. It is worth noting that file is not persistent and every restart of varnish will cause all of cache to be dropped.  File backed storage should be used when you don’t have enough main memory to cache all content and the speed of your IO subsystem overcomes the speed of content generation. For example, you have a slow storage where your content  resides and you want to keep the hot content in cache on smaller, but faster, IO system.</p>

<p>Malloc based storage works so that each object is allocated memory space using the malloc(3) system call. This is the fastest type of cache as memory access latency and throughput are a few orders of magnitude lower/faster than even the fastest SSD drives.</p>

<p>Long story short, use malloc backend if the content set of interest fits into memory and file if it doesn’t. Storage backends are chosen with the -s parameter. For example: <br>
<code>-s malloc,12G</code></p>

<h3 id="varnishthreads">Varnish threads</h3>

<p>Second most important thing to tune are Varnish threads. Varnish uses a few types of threads performing various tasks, but here we will focus on the most important ones – cache-worker threads. Cache worker threads are the ones that will actually serve the HTTP request that was sent. There are three variables that we will focus on here: thread<em>pools, thread</em>pool<em>min and thread</em>pool_max.</p>

<p>The first variable, thread_pools is, as the name says, number of pools that threads will be grouped into. Each of them will consist of at least thread_pool_min and no more than thread_pool_max. This variable is set to ‘2’ by default and is recommended you leave it like that. No noticeable performance improvement was observed by upping its value.</p>

<p>The second variable, thread<em>pool</em>min, defines the minimum amount of threads that always need to be alive in (per thread pool), even if idle. It is wise to keep a decent amount of threads idle (we usually like to keep at least 30-40) as creating threads is an expensive operations, compared to having them run idle. This way if you have a sudden spike in traffic, you will have enough threads to handle the first hit while new ones are being spawned.</p>

<p>The third variable, thread_pool_max, defines the maximum amount of threads to run per thread pool. This variable obviously needs to be high enough to accommodate your traffic and needs to be adjusted per workload. Usually, you don’t want to go over 5000 threads as specified in the documentation.</p>

<p>Last thing to consider is a variable called thread<em>pool</em>stack and we have had good experience setting it to 256k. Otherwise Varnish threads will use your system default which, depending on the operating system, can cause quite a lot of memory waste.</p>

<h3 id="iosystemtuning">IO system tuning</h3>

<p>Most important thing is to mount the Varnish working directory (where the shmlog is stored) to tmpfs. <br>
<code>tmpfs /usr/lib/varnish tmpfs rw,size=256M 0 0</code></p>

<p>In case you are using the file backend, make sure you set noatime on the file systems where that file is saved. This will prevent unneeded IO to update the file’s access times (which is useless for Varnish). Be sure that your partitions are aligned, that your RAID systems have decent chunk sizes (depending on your filesize) and that file systems are aligned to those chunk sizes.</p>

<h3 id="networkrelated">Network related</h3>

<p>Last, but not least, one must tune the network parameters of Varnish and the operating system (we will stick to Linux here). There is a lot of low level thinking to this, but we will stick to things that have most effect. The single most important thing is to properly size your listen queue size (and the later described sysctl). Listen queue size is passed to the listen(2) system call and will limit the size of not-yet-accepted connections by the application (and connections in SYN<em>RECV state in case smaller than tcp</em>max<em>syn</em>backlog).</p>

<p>Varnish can set the listen backlog size using the the -p parameter as follows: <br>
<code>-p listen_depth=16383</code></p>

<p>We use 16383 as the number is first incremented by the kernel and then rounded up to the higher power of two. There is also a sysctl that controls the maximum size of the listen backlog, net.somaxconn. You should set it higher than the listen depth, but be careful as it is represented as uint_16 in the kernel, so the maximum value is 65535.</p>

<p>Other variables to consider are: tcp_max_syn_backlog, net.ipv4.tcp_tw_reuse, net.ipv4.tcp_max_tw_buckets, net.ipv4.ip_local_port_range and net.ipv4.tcp_syncookies. Going into kernel tuning details is out of scope of this article.</p>

<p>That would be all in part I. In the next blog post we will see how to understand Varnish variables, as well as monitor and debug it. Stay tuned!</p>]]></content:encoded></item></channel></rss>