vmod_directors¶
Varnish Directors Module¶
- Manual section:
3
SYNOPSIS¶
import directors [from "path"] ;
new xround_robin = directors.round_robin()
VOID xround_robin.add_backend(BACKEND)
VOID xround_robin.remove_backend(BACKEND)
BACKEND xround_robin.backend()
new xfallback = directors.fallback(BOOL sticky)
VOID xfallback.add_backend(BACKEND)
VOID xfallback.remove_backend(BACKEND)
BACKEND xfallback.backend()
new xrandom = directors.random()
VOID xrandom.add_backend(BACKEND, REAL)
VOID xrandom.remove_backend(BACKEND)
BACKEND xrandom.backend()
new xhash = directors.hash()
VOID xhash.add_backend(BACKEND, REAL)
VOID xhash.remove_backend(BACKEND)
BACKEND xhash.backend(STRING)
new xshard = directors.shard()
VOID xshard.set_warmup(REAL probability)
VOID xshard.set_rampup(DURATION duration)
VOID xshard.associate(BLOB param)
BOOL xshard.add_backend(BACKEND backend, [STRING ident], [DURATION rampup])
BOOL xshard.remove_backend([BACKEND backend], [STRING ident])
BOOL xshard.clear()
BOOL xshard.reconfigure(INT replicas)
INT xshard.key(STRING)
BACKEND xshard.backend([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy], [BLOB param], [ENUM resolve])
VOID xshard.debug(INT)
new xshard_param = directors.shard_param()
VOID xshard_param.clear()
VOID xshard_param.set([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy])
STRING xshard_param.get_by()
INT xshard_param.get_key()
INT xshard_param.get_alt()
REAL xshard_param.get_warmup()
BOOL xshard_param.get_rampup()
STRING xshard_param.get_healthy()
BLOB xshard_param.use()
CONTENTS¶
DESCRIPTION¶
vmod_directors enables backend load balancing in Varnish.
The module implements load balancing techniques, and also serves as an example on how one could extend the load balancing capabilities of Varnish.
To enable load balancing you must import this vmod (directors).
Then you define your backends. Once you have the backends declared you can add them to a director. This happens in executed VCL code. If you want to emulate the previous behavior of Varnish 3.0 you can just initialize the directors in vcl_init, like this:
sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(backend1);
vdir.add_backend(backend2);
}
As you can see there is nothing keeping you from manipulating the directors elsewhere in VCL. So, you could have VCL code that would add more backends to a director when a certain URL is called.
Note that directors can use other directors as backends.
new xround_robin = directors.round_robin()¶
- Description
Create a round robin director.
This director will pick backends in a round robin fashion.
- Example
new vdir = directors.round_robin();
VOID xround_robin.add_backend(BACKEND)¶
- Description
Add a backend to the round-robin director.
- Example
vdir.add_backend(backend1);
VOID xround_robin.remove_backend(BACKEND)¶
- Description
Remove a backend from the round-robin director.
- Example
vdir.remove_backend(backend1);
BACKEND xround_robin.backend()¶
- Description
Pick a backend from the director.
- Example
set req.backend_hint = vdir.backend();
new xfallback = directors.fallback(BOOL sticky=0)¶
- Description
Create a fallback director.
A fallback director will try each of the added backends in turn, and return the first one that is healthy.
If
sticky
is set to true, the director will keep using the healthy backend, even if a higher-priority backend becomes available. Once the whole backend list is exhausted, it’ll start over at the beginning.- Example
new vdir = directors.fallback();
VOID xfallback.add_backend(BACKEND)¶
- Description
Add a backend to the director.
Note that the order in which this is done matters for the fallback director.
- Example
vdir.add_backend(backend1);
VOID xfallback.remove_backend(BACKEND)¶
- Description
Remove a backend from the director.
- Example
vdir.remove_backend(backend1);
BACKEND xfallback.backend()¶
- Description
Pick a backend from the director.
- Example
set req.backend_hint = vdir.backend();
new xrandom = directors.random()¶
- Description
Create a random backend director.
The random director distributes load over the backends using a weighted random probability distribution. The “testable” random generator in varnishd is used, which enables deterministic tests to be run (See: d00004.vtc).
- Example
new vdir = directors.random();
VOID xrandom.add_backend(BACKEND, REAL)¶
- Description
Add a backend to the director with a given weight.
Each backend will receive approximately 100 * (weight / (sum(all_added_weights))) per cent of the traffic sent to this director.
- Example
- # 2/3 to backend1, 1/3 to backend2.vdir.add_backend(backend1, 10.0);vdir.add_backend(backend2, 5.0);
VOID xrandom.remove_backend(BACKEND)¶
- Description
Remove a backend from the director.
- Example
vdir.remove_backend(backend1);
BACKEND xrandom.backend()¶
- Description
Pick a backend from the director.
- Example
set req.backend_hint = vdir.backend();
new xhash = directors.hash()¶
- Description
Create a hashing backend director.
The director chooses the backend server by computing a hash/digest of the string given to .backend().
Commonly used with
client.ip
or a session cookie to get sticky sessions.- Example
new vdir = directors.hash();
VOID xhash.add_backend(BACKEND, REAL)¶
- Description
Add a backend to the director with a certain weight.
Weight is used as in the random director. Recommended value is 1.0 unless you have special needs.
- Example
vdir.add_backend(backend1, 1.0);
VOID xhash.remove_backend(BACKEND)¶
- Description
Remove a backend from the director.
- Example
vdir.remove_backend(backend1);
BACKEND xhash.backend(STRING)¶
- Description
Pick a backend from the backend director.
Use the string or list of strings provided to pick the backend.
- Example
- # pick a backend based on the cookie header from the clientset req.backend_hint = vdir.backend(req.http.cookie);
new xshard = directors.shard()¶
Create a shard director.
Note that the shard director needs to be configured using at least one
shard.add_backend()
call(s) followed by a
shard.reconfigure()
call before it can hand out backends.
_Note_ that due to various restrictions (documented below), it is recommended to use the shard director on the backend side.
Introduction¶
The shard director selects backends by a key, which can be provided directly or derived from strings. For the same key, the shard director will always return the same backend, unless the backend configuration or health state changes. Conversely, for differing keys, the shard director will likely choose different backends. In the default configuration, unhealthy backends are not selected.
The shard director resembles the hash director, but its main advantage is that, when the backend configuration or health states change, the association of keys to backends remains as stable as possible.
In addition, the rampup and warmup features can help to further improve user-perceived response times.
Method¶
When .reconfigure()
is called, a consistent hashing circular data
structure gets built from the last 32 bits of SHA256 hash values of
<ident><n> (default ident being the backend name) for each
backend and for a running number n from 1 to replicas. Hashing
creates the seemingly random order for placement of backends on the
consistent hashing ring.
When .backend()
is called, a load balancing key gets generated
unless provided. The smallest hash value in the circle is looked up
that is larger than the key (searching clockwise and wrapping around
as necessary). The backend for this hash value is the preferred
backend for the given key.
If a healthy backend is requested, the search is continued linearly on the ring as long as backends found are unhealthy or all backends have been checked. The order of these “alternative backends” on the ring is likely to differ for different keys. Alternative backends can also be selected explicitly.
On consistent hashing see:
svn://svn.audioscrobbler.net/misc/ketama
Error Reporting¶
Failing methods should report errors to VSL with the Error tag, so when configuring the shard director, you are advised to check:
varnishlog -I Error:^shard
VOID xshard.set_warmup(REAL probability=0.0)¶
Set the default warmup probability. See the warmup parameter of
shard.backend()
. If probability is 0.0 (default), warmup is
disabled.
VOID xshard.set_rampup(DURATION duration=0)¶
Set the default rampup duration. See rampup parameter of shard.backend(). If duration is 0 (default), rampup is disabled.
VOID xshard.associate(BLOB param=0)¶
Associate a default obj_shard_param object or clear an association.
The value of the param argument must be a call to the func_shard_param.use method. No argument clears the association.
The association can be changed per backend request using the param argument of func_shard.backend.
BOOL xshard.clear()¶
Remove all backends from the director.
NOTE: Backend changes need to be finalized with shard.reconfigure() and are only supported on one shard director at a time.
BOOL xshard.reconfigure(INT replicas=67)¶
Reconfigure the consistent hashing ring to reflect backend changes.
This method must be called at least once before the director can be used.
INT xshard.key(STRING)¶
Convenience method to generate a sharding key for use with the key
argument to the shard.backend()
method by hashing the given string
with SHA256.
To generate sharding keys using other hashes, use a custom vmod like
vmod blobdigest with the key_blob argument of the
shard.backend()
method.
VOID xshard.debug(INT)¶
intentionally undocumented
new xshard_param = directors.shard_param()¶
Create a shard parameter set.
A parameter set allows for re-use of func_shard.backend arguments across many shard director instances and simplifies advanced use cases (e.g. shard director with custom parameters layered below other directors).
Parameter sets have two scopes:
per-VCL scope defined in
vcl_init{}
per backend request scope
The per-VCL scope defines defaults for the per backend scope. Any changes to a parameter set in backend context only affect the respective backend request.
Parameter sets can not be used in client context.
VOID xshard_param.clear()¶
Reset the parameter set to default values as documented for func_shard.backend.
in
vcl_init{}
, resets the parameter set default for this VCLin backend context, resets the parameter set for this backend request to the VCL defaults
This method may not be used in client context
STRING xshard_param.get_by()¶
Get a string representation of the by enum argument which denotes how a shard director using this parameter object would derive the shard key. See func_shard.backend.
INT xshard_param.get_key()¶
Get the key which a shard director using this parameter object would use. See func_shard.backend.
INT xshard_param.get_alt()¶
Get the alt parameter which a shard director using this parameter object would use. See func_shard.backend.
REAL xshard_param.get_warmup()¶
Get the warmup parameter which a shard director using this parameter object would use. See func_shard.backend.
BOOL xshard_param.get_rampup()¶
Get the rampup parameter which a shard director using this parameter object would use. See func_shard.backend.
STRING xshard_param.get_healthy()¶
Get a string representation of the healthy enum argument which a shard director using this parameter object would use. See func_shard.backend.
BLOB xshard_param.use()¶
This method may only be used in backend context.
For use with the param argument of func_shard.backend to associate this shard parameter set with a shard director.
ACKNOWLEDGEMENTS¶
Development of a previous version of the shard director was partly sponsored by Deutsche Telekom AG - Products & Innovation.
Development of a previous version of the shard director was partly sponsored by BILD GmbH & Co KG.
COPYRIGHT¶
This document is licensed under the same licence as Varnish
itself. See LICENCE for details.
Copyright (c) 2013-2015 Varnish Software AS
Copyright 2009-2018 UPLEX - Nils Goroll Systemoptimierung
All rights reserved.
Authors: Poul-Henning Kamp <phk@FreeBSD.org>
Julian Wiesener <jw@uplex.de>
Nils Goroll <slink@uplex.de>
Geoffrey Simmons <geoff@uplex.de>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.