Search
Varnish Enterprise

directors

Description

The directors VMOD enables backend load balancing in Varnish. It is the standard directors module from Varnish Cache and is included in the main Varnish Enterprise package.

A director groups a set of backends and picks one of them for each backend request according to a load balancing policy. Directors can use other directors as backends, so policies can be layered.

The module provides four load balancing policies:

  • round_robin: pick backends in turn.
  • fallback: always use the first healthy backend in the order they were added.
  • random: distribute load using a weighted random distribution.
  • hash: pick a backend based on a hash of a string, for example a cookie or the client IP.
  • shard: consistent hashing; like hash, but keeps the key-to-backend association as stable as possible when the backend configuration or health state changes.

For advanced use cases, consider udo (Unified Director Object), the Varnish Enterprise successor to this module. udo covers the same load balancing policies in a single configurable director object and adds features such as dynamic backends and integration with activedns.

Directors are created in sub vcl_init, and backends are added to them there or later from other VCL code:

vcl 4.1;

import directors;

backend backend1 { .host = "192.0.2.11"; .port = "8080"; }
backend backend2 { .host = "192.0.2.12"; .port = "8080"; }

sub vcl_init {
	new vdir = directors.round_robin();
	vdir.add_backend(backend1);
	vdir.add_backend(backend2);
}

sub vcl_recv {
	set req.backend_hint = vdir.backend();
}

round_robin

new vdir = directors.round_robin()

Creates a round robin director. The director picks backends in a round robin fashion.

.add_backend

VOID vdir.add_backend(BACKEND backend)

Adds a backend to the round robin director.

.remove_backend

VOID vdir.remove_backend(BACKEND backend)

Removes a backend from the round robin director.

.backend

BACKEND vdir.backend()

Picks a backend from the director:

set req.backend_hint = vdir.backend();

fallback

new vdir = directors.fallback(BOOL sticky = 0)

Creates a fallback director. A fallback director tries each of the added backends in turn and returns the first one that is healthy. The order in which backends are added matters.

If sticky is set to true, the director keeps using the healthy backend it has chosen, even if a higher-priority backend becomes available again. Once the whole backend list is exhausted, it starts over at the beginning.

.add_backend

VOID vdir.add_backend(BACKEND backend)

Adds a backend to the director. The order in which backends are added determines the fallback priority.

.remove_backend

VOID vdir.remove_backend(BACKEND backend)

Removes a backend from the director.

.backend

BACKEND vdir.backend()

Picks a backend from the director.

random

new vdir = directors.random()

Creates a random director. The random director distributes load over the backends using a weighted random probability distribution.

.add_backend

VOID vdir.add_backend(BACKEND backend, REAL weight)

Adds a backend to the director with a given weight. Each backend receives approximately 100 * (weight / sum(all_added_weights)) percent of the traffic sent to this director.

# 2/3 of the traffic to backend1, 1/3 to backend2
vdir.add_backend(backend1, 10.0);
vdir.add_backend(backend2, 5.0);

.remove_backend

VOID vdir.remove_backend(BACKEND backend)

Removes a backend from the director.

.backend

BACKEND vdir.backend()

Picks a backend from the director.

hash

new vdir = directors.hash()

Creates a hashing director. The director chooses the backend by computing a hash of the string given to .backend(). Commonly used with client.ip or a session cookie to get sticky sessions.

.add_backend

VOID vdir.add_backend(BACKEND backend, REAL weight)

Adds a backend to the director with a given weight. Weight is used as in the random director. The recommended value is 1.0 unless you have special needs.

.remove_backend

VOID vdir.remove_backend(BACKEND backend)

Removes a backend from the director.

.backend

BACKEND vdir.backend(STRING string)

Picks a backend from the director based on the given string:

# Pick a backend based on the client's session cookie
set req.backend_hint = vdir.backend(req.http.cookie);

shard

new vdir = directors.shard()

Creates a shard director. The shard director selects backends by a key, which can be provided directly or derived from strings. For the same key, the shard director always returns the same backend, unless the backend configuration or health state changes. For differing keys, the shard director will likely choose different backends.

The shard director resembles the hash director, but when the backend configuration or health state changes, the association of keys to backends remains as stable as possible (consistent hashing). This is useful for optimizing backend cache efficiency, for segregating objects across a cluster of Varnish servers, and for persisting sessions to servers without keeping any state.

When used in clusters of Varnish servers that are otherwise configured equally, the shard director makes the same decision on all servers.

The shard director must be configured using at least one .add_backend() call followed by a .reconfigure() call before it can hand out backends. It is recommended to use the shard director on the backend side (in sub vcl_backend_fetch).

Failing shard methods report errors to the Varnish log with the Error tag; check with:

varnishlog -I Error:^shard

.add_backend

BOOL vdir.add_backend(BACKEND backend, [STRING ident],
    [DURATION rampup], [REAL weight])

Adds backend backend to the director.

Arguments:

  • ident: optional identification string for this backend, hashed by .reconfigure() to construct the consistent hashing ring. Defaults to the backend name. ident allows adding multiple instances of the same backend.
  • rampup: optional rampup time specific to this backend. Otherwise, the per-director rampup time set with .set_rampup() is used.
  • weight: optional weight scaling the .reconfigure() replicas parameter for this backend. Limited to at least 1; values above 10 probably do not make much sense.

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

.remove_backend

BOOL vdir.remove_backend([BACKEND backend], [STRING ident])

Removes 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. Requires a subsequent .reconfigure() call.

.clear

BOOL vdir.clear()

Removes all backends from the director. Requires a subsequent .reconfigure() call.

.reconfigure

BOOL vdir.reconfigure(INT replicas = 67)

Rebuilds the consistent hashing ring to reflect backend changes. This method must be called at least once before the director can be used.

.key

INT vdir.key(STRING)

Convenience method to generate a sharding key for use with the key argument of .backend(), by hashing the given string with SHA256.

.set_rampup

VOID vdir.set_rampup(DURATION duration = 0)

Sets the default rampup duration: newly healthy backends are eased into service over this period. See the rampup parameter of .backend(). If duration is 0 (the default), rampup is disabled.

.set_warmup

VOID vdir.set_warmup(REAL probability = 0.0)

Sets the default warmup probability: the ratio of requests sent to the next alternative backend to keep it warm. See the warmup parameter of .backend(). If probability is 0.0 (the default), warmup is disabled.

.associate

VOID vdir.associate(BLOB param = 0)

Associates a default shard_param parameter set with this director, or clears the association when called without argument. The param argument must be a call to the shard_param object’s .use() method.

.backend

BACKEND vdir.backend(
    [ENUM {HASH, URL, KEY, BLOB} by = HASH],
    [INT key], [BLOB key_blob], [INT alt = 0],
    [REAL warmup = -1], [BOOL rampup = 1],
    [ENUM {CHOSEN, IGNORE, ALL} healthy = CHOSEN],
    [BLOB param], [ENUM {NOW, LAZY} resolve])

Looks up a backend on the consistent hashing ring.

Arguments:

  • by: how to determine the sharding key. HASH (default) uses the Varnish hash value as set by sub vcl_hash when called in backend context, and hashes req.url in client context. URL hashes req.url/bereq.url. KEY uses the key argument. BLOB uses the key_blob argument.
  • key: the lookup key when by=KEY. The .key() method can be used to generate one from a string.
  • key_blob: the lookup key when by=BLOB. Uses the first 4 bytes of the blob in network byte order.
  • alt: selects the alt-th alternative backend for the key. Useful for retries and restarts: setting alt=req.restarts or alt=bereq.retries with healthy=ALL selects another server. Rampup and warmup are only active for alt=0.
  • rampup: if true (default), spread traffic onto a backend that just became healthy gradually over the rampup period.
  • warmup: ratio (0.0 to 1.0) of requests for alt=0 that go to the next alternative backend to keep it warm. -1 (default) uses the probability set with .set_warmup(). warmup=0.5 is a convenient way to spread the load for each key over two backends.
  • healthy: CHOSEN (default) returns a healthy backend if possible. IGNORE returns the selected backend regardless of health state, ignoring rampup and warmup. ALL also checks health state for alternative backend selection.
  • param: use or associate a shard_param parameter set; the value must be a call to the shard_param object’s .use() method.
  • resolve: NOW looks up a backend and returns it (cannot be used in sub vcl_init). LAZY returns an instance of the director for later resolution, which is required when layering the shard director under other directors. The default is LAZY in sub vcl_init and NOW otherwise.

shard_param

new p = directors.shard_param()

Creates a shard parameter set: a reusable group of .backend() arguments that can be shared across many shard director instances. This simplifies advanced use cases such as layering a shard director with custom parameters below other directors.

Parameter sets defined in sub vcl_init set per-VCL defaults; changes made in backend context only affect the current backend request. Parameter sets cannot be used in client context except in sub vcl_pipe.

.set

VOID p.set([ENUM by], [INT key], [BLOB key_blob], [INT alt],
    [REAL warmup], [BOOL rampup], [ENUM healthy])

Changes the given parameters, as documented for the shard director’s .backend() method.

.clear

VOID p.clear()

Resets the parameter set to its default values.

.use

BLOB p.use()

For use with the param argument of the shard director’s .backend() method, or the .associate() method, to associate this parameter set with a shard director. May only be used in backend context and in sub vcl_pipe.

Getters

STRING p.get_by()
INT p.get_key()
INT p.get_alt()
REAL p.get_warmup()
BOOL p.get_rampup()
STRING p.get_healthy()

Return the respective parameter value that a shard director using this parameter set would use.


®Varnish Software, Wallingatan 12, 111 60 Stockholm, Organization nr. 556805-6203