usl

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2021 License: Apache-2.0 Imports: 5 Imported by: 0

README

usl

usl is a Go modeler for Dr. Neil Gunther's Universal Scalability Law as described in Baron Schwartz's book Practical Scalability Analysis with the Universal Scalability Law.

Given a handful of measurements of any two Little's Law parameters--throughput, latency, and concurrency--the USL allows you to make predictions about any of those parameters' values given an arbitrary value for any another parameter. For example, given a set of measurements of concurrency and throughput, the USL will allow you to predict what a system's average latency will look like at a particular throughput, or how many servers you'll need to process requests and stay under your SLA's latency requirements.

The model coefficients and predictions should be within 0.001% of those listed in the book.

How to use this

As an example, consider doing load testing and capacity planning for an HTTP server. To model the behavior of the system using the USL, you must first gather a set of measurements of the system. These measurements must be of two of the three parameters of Little's Law: mean response time (in seconds), throughput (in requests per second), and concurrency (i.e. the number of concurrent clients).

Because response time tends to be a property of load (i.e. it rises as throughput or concurrency rises), the dependent variable in your tests should be mean response time. This leaves either throughput or concurrency as your independent variable, but thanks to Little's Law it doesn't matter which one you use. For the purposes of discussion, let's say you measure throughput as a function of the number of concurrent clients working at a fixed rate (e.g. you used wrk2).

After you're done load testing, you should have a set of measurements shaped like this:

concurrency throughput
1 65
18 996
36 1652
72 1853
108 1829
144 1775
216 1702

Now you can build a model and begin estimating things.

As A CLI Tool
$ go get github.com/codahale/usl/cmd/usl
$ cat measurements.csv
1,65
18,996
36,1652
72,1853
etc.
$ usl measurements.csv 10 50 100 150 200 250 300
USL parameters: σ=0.0277299, κ=0.000104343, λ=89.9878
	max throughput: 1883.76, max concurrency: 96
	contention constrained
                                                                          
        |                                                                 
 2.1 k  +                                                                 
 2.0 k  +                   ***X******@***X*********                      
 1.8 k  +              *****                        **X**********         
 1.7 k  +          X **                                                   
 1.6 k  +          **                                                     
 1.5 k  +        **                                                       
 1.3 k  +       *                                                         
 1.2 k  +      *                                                          
 1.1 k  +    X*                                                           
   975  +     *                                  .------------------.     
   853  +    *                                   |****** Predicted  |     
   731  +   *                                    |  X    Actual     |     
   609  +  *                                     |  @    Peak       |     
   487  + *                                      '------------------'     
   366  + *                                                               
   244  +*                                                                
  1122  X----+------+-----+-----+-----+------+-----+-----+-----+-----+-   
            19     38    58    77    96     115   134   154   173   192   

10.000000,714.778987
50.000000,1721.000603
100.000000,1883.278957
150.000000,1808.481681
200.000000,1686.571797
250.000000,1562.279331
300.000000,1447.463805
As A Go Library
import (
	"fmt"

	"github.com/codahale/usl"
)

func main() {
	measurements := []usl.Measurement{
		usl.ConcurrencyAndThroughput(1, 955.16),
		usl.ConcurrencyAndThroughput(2, 1878.91),
		usl.ConcurrencyAndThroughput(3, 2688.01), // etc
	}

	model := usl.Build(measurements)
	for n := 10; n < 200; n += 10 {
		fmt.Printf("At %d concurrent clients, expect %f req/sec\n",
			n, model.ThroughputAtConcurrency(float64(n)))
	}
}

Performance

Building models is pretty fast:

pkg: github.com/codahale/usl
BenchmarkBuild-8   	    2242	    500232 ns/op

Further reading

I strongly recommend Practical Scalability Analysis with the Universal Scalability Law, a free e-book by Baron Schwartz, author of High Performance MySQL and CEO of VividCortex. Trying to use this library without actually understanding the concepts behind Little's Law, Amdahl's Law, and the Universal Scalability Law will be difficult and potentially misleading.

I also wrote a blog post about my Java implementation of USL.

License

Copyright © 2021 Coda Hale

Distributed under the Apache License 2.0.

Documentation

Overview

Package usl provides functionality to build Universal Scalability Law models from sets of observed measurements.

Index

Constants

This section is empty.

Variables

View Source
var ErrInsufficientMeasurements = fmt.Errorf("usl: need at least %d measurements", minMeasurements)

ErrInsufficientMeasurements is returned when fewer than 6 measurements were provided.

Functions

This section is empty.

Types

type Measurement

type Measurement struct {
	Concurrency float64 // The average number of concurrent events.
	Throughput  float64 // The long-term average arrival rate of events, in events/sec.
	Latency     float64 // The average duration of events in seconds.
}

Measurement is a simultaneous measurement of at least two of the parameters of Little's Law: concurrency, throughput, and latency. The third parameter is inferred from the other two.

func ConcurrencyAndLatency

func ConcurrencyAndLatency(n uint64, r time.Duration) Measurement

ConcurrencyAndLatency returns a measurement of a system's latency at a given level of concurrency. The throughput of the system is derived via Little's Law.

func ConcurrencyAndThroughput

func ConcurrencyAndThroughput(n uint64, x float64) Measurement

ConcurrencyAndThroughput returns a measurement of a system's throughput at a given level of concurrency. The latency of the system is derived via Little's Law.

func ThroughputAndLatency

func ThroughputAndLatency(x float64, r time.Duration) Measurement

ThroughputAndLatency returns a measurement of a system's latency at a given level of throughput. The concurrency of the system is derived via Little's Law.

func (*Measurement) String

func (m *Measurement) String() string

type Model

type Model struct {
	Sigma  float64 // The model's coefficient of contention, σ.
	Kappa  float64 // The model's coefficient of crosstalk/coherency, κ.
	Lambda float64 // The model's coefficient of performance, λ.
}

Model is a Universal Scalability Law model.

func Build

func Build(measurements []Measurement) (m *Model, err error)

Build returns a model whose parameters are generated from the given measurements.

Finds a set of coefficients for the equation y = λx/(1+σ(x-1)+κx(x-1)) which best fit the observed values using unconstrained least-squares regression. The resulting values for λ, κ, and σ are the parameters of the returned model.

func (*Model) CoherencyConstrained

func (m *Model) CoherencyConstrained() bool

CoherencyConstrained returns true if the system is constrained by coherency costs.

func (*Model) ConcurrencyAtLatency

func (m *Model) ConcurrencyAtLatency(r float64) float64

ConcurrencyAtLatency returns the expected number of concurrent events at a particular mean latency, N(R).

See "Practical Scalability Analysis with the Universal Scalability Law, Equation 10".

func (*Model) ConcurrencyAtThroughput

func (m *Model) ConcurrencyAtThroughput(x float64) float64

ConcurrencyAtThroughput returns the expected number of concurrent events at a particular throughput, N(X).

func (*Model) ContentionConstrained

func (m *Model) ContentionConstrained() bool

ContentionConstrained returns true if the system is constrained by contention.

func (*Model) LatencyAtConcurrency

func (m *Model) LatencyAtConcurrency(n float64) float64

LatencyAtConcurrency returns the expected mean latency given a number of concurrent events, R(N).

See "Practical Scalability Analysis with the Universal Scalability Law, Equation 6".

func (*Model) LatencyAtThroughput

func (m *Model) LatencyAtThroughput(x float64) float64

LatencyAtThroughput returns the expected mean latency given a throughput, R(X).

See "Practical Scalability Analysis with the Universal Scalability Law, Equation 8".

func (*Model) Limitless

func (m *Model) Limitless() bool

Limitless returns true if the system is linearly scalable.

func (*Model) MaxConcurrency

func (m *Model) MaxConcurrency() float64

MaxConcurrency returns the maximum expected number of concurrent events the system can handle, Nmax.

See "Practical Scalability Analysis with the Universal Scalability Law, Equation 4".

func (Model) MaxThroughput

func (m Model) MaxThroughput() float64

MaxThroughput returns the maximum expected throughput the system can handle, Xmax.

func (*Model) String

func (m *Model) String() string

func (*Model) ThroughputAtConcurrency

func (m *Model) ThroughputAtConcurrency(n float64) float64

ThroughputAtConcurrency returns the expected throughput given a number of concurrent events, X(N).

See "Practical Scalability Analysis with the Universal Scalability Law, Equation 3".

func (*Model) ThroughputAtLatency

func (m *Model) ThroughputAtLatency(r float64) float64

ThroughputAtLatency returns the expected throughput given a mean latency, X(R).

See "Practical Scalability Analysis with the Universal Scalability Law, Equation 9".

Directories

Path Synopsis
cmd
usl
USL is a modeler for the Universal Scalability Law, which can be used in system testing and capacity planning.
USL is a modeler for the Universal Scalability Law, which can be used in system testing and capacity planning.
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL