Module resty.dns.balancer

Ring-balancer.

This loadbalancer is designed for consistent hashing approaches and to retain consistency on a maximum level while dealing with dynamic changes like adding/removing hosts/targets.

Due to its deterministic way of operating it is also capable of running identical balancers (identical consistent rings) on multiple servers/workers (though it does not implement inter-server/worker communication).

Only dns is non-deterministic as it might occur when a peer is requested, and hence should be avoided (by directly inserting ip addresses). Adding/deleting hosts, etc (as long as done in the same order) is always deterministic.

Updating the dns records is passive, meaning that when getPeer accesses a target, only then the check is done whether the record is stale, and if so it is updated. The one exception is the failed dns queries (because they have no slots assigned, and hence will never be hit by getPeer), which will be actively refreshed using a timer.

Whenever dns resolution fails for a hostname, the host will relinguish all the slots it owns, and they will be reassigned to other targets. Periodically the query for the hostname will be retried, and if it succeeds it will get slots reassigned to it.

Housekeeping; the ring-balancer does some house keeping and may insert some extra fields in dns records. Those fields will, similar to the toip function, have an __ prefix (double underscores).

Info:

  • Copyright: Mashape Inc. All rights reserved.
  • License: Apache 2.0
  • Author: Thijs Schreijer

Functions

addHost (hostname, port, weight) Adds a host to the balancer.
getPeer (hashValue, retryCount, cacheOnly) Gets the next ip address and port according to the loadbalancing scheme.
hash_md5 (str) Creates a MD5 hash value from a string.
new (opts) Creates a new balancer.
removeHost (hostname, port) Removes a host from a balancer.

Fields

hash_crc32 Creates a CRC32 hash value from a string.


Functions

addHost (hostname, port, weight)
Adds a host to the balancer. If the name resolves to multiple entries, each entry will be added, all with the same weight. So adding an A record with 2 entries, with weight 10, will insert both entries with weight 10, and increase to overall balancer weight by 20. The one exception is that if it resolves to a record with ttl=0, then it will always only insert a single (unresolved) entry. The unresolved entry will be resolved by getPeer when requested.

Resolving will be done by the dns clients resolve method. Which will dereference CNAME record if set to, but it will not dereference SRV records. An unresolved SRV target field will also be resolved by getPeer when requested.

Only the slots assigned to the newly added targets will loose their consistency, all other slots are guaranteed to remain the same.

Within a balancer the combination of hostname and port must be unique, so multiple calls with the same target will only update the weight of the existing entry.

multi-server/worker consistency; to keep multiple servers/workers consistent it is important to apply all modifications to the ring-balancer in the exact same order on each system. Also the initial order list must be the same. And; do not use names, only ip adresses, as dns resolution is non-deterministic across servers/workers.

Parameters:

  • hostname hostname to add (note: not validated, as long as it's a string it will be accepted, but remain unresolved!)
  • port (optional) the port to use (defaults to 80 if omitted)
  • weight (optional) relative weight for A/AAAA records (defaults to 10 if omitted), and will be ignored in case of an SRV record.

Returns:

    balancer object, or throw an error on bad input
getPeer (hashValue, retryCount, cacheOnly)
Gets the next ip address and port according to the loadbalancing scheme. If the dns record attached to the requested slot is expired, then it will be renewed and as a consequence the ring-balancer might be updated.

If the slot that is requested holds either an unresolved SRV entry (where the target field contains a name instead of an ip), or a record with ttl=0 then this call will perform the final query to resolve to an ip using the toip function of the dns client (this also invokes the loadbalancing as done by the toip function).

Parameters:

  • hashValue (optional) number for consistent hashing, round-robins if omitted. The hashValue must be an (evenly distributed) integer >= 0. See also hash.
  • retryCount should be 0 (or nil) on the initial try, 1 on the first retry, etc. If provided, it will be added to the hashValue to make it fall-through.
  • cacheOnly If truthy, no dns lookups will be done, only cache.

Returns:

    ip + port + hostname, or nil+error
hash_md5 (str)
Creates a MD5 hash value from a string. The string will be hashed using MD5, and then shortened to 4 bytes. The returned hash value can be used as input for the getpeer function.

Parameters:

  • str (string) value to create the hash from

Returns:

    32-bit numeric hash
new (opts)

Creates a new balancer. The balancer is based on a wheel with slots. The slots will be randomly distributed over the targets. The number of slots assigned will be relative to the weight.

A single balancer can hold multiple hosts. A host can be an ip address or a name. As such each host can have multiple targets (or actual ip+port combinations).

The options table has the following fields;

  • hosts (optional) containing hostnames, ports and weights. If omitted, ports and weights default respectively to 80 and 10. The list will be sorted before being added, so the order of entry is deterministic.
  • wheelSize (optional) for total number of slots in the balancer, if omitted the size of order is used, or 1000 if order is not provided. It is important to have enough slots to keep the ring properly randomly distributed. If there are to few slots for the number of targets then the load distribution might become to coarse. Consider the maximum number of targets expected, as new hosts can be dynamically added, and dns renewals might yield larger record sets. The wheelSize cannot be altered, only a new wheel can be created, but then all consistency would be lost. On a similar note; making it too big, will have a performance impact when the wheel is modified as too many slots will have to be moved between targets. A value of 50 to 200 slots per entry seems about right.
  • order (optional) if given, a list of random numbers, size wheelSize, used to randomize the wheel. Duplicates are not allowed in the list.
  • dns (required) a configured dns.client object for querying the dns server.
  • requery (optional) interval of requerying the dns server for previously failed queries. Defaults to 1 if omitted (in seconds)
  • ttl0 (optional) Maximum lifetime for records inserted with ttl=0, to verify the ttl is still 0. Defaults to 60 if omitted (in seconds)

Parameters:

  • opts table with options

Returns:

    new balancer object or nil+error

Usage:

    -- hosts
    local hosts = {
      "mashape.com",                                     -- name only, as string
      { name = "gelato.io" },                            -- name only, as table
      { name = "getkong.org", port = 80, weight = 25 },  -- fully specified, as table
    }
removeHost (hostname, port)
Removes a host from a balancer. All assigned slots will be redistributed to the remaining targets. Only the slots from the removed host will loose their consistency, all other slots are guaranteed to remain in place. Will not throw an error if the hostname is not in the current list.

See addHost for multi-server consistency.

Parameters:

  • hostname hostname to remove
  • port port to remove (optional, defaults to 80 if omitted)

Returns:

    balancer object, or an error on bad input

Fields

hash_crc32
Creates a CRC32 hash value from a string. The string will be hashed using CRC32. The returned hash value can be used as input for the getpeer function. This is simply a shortcut to ngx.crc32_short.
  • str (string) value to create the hash from
generated by LDoc 1.4.6 Last updated 2017-07-28 21:55:16