bionic (3) vmod_directors.3.gz

Provided by: varnish_5.2.1-1ubuntu0.1_amd64 bug

NAME

       vmod_directors - Varnish Directors Module

SYNOPSIS

       import directors [from "path"] ;

CONTENTS

       • round_robin()

       • fallback(BOOL)

       • random()

       • hash()

       • shard()

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.

   round_robin
          new OBJ = round_robin()

       Description
              Create a round robin director.

              This director will pick backends in a round robin fashion.

       Example
              new vdir = directors.round_robin();

   round_robin.add_backend
          VOID round_robin.add_backend(BACKEND)

       Description
              Add a backend to the round-robin director.

       Example
              vdir.add_backend(backend1); vdir.add_backend(backend2);

   round_robin.remove_backend
          VOID round_robin.remove_backend(BACKEND)

       Description
              Remove a backend from the round-robin director.

       Example
              vdir.remove_backend(backend1); vdir.remove_backend(backend2);

   round_robin.backend
          BACKEND round_robin.backend()

       Description
              Pick a backend from the director.

       Example
              set req.backend_hint = vdir.backend();

   fallback
          new OBJ = 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();

   fallback.add_backend
          VOID fallback.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); vdir.add_backend(backend2);

   fallback.remove_backend
          VOID fallback.remove_backend(BACKEND)

       Description
              Remove a backend from the director.

       Example
              vdir.remove_backend(backend1); vdir.remove_backend(backend2);

   fallback.backend
          BACKEND fallback.backend()

       Description
              Pick a backend from the director.

       Example
              set req.backend_hint = vdir.backend();

   random
          new OBJ = 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();

   random.add_backend
          VOID random.add_backend(BACKEND, REAL)

       Description
              Add a backend to the director with a given weight.

              Each backend 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);

   random.remove_backend
          VOID random.remove_backend(BACKEND)

       Description
              Remove a backend from the director.

       Example
              vdir.remove_backend(backend1); vdir.remove_backend(backend2);

   random.backend
          BACKEND random.backend()

       Description
              Pick a backend from the director.

       Example
              set req.backend_hint = vdir.backend();

   hash
          new OBJ = 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();

   hash.add_backend
          VOID hash.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); vdir.add_backend(backend2, 1.0);

   hash.remove_backend
          VOID hash.remove_backend(BACKEND)

       Description
              Remove a backend from the director.

       Example
              vdir.remove_backend(backend1); vdir.remove_backend(backend2);

   hash.backend
          BACKEND hash.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  client  set  req.backend_hint  =
              vdir.backend(req.http.cookie);

   shard
          new OBJ = 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.

   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.

   Sharding
       This  basic  technique  allows for numerous applications like optimizing backend server cache efficiency,
       Varnish clustering or persisting sessions to servers without  keeping  any  state,  and,  in  particular,
       without the need to synchronize state between nodes of a cluster of Varnish servers:

       • Many  applications  use  caches  for  data objects, so, in a cluster of application servers, requesting
         similar objects from the same server may help to optimize efficiency of such caches.

         For example, sharding by URL or some id component of the url has been shown to drastically improve  the
         efficiency of many content management systems.

       • As  special  case  of  the  previous example, in clusters of Varnish servers without additional request
         distribution logic, each cache will need store  all  hot  objects,  so  the  effective  cache  size  is
         approximately the smallest cache size of any server in the cluster.

         Sharding  allows to segregate objects within the cluster such that each object is only cached on one of
         the servers (or on one primary and one backup, on a primary for long  and  others  for  short  etc...).
         Effectively,  this will lead to a cache size in the order of the sum of all individual caches, with the
         potential to drastically increase efficiency (scales by the number of servers).

       • Another application is to implement persistence of backend requests, such that all requests  sharing  a
         certain criterion (such as an IP address or session ID) get forwarded to the same backend server.

       When  used  with  clusters  of varnish servers, the shard director will, if otherwise configured equally,
       make the same decision on all servers. In other words, requests sharing a common criterion  used  as  the
       shard  key  will  be  balanced onto the same backend server(s) no matter which Varnish server handles the
       request.

       The drawbacks are:

       • the distribution of requests depends on the number of requests  per  key  and  the  uniformity  of  the
         distribution  of key values. In short, while this technique may lead to much better efficiency overall,
         it may also lead to less good load balancing for specific cases.

       • When a backend server becomes unavailable, every persistence technique has to reselect  a  new  backend
         server, but this technique will also switch back to the preferred server once it becomes healthy again,
         so when used for persistence, it is generally less stable compared to stateful techniques (which  would
         continue to use a selected server for as long as possible (or dictated by a TTL)).

   Method
       When  .reconfigure()  is called, a consistent hashing circular data structure gets built from hash values
       of "ident%d" (default ident being the backend name) for each backend and for a running number from 1 to n
       (n  is  the  number of 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:

       • http://www8.org/w8-papers/2a-webserver/caching/paper2.htmlhttp://www.audioscrobbler.net/development/ketama/

       • svn://svn.audioscrobbler.net/misc/ketama

       • http://en.wikipedia.org/wiki/Consistent_hashing

   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

   shard.set_warmup
          VOID shard.set_warmup(REAL probability=0.0)

       Set the default warmup probability. See the warmup parameter of shard.backend().

       Default: 0.0 (no warmup)

   shard.set_rampup
          VOID shard.set_rampup(DURATION duration=0)

       Set the default rampup duration. See rampup parameter of shard.backend().

       Default: 0s (no rampup)

   shard.add_backend
          BOOL shard.add_backend(PRIV_TASK, BACKEND backend, STRING ident=0, DURATION rampup=973279260)

       Add a backend backend to the director.

       ident:  Optionally  specify  an  identification  string  for  this  backend,  which  will  be  hashed  by
       shard.reconfigure() to construct the consistent hashing ring. The identification string defaults  to  the
       backend name.

       ident allows to add multiple instances of the same backend.

       rampup: Optionally specify a specific rampup time for this backend. The magic default value of 973279260s
       instructs the shard director to use the default rampup time (see func_shard.set_rampup).

       NOTE: Backend changes need to be finalized with shard.reconfigure() and are only supported on  one  shard
       director at a time.

   shard.remove_backend
          BOOL shard.remove_backend(PRIV_TASK, BACKEND backend=0, STRING ident=0)

       Remove  backend(s) from the director. Either backend or ident must be specified. ident removes a specific
       instance. If backend is given without ident, all instances of this backend are removed.

       NOTE: Backend changes need to be finalized with shard.reconfigure() and are only supported on  one  shard
       director at a time.

   shard.clear
          BOOL shard.clear(PRIV_TASK)

       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.

   shard.reconfigure
          BOOL shard.reconfigure(PRIV_TASK, INT replicas=67, ENUM {CRC32,SHA256,RS} alg="SHA256")

       Reconfigure the consistent hashing ring to reflect backend changes.

       This method must be called at least once before the director can be used.

   shard.key
          INT shard.key(STRING string, ENUM {CRC32,SHA256,RS} alg="SHA256")

       Utility method to generate a sharding key for use with the shard.backend() method by hashing string  with
       hash algorithm alg.

   shard.backend
          BACKEND shard.backend(ENUM {HASH,URL,KEY,BLOB} by="HASH", INT key=0, BLOB key_blob=0, INT alt=0, REAL warmup=-1, BOOL rampup=1, ENUM {CHOSEN,IGNORE,ALL} healthy="CHOSEN")

       Lookup a backend on the consistent hashing ring.

       This  documentation  uses  the  notion  of an order of backends for a particular shard key. This order is
       deterministic but seemingly random as determined by the consistent hashing algorithm  and  is  likely  to
       differ for different keys, depending on the number of backends and the number of replicas. In particular,
       the backend order referred to here is _not_ the order given when backends are added.

       • by how to determine the sharding key

         default: HASHHASH:

           • when called in backend context: Use the varnish hash value as set by vcl_hash

           • when called in client content: hash req.urlURL: hash req.url / bereq.url

         • KEY: use the key argument

         • BLOB: use the key_blob argument

         • key lookup key with by=KEY

           the shard.key() function may come handy to generate a sharding key from custom strings.

         • key_blob lookup key with by=BLOB

           Currently, this uses the first 4 bytes from the given  blob  in  network  byte  order  (big  endian),
           left-padded with zeros for blobs smaller than 4 bytes.

       • alt alternative backend selection

         default: 0

         Select the alt-th alternative backend for the given key.

         This  is  particularly useful for retries / restarts due to backend errors: By setting alt=req.restarts
         or alt=bereq.retries with healthy=ALL, another server gets selected.

         The rampup and warmup features are only active for alt==0rampup slow start for servers which just went healthy

         default: true

         If alt==0 and the chosen backend is in its rampup  period,  with  a  probability  proportional  to  the
         fraction  of  time  since  the  backup became healthy to the rampup period, return the next alternative
         backend, unless this is also in its rampup period.

         The default rampup interval can be set per shard director using the set_rampup() method or specifically
         per backend with the set_backend() method.

       • warmup probabilistic alternative server selection

         possible values: -1, 0..1

         default: -1

         -1: use the warmup probability from the director definition

         Only  used  for alt==0: Sets the ratio of requests (0.0 to 1.0) that goes to the next alternate backend
         to warm it up when the preferred backend is healthy. Not active if any of the preferred or  alternative
         backend are in rampup.

         warmup=0.5 is a convenient way to spread the load for each key over two backends under normal operating
         conditions.

       • healthy

         default: CHOSEN

         • CHOSEN: Return a healthy backend if possible.

           For alt==0, return the first healthy backend or none.

           For alt > 0, ignore the health state of backends skipped  for  alternative  backend  selection,  then
           return  the  next  healthy  backend. If this does not exist, return the last healthy backend of those
           skipped or none.

         • IGNORE: Completely ignore backend health state

           Just return the first or alt-th alternative backend, ignoring health state. Ignore rampup and warmup.

         • ALL: Check health state also for alternative backend selection

           For alt > 0, return the alt-th alternative backend of all those healthy,  the  last  healthy  backend
           found or none.

   shard.debug
          VOID shard.debug(INT)

       intentionally undocumented

ACKNOWLEDGEMENTS

       Development  of  a  previous  version of the shard director was partly sponsored by Deutsche Telekom AG -
       Products & Innovation.

       Development of this version of the shard director was partly sponsored by BILD GmbH & Co KG.

          This document is licensed under the same licence as Varnish
          itself. See LICENCE for details.

          Copyright (c) 2013-2015 Varnish Software AS
          Copyright 2009-2016 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.

                                                                                               VMOD_DIRECTORS(3)