GitHub License chat GitHub Repo stars GitHub commit activity 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][].
[Dgraph]: https://github.com/hypermodeinc/dgraph
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).
excellent throughput.
(cost could be anything).
degradation.
Config values and you're off and running.Ristretto is production-ready. See Projects using Ristretto.
To start using Ristretto, install Go 1.21 or above. Ristretto needs go modules. From your project, run the following command
go get github.com/dgraph-io/ristretto/v2
This will retrieve the library.
Following these rules:
interface. This version is designed to solve compatibility problems of programs using the old version of Ristretto. If you start writing a new program, it is recommended to use this version.
package main
import (
"fmt"
"github.com/dgraph-io/ristretto/v2"
)
func main() {
cache, err := ristretto.NewCache(&ristretto.Config[string, string]{
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)
}
defer cache.Close()
// 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")
}
The benchmarks can be found in https://github.com/hypermodeinc/dgraph-benchmarks/tree/main/cachebench/ristretto.
This trace is described as "disk read accesses initiated by a large commercial search engine in response to various web search requests."
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Hit%20Ratios%20-%20Search%20(ARC-S3).svg" alt="Graph showing hit ratios comparison for search workload"> </p>
This trace is described as "a database server running at a commercial site running an ERP application on top of a commercial database."
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Hit%20Ratios%20-%20Database%20(ARC-DS1).svg" alt="Graph showing hit ratios comparison for database workload"> </p>
This trace demonstrates a looping access pattern.
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Hit%20Ratios%20-%20Glimpse%20(LIRS-GLI).svg" alt="Graph showing hit ratios comparison for looping access pattern"> </p>
This trace is described as "references to a CODASYL database for a one hour period."
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Hit%20Ratios%20-%20CODASYL%20(ARC-OLTP).svg" alt="Graph showing hit ratios comparison for CODASYL workload"> </p>
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Throughput%20-%20Mixed.svg" alt="Graph showing throughput comparison for mixed workload"> </p>
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Throughput%20-%20Read%20(Zipfian).svg" alt="Graph showing throughput comparison for read workload"> </p>
<p align="center"> <img src="https://raw.githubusercontent.com/hypermodeinc/ristretto/main/benchmarks/Throughput%20-%20Write%20(Zipfian).svg" alt="Graph showing throughput comparison for write workload"> </p>
Below is a list of known projects that use Ristretto:
database with a graph backend
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.
No, it's just like any other Go library that you can import into your project and use in a single process.