ubgo is in early alpha: libraries and APIs may still change.

Skip to content
ubgo Alpha

cache-cluster

Peer-aware distributed cache with a consistent-hash ring and HTTP peer fill, on any cache backend.

go get github.com/ubgo/cache-cluster
Language
Go
Go version
1.24
Core deps
1 direct
Latest tag
v0.1.0
License
Apache-2.0
Go modules
1

Highlights from the README

  • One fill per hot key, cluster-wide. Ownership routing plus single-flight at the owner collapses a thundering herd into a single backend load.
  • Minimal reshuffle on membership change. Consistent hashing means adding or removing a node only moves that node’s share of keys, not the whole keyspace.
  • Bring your own storage. Any cache.Cache (in-memory, Redis, …) is the local backend; clustering is a thin layer on top.
  • No third-party dependencies. Standard library HTTP plus the ubgo/cache contract. The core and this module are dependency-free.
  • Explicit, predictable membership. Peers are configured, not gossiped — no surprise topology changes.

Code from the README

package main

import (
	"context"
	"net/http"

	clustercache "github.com/ubgo/cache-cluster"
	memcache "github.com/ubgo/cache-mem"
)

func main() {
	local := memcache.New()

	node := clustercache.New("n1", local,
		clustercache.WithPeers(map[string]string{
			"n1": "http://10.0.0.1:8080",
			"n2": "http://10.0.0.2:8080",
			"n3": "http://10.0.0.3:8080",
		}),
		clustercache.WithLoader(func(ctx context.Context, key string) ([]byte, error) {
			return db.Load(ctx, key)
		}),
	)
	defer node.Close()

	http.Handle("/_cache", node.Handler()) // peers reach each other here
	go http.ListenAndServe(":8080", nil)

	v, err := node.Get(context.Background(), "user:42") // owner-routed, filled once
	_ = v
	_ = err
}

From the cache-cluster README.