Giter VIP home page Giter VIP logo

squeeze's Introduction

Squeeze

Dynamic congestion-based concurrency limits for controlling backpressure.

Documentation

What is this?

A Rust library to dynamically control concurrency limits. Several algorithms are included, mostly based on TCP congestion control. These detect signs of congestion or overload by observing and reacting to either latency (delay) or load-based failures (loss), respectively. Beyond the limit, additional requests to perform work can be rejected. These rejections can be detected by upstream limiters as load-based failures, acting as an effective form of backpressure.

In general, systems serving clients by doing jobs have a finite number of resources. For example, an HTTP server might have 4 CPU cores available. When these resources become heavily utilised, queues begin to form, and job latency increases. If these queues continue to grow, the system becomes effectively overloaded and unable to respond to job requests in a reasonable time.

These systems can only process so many jobs concurrently. For a purely CPU-bound job, the server above might only be able to process about 4 jobs concurrently. Reality is much more complex, however, and therefore this number is much harder to predict.

Concurrency limits can help protect a system from becoming overloaded, and these limits can be automatically set by observing and responding to the behaviour of the system.

See background for more details.

Example

use std::sync::Arc;
use squeeze::{limits::Aimd, Limiter, Outcome};

// A limiter shared between request handler invocations.
// This controls the concurrency of incoming requests.
let limiter = Arc::new(Limiter::new(
    Aimd::with_initial_limit(10)
        .with_max_limit(20)
        .decrease_factor(0.9)
        .increase_by(1),
));

// A request handler
tokio_test::block_on(async move {
    // On request start
    let token = limiter.try_acquire()
        .await
        .expect("Do some proper error handling instead of this...");

    // Do some work...

    // On request finish
    limiter.release(token, Some(Outcome::Success)).await;
});

Goals

This library aims to:

  1. Achieve optimally high throughput and low latency.
  2. Shed load and apply backpressure in response to congestion or overload.
  3. Fairly distribute available resources between independent clients with zero coordination.

Limit algorithms

The congestion-based algorithms come in several flavours:

  • Loss-based โ€“ respond to failed jobs (i.e. overload). Feedback can be implicit (e.g. a timeout) or explicit (e.g. an HTTP 429 or 503 status).
  • Delay-based โ€“ respond to increases in latency (i.e. congestion). Feedback is implicit.
Algorithm Feedback Response Fairness
AIMD Loss AIMD Fair, but can out-compete delay-based algorithms
Gradient Delay AIMD TODO: ?
Vegas Loss and delay AIAD Proportional until overload (loss)

Example topology

The example below shows two applications using limiters on the client (output) and on the server (input), using different algorithms for each.

Example topology

Caveats

TODO:

  • Loss-based algorithms require a reliable signal for load-based errors.
    • If configured to reduce concurrency for non-load-based errors, they can exacerbate availability problems when these errors occur.
  • Delay-based algorithms work more reliably with predictable latency.
    • For example, short bursts of increased latency from GC pauses could cause an outsized reduction in concurrency limits.
    • Windowing can help with this.
  • Cold-start problem: capacity limits are not known at start up.
    • There's a need to probe to discover this. Requests could be unnecessarily limited until the limit is increased to match capacity.
    • Can be mitigated with single immediate retries (from a token bucket?), which might get load balanced to a server with available capacity.

FAQ

Does this require coordination between multiple processes?

No! The congestion avoidance is based on TCP congestion control algorithms which are designed to work independently. In TCP, each transmitting socket independently detects congestion and reacts accordingly.

Installing, running and testing

TODO:

Prior art

Further reading

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

squeeze's People

Contributors

thomwright avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

conradludgate

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.