The pingora-load-balancing crate actually provides three key features related to managing upstreams:
- Load Balancing, e.g. allowing for sharing all incoming requests between multiple upstream servers
- Health Checks, e.g. ensuring all upstream servers are healthy or live, before proxying requests to them
- Service Discovery, e.g. updating the list of upstream servers over time
river will be integrating pingora-load-balancing in order to add these features. This post discusses what does and does not exist today.
Load Balancing
Load balancing functionality is largely contained within the selection module.
There are currently four supported algorthms:
- Consistent (Ketama) hashing
- FNV hashing
- Random
- Round Robin
All of these algorithms support weighting of different backends. TODO: I'm unsure how weighting will play with health checks and service discovery
It is likely we will need/want more load balancing algorithms in the future. For example, NGINX supports quite a few.
To begin with, we will want to add support for all four currently supported algorithms, selected on a per-service basis. Configuration will need to include weighting cost for statically selected server lists.
Health Checks
Health check functionality is largely contained within the health_check module.
There are currently two supported methods of health check:
- TCP Health checks, which creates a TCP (or TLS) connection in order to establish health
- HTTP Health checks, which sends an HTTP(s) connection in order to establish health
Both methods have some basic shared configuration, such as hysteresis for healthy/unhealthy determination, as well as the connection information for each peer.
Additionally, HTTP health checks have a quite a few more options, including what to request from the server, how to validate the response, and additional checks like whether a TCP/TLS connection can be re-used (this makes checking more efficient, but can mask firewall or routing issues).
We will want to support both options, some effort is expected for determining reasonable configuration APIs for the health checks.
Service Discovery
Service discovery functionality is largely contained within the discovery module.
Currently, the only provided algorithm is "Static", which uses a fixed array of backends (e.g. "no discovery").
There does exist a ServiceDiscovery trait that allows for implementing and providing service discovery functionality.
We have a couple of required service discovery abilities in river's requirements. We may want to implement DNS-SD or polling of SRV records, though that may not occur during the initial implementation.
Summary
This tracking issue will likely cover multiple PRs for implementing this functionality. We'll need to design quite a bit of configuration surface for these new features, and it will likely be a breaking change from the existing "one listener" configuration file.
We should also cross check the requirements after implementation that pingora-load-balancing has sufficient API surface to allow for the things we've mentioned, such as DNS TTL tracking to invalidate hosts.
The
pingora-load-balancingcrate actually provides three key features related to managing upstreams:riverwill be integratingpingora-load-balancingin order to add these features. This post discusses what does and does not exist today.Load Balancing
Load balancing functionality is largely contained within the
selectionmodule.There are currently four supported algorthms:
All of these algorithms support weighting of different backends. TODO: I'm unsure how weighting will play with health checks and service discovery
It is likely we will need/want more load balancing algorithms in the future. For example, NGINX supports quite a few.
To begin with, we will want to add support for all four currently supported algorithms, selected on a per-service basis. Configuration will need to include weighting cost for statically selected server lists.
Health Checks
Health check functionality is largely contained within the
health_checkmodule.There are currently two supported methods of health check:
Both methods have some basic shared configuration, such as hysteresis for healthy/unhealthy determination, as well as the connection information for each peer.
Additionally, HTTP health checks have a quite a few more options, including what to request from the server, how to validate the response, and additional checks like whether a TCP/TLS connection can be re-used (this makes checking more efficient, but can mask firewall or routing issues).
We will want to support both options, some effort is expected for determining reasonable configuration APIs for the health checks.
Service Discovery
Service discovery functionality is largely contained within the
discoverymodule.Currently, the only provided algorithm is "Static", which uses a fixed array of backends (e.g. "no discovery").
There does exist a
ServiceDiscoverytrait that allows for implementing and providing service discovery functionality.We have a couple of required service discovery abilities in
river's requirements. We may want to implement DNS-SD or polling of SRV records, though that may not occur during the initial implementation.Summary
This tracking issue will likely cover multiple PRs for implementing this functionality. We'll need to design quite a bit of configuration surface for these new features, and it will likely be a breaking change from the existing "one listener" configuration file.
We should also cross check the requirements after implementation that pingora-load-balancing has sufficient API surface to allow for the things we've mentioned, such as DNS TTL tracking to invalidate hosts.