• Stars
    star
    5,088
  • Rank 8,175 (Top 0.2 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A high performance memory-bound Go cache

Ristretto

Go Doc ci-ristretto-tests ci-ristretto-lint Coverage Status Go Report Card

Ristretto is a fast, concurrent cache library built with a focus on performance and correctness.

The motivation to build Ristretto comes from the need for a contention-free cache in Dgraph.

Features

  • High Hit Ratios - with our unique admission/eviction policy pairing, Ristretto's performance is best in class.
    • Eviction: SampledLFU - on par with exact LRU and better performance on Search and Database traces.
    • Admission: TinyLFU - extra performance with little memory overhead (12 bits per counter).
  • Fast Throughput - we use a variety of techniques for managing contention and the result is excellent throughput.
  • Cost-Based Eviction - any large new item deemed valuable can evict multiple smaller items (cost could be anything).
  • Fully Concurrent - you can use as many goroutines as you want with little throughput degradation.
  • Metrics - optional performance metrics for throughput, hit ratios, and other stats.
  • Simple API - just figure out your ideal Config values and you're off and running.

Status

Ristretto is production-ready. See Projects using Ristretto.

Table of Contents

Usage

Example

package main

import (
	"fmt"

	"github.com/dgraph-io/ristretto"
)

func main() {
	cache, err := ristretto.NewCache(&ristretto.Config{
		NumCounters: 1e7,     // number of keys to track frequency of (10M).
		MaxCost:     1 << 30, // maximum cost of cache (1GB).
		BufferItems: 64,      // number of keys per Get buffer.
	})
	if err != nil {
		panic(err)
	}

	// set a value with a cost of 1
	cache.Set("key", "value", 1)

	// wait for value to pass through buffers
	cache.Wait()

	// get value from cache
	value, found := cache.Get("key")
	if !found {
		panic("missing value")
	}
	fmt.Println(value)

	// del value from cache
	cache.Del("key")
}

Config

The Config struct is passed to NewCache when creating Ristretto instances (see the example above).

NumCounters int64

NumCounters is the number of 4-bit access counters to keep for admission and eviction. We've seen good performance in setting this to 10x the number of items you expect to keep in the cache when full.

For example, if you expect each item to have a cost of 1 and MaxCost is 100, set NumCounters to 1,000. Or, if you use variable cost values but expect the cache to hold around 10,000 items when full, set NumCounters to 100,000. The important thing is the number of unique items in the full cache, not necessarily the MaxCost value.

MaxCost int64

MaxCost is how eviction decisions are made. For example, if MaxCost is 100 and a new item with a cost of 1 increases total cache cost to 101, 1 item will be evicted.

MaxCost can also be used to denote the max size in bytes. For example, if MaxCost is 1,000,000 (1MB) and the cache is full with 1,000 1KB items, a new item (that's accepted) would cause 5 1KB items to be evicted.

MaxCost could be anything as long as it matches how you're using the cost values when calling Set.

BufferItems int64

BufferItems is the size of the Get buffers. The best value we've found for this is 64.

If for some reason you see Get performance decreasing with lots of contention (you shouldn't), try increasing this value in increments of 64. This is a fine-tuning mechanism and you probably won't have to touch this.

Metrics bool

Metrics is true when you want real-time logging of a variety of stats. The reason this is a Config flag is because there's a 10% throughput performance overhead.

OnEvict func(hashes [2]uint64, value interface{}, cost int64)

OnEvict is called for every eviction.

KeyToHash func(key interface{}) [2]uint64

KeyToHash is the hashing algorithm used for every key. If this is nil, Ristretto has a variety of defaults depending on the underlying interface type.

Note that if you want 128bit hashes you should use the full [2]uint64, otherwise just fill the uint64 at the 0 position and it will behave like any 64bit hash.

Cost func(value interface{}) int64

Cost is an optional function you can pass to the Config in order to evaluate item cost at runtime, and only for the Set calls that aren't dropped (this is useful if calculating item cost is particularly expensive and you don't want to waste time on items that will be dropped anyways).

To signal to Ristretto that you'd like to use this Cost function:

  1. Set the Cost field to a non-nil function.
  2. When calling Set for new items or item updates, use a cost of 0.

Benchmarks

The benchmarks can be found in https://github.com/dgraph-io/benchmarks/tree/master/cachebench/ristretto.

Hit Ratios

Search

This trace is described as "disk read accesses initiated by a large commercial search engine in response to various web search requests."

Database

This trace is described as "a database server running at a commercial site running an ERP application on top of a commercial database."

Looping

This trace demonstrates a looping access pattern.

CODASYL

This trace is described as "references to a CODASYL database for a one hour period."

Throughput

All throughput benchmarks were ran on an Intel Core i7-8700K (3.7GHz) with 16gb of RAM.

Mixed

Read

Write

Projects Using Ristretto

Below is a list of known projects that use Ristretto:

  • Badger - Embeddable key-value DB in Go
  • Dgraph - Horizontally scalable and distributed GraphQL database with a graph backend
  • Vitess - Database clustering system for horizontal scaling of MySQL
  • SpiceDB - Horizontally scalable permissions database

FAQ

How are you achieving this performance? What shortcuts are you taking?

We go into detail in the Ristretto blog post, but in short: our throughput performance can be attributed to a mix of batching and eventual consistency. Our hit ratio performance is mostly due to an excellent admission policy and SampledLFU eviction policy.

As for "shortcuts," the only thing Ristretto does that could be construed as one is dropping some Set calls. That means a Set call for a new item (updates are guaranteed) isn't guaranteed to make it into the cache. The new item could be dropped at two points: when passing through the Set buffer or when passing through the admission policy. However, this doesn't affect hit ratios much at all as we expect the most popular items to be Set multiple times and eventually make it in the cache.

Is Ristretto distributed?

No, it's just like any other Go library that you can import into your project and use in a single process.

More Repositories

1

dgraph

The high-performance database for modern applications
Go
19,791
star
2

badger

Fast key-value DB in Go.
Go
12,961
star
3

dgo

Official Dgraph Go client
Go
347
star
4

dgraph-js

Official Dgraph JavaScript client
JavaScript
322
star
5

sroar

Serialized Roaring Bitmaps
Go
267
star
6

pydgraph

Official Dgraph Python client
Python
261
star
7

dgraph4j

Official Dgraph Java client
Java
157
star
8

travel

Starter Kit For Building Graph Database Go and Browser Apps Using Dgraph
Go
126
star
9

graphoverflow

Run the entire StackOverflow on Dgraph. Work in progress.
JavaScript
116
star
10

ratel

Dgraph Data Visualizer and Cluster Manager
JavaScript
114
star
11

wisemonk

Bot to move conversations from Slack to Discourse.
Go
106
star
12

benchmarks

Run benchmarks with RDF data
Go
97
star
13

badger-bench

Benchmarks of Badger
Go
92
star
14

graphql-sample-apps

This repository contains sample GraphQL applications powered by Dgraph.
JavaScript
73
star
15

dgraph-js-http

A JavaScript HTTP client for Dgraph
TypeScript
67
star
16

gru

Help identify the right minions
JavaScript
46
star
17

dgraph-lambda

TypeScript
39
star
18

tutorial

A Tour of Dgraph
HTML
38
star
19

dgraph-docs

A native GraphQL Database with a graph backend
Shell
35
star
20

charts

Helm charts for Dgraph
Shell
32
star
21

ingressutil

Utils for building an ingress controller
Go
31
star
22

flock

Twitter on Dgraph
Go
31
star
23

dgraph.net

Official Dgraph .NET Client
C#
28
star
24

dgraph-operator

Dgraph Operator creates/configures/manages Dgraph clusters atop Kubernetes
Go
23
star
25

hugo-dgraph-theme

Hugo theme used for our blog
CSS
22
star
26

typhoon-ui

🌀 typhoon-ui: Token-based React component library built using emotion.
TypeScript
14
star
27

hugo-docs

Theme for Dgraph documentation built via Hugo
HTML
13
star
28

experiments

Go
13
star
29

graphql-kanban

Project management app written with Dgraph and Apollo Client
TypeScript
13
star
30

mediawiki-dgraph-skin

Mediawiki skin used by Dgraph wiki.
CSS
13
star
31

svelte-urql-example

Svelte
12
star
32

slash-graphql-cli

Command Line Tools for Slash GraphQL
TypeScript
11
star
33

auth-webinar

Resources for Serverless Authentication + Authorization Webinar
JavaScript
9
star
34

discuss-tutorial

Discuss clone app built for a tutorial
CSS
8
star
35

tove

Crash vulnerability tests for Badger using the ALICE framework
Go
7
star
36

graphql-dgraph-web

GraphQL Web
SCSS
7
star
37

graphql-asia-workshop-2020

JavaScript
7
star
38

rails-graphoverflow

Showcase of using Dgraph in Ruby on Rails
Ruby
7
star
39

dgraph-react-todomvc

TodoMVC in React with GraphQL, Dgraph, NoSQL graph database
JavaScript
7
star
40

grpc-proxy

Go
6
star
41

webinar-1-twitter-graphql

JavaScript
5
star
42

react-slash-graphql-starter

JavaScript
4
star
43

gatsby-dgraph-graphql

A simple blog app with Gatsby and Dgraph's GraphQL API
JavaScript
4
star
44

auth0-integration

Slash GraphQL + Auth0 integration quick start
JavaScript
4
star
45

tweetsletter-workshop

JavaScript
4
star
46

dgraph-day

Learn graph database best practices from experts using Dgraph at scale in production and building the next generation of apps. Sign up for the FREE virtual event, April 15-16th.
4
star
47

hello

Dgraph's take on Go present
JavaScript
3
star
48

live-demo

JavaScript
3
star
49

dev-jokes

Slash powered DevJokes Application
JavaScript
3
star
50

Install-Dgraph

Dgraph installation scripts
Shell
2
star
51

workshop

Dgraph workshop: Build a Twitter graph with Dgraph!
2
star
52

video-tutorial-todo

JavaScript
2
star
53

vlg

Dgraph's Very Large Graph (WIP) Project
Go
2
star
54

website-old

Website code for dgraph.io
CSS
2
star
55

tudo-tutorial

Tutorial for building a GraphQL React app with Slash GraphQL
JavaScript
2
star
56

dgraph-io.github.io

Dgraph blog
HTML
2
star
57

cloud-docs

Documentation for Dgraph Cloud
Shell
1
star
58

discuss-tutorial-vue

CSS
1
star
59

developer-connect-sessions

1
star