(glbd and libglb: TCP proxy daemon and load balancing library in one bottle)
Copyright (C) 2007-2013 Codership Oy firstname.lastname@example.org
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See COPYING for license details.
glbd is a simple TCP connection balancer made with scalability and performance in mind. It was inspired by pen, but unlike pen its functionality is limited only to balancing generic TCP connections.
- list of backend servers is configurable in runtime.
- supports server "draining", i.e. does not allocate new connections to server, but does not kill existing ones, waiting for them to end gracefully.
- can use epoll API provided by Linux version 2.6 and higher for ultimate routing performance.
- glbd is multithreaded, so it can utilize multiple CPU cores. Also, if your OS does not support epoll API, consider using several threads even on a single core machine as it will lessen poll() overhead proportionally and can improve overall performance by a factor of 2 or more.
- optional watchdog module can monitor destinations and adjust routing table automatically.
libglb is a shared library that provides 0-effort connection balancing to
any Linux application that uses standard libc
connect() call by overloading
that function in runtime. No other program functionality is affected and no
program modification or recompilation is needed. See below for details.
GLB (both glbd and libglb) supports five balancing "policies":
a) least connected - new connection will be directed to the server with least connections (corrected for server "weight"). This policy is default.
b) round-robin - each new connection is routed to the next destination in the list in circular order.
c) single - all connections are routed to a single server with the highest weight available. All routing will stick to that server until it fails or a server with a strictly higher weight is introduced.
d) random - connections are distributed randomly between the servers.
e) source tracking - connections originating from the same address are directed to the same server. For details about this policy see below.
-T|--top option was introduced in GLB 0.9.2. It restricts all balancing
policies to a subset of destinations with top weight. E.g. if there are servers
configured with weight 1 and 2, all balancing will happen only between servers
with weight 2 as long as at least one of them is available.
MAXIMUM CONCURRENT CONNECTIONS:
Maximum connections that can be opened via glbd simultaneously depends on the system open files limit and is 493 for a standard limit of 1024. If needed glbd will attempt to increase open files limit as much as allowed by the effective user privileges. For unprivileged user it is normally 4096 which results in max 2029 connections.
On Linux open files limit may be checked with
ulimit -n and if necessary
COMMAND LINE OPTIONS:
See output of the
Runtime management can be done either through FIFO file, or network socket.
By default network socket is not opened; address and port to listen at must
be explicitly specified with
To add/modify/delete backend server (destination):
send server specification in the form
<IP address>:<port>[:weight] where
weight is an integer to the daemon. Connections are distributed proportionally
to the weight. Default weight is 1. Weight of 0 means drain the server.
Negative weight means delete the server completely (all connections to that
server are closed immediately). This works both on socket connection and on
To see the stats:
getstat command to the daemon. This works only on socket connection
since it implies response.
(here glbd is listening at 127.0.0.1:4444)
$ echo "192.168.0.1:3307:5" | nc -q 1 127.0.0.1 4444 OK $ echo "192.168.0.2:3307:5" | nc -q 1 127.0.0.1 4444 OK $ echo "getinfo" | nc -q 1 127.0.0.1 4444 Router: ---------------------------------------------------- Address : weight usage conns 192.168.0.1:3307 : 5.000 0.000 0 192.168.0.2:3307 : 5.000 0.000 0 ---------------------------------------------------- Destinations: 2, total connections: 0
usage here is some dimensionless metric of how much destination is staffed
with connections (relative to weight). Ranges from 0 (totally unused) to 1.0
(very busy). Router tries to keep
usage equal on all destinations.
All network addresses are specified in the form
Depending on the context some parts can be optional, in that case they can be
omitted. For example address to listen for client connections can be specified
HOSTNAME:PORT or just
PORT. In the latter case glbd will listen for
client connections on all interfaces. Backend servers can be specified as
HOSTNAME1,HOSTNAME2,HOSTNAME3. In that case incoming port number will be used
PORT value and 1 will be used for
GLB allows to query raw performance statistics through control socket using
getstat command. The client can use these data to obtain useful information,
e.g. average number of reads per poll() call.
$ echo "getstat" | nc -q 1 127.0.0.1 4444 in: 6930 out: 102728 recv: 109658 / 45 send: 109658 / 45 conns: 0 / 4 poll: 45 / 0 / 45 elapsed: 1.03428
Statistics line consists of fields separated by spaces for ease of parsing in scripts. A few description fields are added to assist in human reading. Value fields are all even and go as follows:
2 - number of bytes received on incoming interface (client requests)
4 - number of bytes sent from incoming interface (server responses)
6 - number of bytes passed through
8 - number of
10 - number of bytes passed through
send() call (should be equal to p.6)
12 - number of
14 - number of created connections
16 - number of concurrent connections
18 - number of read-ready file descriptors returned by
20 - number of write-ready file descriptors returned by
22 - number of times
24 - time elapsed since last statistics report (seconds)
All values except for 16 and 24 are totals accumulated since the last report. In order to obtain some variable rate it must be divided by the elapsed time. On 32-bit architectures the values are stored in 4-byte integers and can overflow after enough time elapsed, so the first statistics report in the series may need to be discarded.
SOURCE TRACKING CAPABILITY:
GLB features simple source tracking capability where connections originating from one address can be routed to the same destination, chosen randomly among available destinations according to their weights. One limitation of such scheme is that when the destination list changes, destination choice for new connections changes as well while established connections naturally stay unchanged. Also when a destination is marked unavailable, all connections that would be routed to it will fail over to another, randomly chosen destination. When the original target becomes available, all new connections will be routed back to it.
In other words source tracking should be considered a best effort feature and will work best for short-lived connections.
(NOTE: this is a work in progress and neither functionality nor terminology is final.)
Without the watchdog GLB can check destination availability only via the ability to establish TCP connection to destination. For most use cases TCP connectivity is an insufficient check. E.g. for HTTP server it is important to be able to serve web pages and for DBMS server - to be able to execute queries. Watchdog module implements asynchronous monitoring of destinations via backends made to check particular service availability.
Watchdog is enabled with a
-w|--watchdog option. Its parameter is a string
containing the backend ID string, optionally followed by a colon and backend
configuration options. For example:
$ glbd -w exec:"mysql.sh -utest -ptestpass" -t 2 3306 192.168.0.1 192.168.0.2
exec backend that executes external programs. In this case
it will execute
mysql.sh script (can be found in the
must be placed in
PATH) with provided parameters to check MySQL servers
at 192.168.0.1 and 192.168.0.2 (in parallel threads). To pass server
address to a script,
exec backend will insert
host:port string as the first
argument after a script/command name, so the actual command that would be
executed in this case looks like:
"mysql.sh 192.168.0.1:3306 -utest -ptestpass"
Check interval is set with
-i|--interval parameter (fractional seconds, default 1.0).
If destinations can supply information about other members of the cluster
it can be used to automatically populate watchdog destination list if
-D|--discover option is supplied. Currently only MySQL/Galera nodes are known
to do this, so it is a Galera-only option.
RUNNING GLBD AS A "SERVICE":
README in the
Using libglb requires 2 environment variables to be set:
- allows to specify GLB options to libglb the same way as command line
parameters for glbd. It is limited however in that options and their values
cannot contain whitespaces and commas and short options cannot be
-qri10should go as
-q -r -i 10). Parsing errors and options unsupported by libglb (like
-d) will be silently ignored. In particular, watchdog option cannot be specified this way. (See
GLB_WATCHDOGenvironment variable below)
$ LD_PRELOAD=src/.libs/libglb.so \ GLB_OPTIONS="--random 3306 192.168.0.1 192.168.0.2 192.168.0.3" \ mysql -uroot -prootpass -h127.0.0.1 -P3306 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 76 Server version: 5.5.28 Source distribution, wsrep_24dev.7.r3830 ...
Additional libglb parameters:
GLB_OPTIONS is not sufficient (e.g. watchdog option needs to be
specified) below there is a list of additional environment variables (which
take precedence over
GLB_OPTIONS). Note however, that all these options except
GLB_WATCHDOG are considered deprecated at the moment.
Interpreted the same way as
Is a comma-separated list of target servers among which the client connections must be distributed.
<addr> is interpreted the same way as
LISTEN_ADDR parameter for glbd.
Whenever application attempts to initiate connection to this address, the
request will be intercepted and connection established to one of the
GLB_TARGETS list according to balancing rules.
Default libglb balancing policy is "round-robin", "single", "random" and
"source tracking" policies can be specified with
(The meaning of
GLB_POLICY=source in this case is that all connections from
this client will be routed to the same random destination, and fail over to
another if the primary destination fails. Thus client-server affinity is
achieved, however load from many clients will be spread over all available
Interpreted the same way as
--control parameter of glbd. Application will
open a socket at a specified address to listen to control commands. Due
to library functionality limited only to
connect() call, no traffic
statistics or connection count is maintained, so
"getstat" command is a
"getinfo" only prints out a routing table.