cluster

package
v0.40.1 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package cluster implements the L0 distribution layer (DESIGN.md §3, §11, §14 M6–M7): rendezvous (HRW) hashing with spread-minimizing tokens, etcd-backed ring state and leases, RF=3 quorum replication, and rebalancing.

This is a scaffold stub: the ring, etcd integration, replication, and rebalancing are filled in at M6. Single-node users skip this package entirely ([Options.Cluster] == nil ⇒ no cluster layer).

Index

Constants

View Source
const (
	SeriesPath = "/internal/series"
	SidePath   = "/internal/side"
	KeysPath   = "/internal/keys"
)

SeriesPath, SidePath, and KeysPath are the HTTP paths of the series-listing, side-store, and attribute-key enumeration servers.

View Source
const AggregatePath = "/internal/aggregate"

AggregatePath is the HTTP path the cluster aggregate-pushdown server serves. A peer runs the step-bucketed aggregate over its local shard (using its stats sidecar where it applies) and returns one compact engine.NamedAgg per series — identity + buckets — instead of every sample, so a coordinator gathers and unions across shards without shipping raw points.

View Source
const AggregateWindowPath = "/internal/aggregate/window"

AggregateWindowPath is the HTTP path the overlapping-window aggregate server serves. It is a separate endpoint from AggregatePath rather than a widened request on it: the two carry different results (windows keyed by their evaluation timestamp, buckets by their start), and a peer too old to know about windows answers 404 — an error the coordinator fails over on — instead of silently returning disjoint buckets for an overlapping question.

View Source
const DefaultRF = 3

DefaultRF is the replication factor used when Config.RF is unset.

View Source
const DefaultRoot = "/oteldb"

DefaultRoot is the etcd key prefix used when Config.Root is empty.

View Source
const DefaultTenant signal.TenantID = "default"

DefaultTenant is the tenant id a record routes to when no routing callback is configured, or when one returns the empty id.

View Source
const PrimaryWritePath = "/internal/primary-write"

PrimaryWritePath is the endpoint a shard's ring primary serves: the single authority for the shard, so every write for it lands here and the admission decision is made once.

View Source
const (
	ReadPath = "/internal/fetch"
)

ReadPath is the HTTP path the cluster read (fetch fan-out) server serves.

View Source
const ShardSep = "/_s"

ShardSep separates a tenant from its shard index in a shard key. It is chosen so a shard key is a valid backend path segment and never collides with a real tenant id (which the embedder keeps free of this marker).

Variables

View Source
var ErrNotPrimary = errors.New("cluster: shard no longer held by this node")

ErrNotPrimary is a node's refusal to apply a write as a shard's primary: it can no longer prove it holds the shard, so another node may already own it and anything applied here would be acknowledged and then withheld. It is the write side of ErrShardAbsent — a routing answer, not a server fault — so the origin should re-resolve the shard's primary rather than retry here.

View Source
var ErrShardAbsent = errors.New("cluster: shard not held by peer")

ErrShardAbsent is a peer's answer that it does not hold the requested shard at all: it has no engine for the shard, whatever the ring says (a fresh owner after a rebalance, a node whose membership view lags the writer's, a spare that has not backfilled yet).

It is deliberately not an empty result. An empty success is indistinguishable from "this shard really has no data", so a caller that accepts it silently drops every row the shard holds elsewhere; the caller must instead fail over to another owner, and report empty only when every owner disclaims the shard.

Functions

func AggregateHandler added in v0.8.0

func AggregateHandler(fn AggregateFunc) http.Handler

AggregateHandler returns the HTTP handler that serves an aggregate from the local store. Mount it at AggregatePath. the shared halves (body read, matcher rebuild) are already factored out.

func AggregateWindowHandler added in v0.36.0

func AggregateWindowHandler(fn AggregateWindowFunc) http.Handler

AggregateWindowHandler returns the HTTP handler that serves an overlapping-window aggregate from the local store. Mount it at AggregateWindowPath. the shared halves (body read, matcher rebuild) are already factored out.

func DecodeAggregateRequest added in v0.8.0

func DecodeAggregateRequest(data []byte) (tenant string, start, end, step int64, eq []fetch.EqualMatcher, err error)

DecodeAggregateRequest parses a request made by EncodeAggregateRequest.

func DecodeAggregateWindowRequest added in v0.36.0

func DecodeAggregateWindowRequest(data []byte) (
	tenant string, start, end int64, spec engine.WindowSpec, eq []fetch.EqualMatcher, err error,
)

DecodeAggregateWindowRequest parses a request made by EncodeAggregateWindowRequest.

func DecodeAggregates added in v0.8.0

func DecodeAggregates(data []byte) ([]engine.NamedAgg, error)

DecodeAggregates parses an EncodeAggregates payload. It bounds-checks every length before slicing, so it never panics on a malformed or truncated response.

func DecodeBatches

func DecodeBatches(data []byte) ([]*fetch.Batch, error)

DecodeBatches parses EncodeBatches output, recomputing each batch's id from its identity.

func DecodeFetchRequest

func DecodeFetchRequest(data []byte) (sig signal.Signal, tenant string, start, end int64, eq []fetch.EqualMatcher, err error)

DecodeFetchRequest parses a request made by EncodeFetchRequest.

func DecodeLogBatches added in v0.2.0

func DecodeLogBatches(data []byte) ([]*fetch.Batch, error)

DecodeLogBatches parses EncodeLogBatches output, recomputing each batch's id from its identity.

func DecodeSeriesList added in v0.2.0

func DecodeSeriesList(data []byte) ([]signal.Series, error)

DecodeSeriesList parses EncodeSeriesList output.

func DecodeSideTables added in v0.2.0

func DecodeSideTables(data []byte) (map[string][]byte, error)

DecodeSideTables parses EncodeSideTables output.

func DecodeWindowAggregates added in v0.36.0

func DecodeWindowAggregates(data []byte) ([]engine.NamedWindowAgg, error)

DecodeWindowAggregates parses an EncodeWindowAggregates payload. It bounds-checks every length before slicing, so it never panics on a malformed or truncated response.

func DecodeWrite

func DecodeWrite(data []byte) (sig signal.Signal, tenant string, walBytes []byte, err error)

DecodeWrite splits a payload made by EncodeWrite into the signal, tenant id, and WAL bytes.

func EncodeAggregateRequest added in v0.8.0

func EncodeAggregateRequest(tenant string, start, end, step int64, eq []fetch.EqualMatcher) []byte

EncodeAggregateRequest frames an aggregate request: tenant, window, step, and the serializable equality matchers to push to the peer (the coordinator re-checks the full set on the response).

func EncodeAggregateWindowRequest added in v0.36.0

func EncodeAggregateWindowRequest(tenant string, start, end int64, spec engine.WindowSpec, eq []fetch.EqualMatcher) []byte

EncodeAggregateWindowRequest frames a window-aggregate request: tenant, range, the evaluation grid (step, window width, anchor), and the serializable equality matchers to push to the peer (the coordinator re-checks the full set on the response).

func EncodeAggregates added in v0.8.0

func EncodeAggregates(aggs []engine.NamedAgg) []byte

EncodeAggregates serializes per-series aggregates: a count, then per series the identity (the reversible hash pre-image) and its step buckets.

func EncodeBatches

func EncodeBatches(batches []*fetch.Batch) []byte

EncodeBatches serializes fetch batches: each series' identity (reversible hash pre-image) followed by its (timestamp, value) samples. The id is recomputed from the identity on decode, so it is not sent.

func EncodeFetchRequest

func EncodeFetchRequest(sig signal.Signal, tenant string, start, end int64, eq []fetch.EqualMatcher) []byte

EncodeFetchRequest frames a fetch request: the signal, tenant, window, and any serializable equality matchers to push down to the peer (other predicates are re-checked by the requester).

func EncodeKeyList added in v0.10.0

func EncodeKeyList(keys []KeyInfo) []byte

EncodeKeyList serializes a list of distinct attribute keys: a uvarint count, then per key a uvarint length, the key bytes, and a single scope byte.

func EncodeLogBatches added in v0.2.0

func EncodeLogBatches(batches []*fetch.Batch) []byte

EncodeLogBatches serializes log fetch batches: each stream's identity, its record timestamps, and its named per-record columns (each tagged by physical kind). The id is recomputed from the identity on decode, so it is not sent.

func EncodeSeriesList added in v0.2.0

func EncodeSeriesList(series []signal.Series) []byte

EncodeSeriesList serializes stream identities as length-prefixed reversible hash pre-images.

func EncodeSideTables added in v0.2.0

func EncodeSideTables(tables map[string][]byte) []byte

EncodeSideTables serializes a side-store table set (sorted by name for determinism).

func EncodeWindowAggregates added in v0.36.0

func EncodeWindowAggregates(aggs []engine.NamedWindowAgg) []byte

EncodeWindowAggregates serializes per-series window aggregates: a count, then per series the identity (the reversible hash pre-image) and its windows, each keyed by its evaluation timestamp.

func EncodeWrite

func EncodeWrite(sig signal.Signal, tenant string, walBytes []byte) []byte

EncodeWrite frames signal ‖ tenant ‖ walBytes into a replication payload.

func FetchSeries added in v0.2.0

func FetchSeries(
	ctx context.Context, client *http.Client, addr string, sig signal.Signal,
	tenant string, start, end int64, eq []fetch.EqualMatcher,
) ([]signal.Series, error)

FetchSeries lists a peer's stream identities for the signal+tenant+window, pushing down the serializable (equality) matchers; the caller re-applies any non-equality matchers.

func FetchSide added in v0.2.0

func FetchSide(ctx context.Context, client *http.Client, addr string, sig signal.Signal, tenant string) (map[string][]byte, error)

FetchSide returns a peer's side-store tables for the signal+tenant.

func KeysHandler added in v0.10.0

func KeysHandler(fn KeysFunc) http.Handler

KeysHandler serves KeysPath: it enumerates the distinct record-attribute keys for the request's signal+tenant+window via fn (matchers are not used — keys are window-scoped, not matcher-scoped).

func PrimaryWriteHandler added in v0.38.0

func PrimaryWriteHandler(fn PrimaryWriteFunc) http.Handler

PrimaryWriteHandler returns the HTTP handler serving writes routed to this node as a shard's primary. Mount it at PrimaryWritePath.

func ReadHandler

func ReadHandler(metricFn, logFn, traceFn, profileFn FetchFunc) http.Handler

ReadHandler returns the HTTP handler that serves fetches from the local store, reconstructing the pushed-down equality matchers and dispatching to the metric, log, trace, or profile fetch by the request's signal (encoding the result with the matching batch codec — samples for metrics, columns for the record signals). Mount it at ReadPath.

func SeriesHandler added in v0.2.0

func SeriesHandler(fn SeriesFunc) http.Handler

SeriesHandler serves SeriesPath: it reconstructs the pushed-down equality matchers and lists the matching stream identities via fn, dispatched to the right engine by the request's signal.

func ShardCount added in v0.38.0

func ShardCount(shardsPerTenant int) int

ShardCount clamps a configured Config.ShardsPerTenant to the usable range: anything below one means a single shard.

func ShardKeyOf added in v0.38.0

func ShardKeyOf(tenant signal.TenantID, idx, n int) signal.TenantID

ShardKeyOf returns the routing/storage key for tenant's shard idx. With a single shard it is the bare (already-normalized) tenant, so ring placement and on-disk prefixes are byte-identical to the unsharded path; with n > 1 it suffixes the shard index.

func ShardKeys added in v0.38.0

func ShardKeys(tenant signal.TenantID, n int) []signal.TenantID

ShardKeys returns every shard key of a tenant, in index order. A read cannot know which shard holds a series before it matches one, so it fans out across all of them.

func ShardOf added in v0.38.0

func ShardOf(id signal.SeriesID, n int) int

ShardOf maps a series id to a shard index in [0, n). The series id is already a uniform content hash, so the low word modulo n distributes evenly.

func SideHandler added in v0.2.0

func SideHandler(fn SideFunc) http.Handler

SideHandler serves SidePath: it returns the tenant's side-store tables via fn.

func TenantOfShard added in v0.38.0

func TenantOfShard(shardKey signal.TenantID) signal.TenantID

TenantOfShard recovers the tenant id from a shard key (the inverse of ShardKeyOf), for policy resolution. A key without the shard marker (the single-shard case) is returned unchanged.

Types

type AdmitFunc added in v0.38.0

type AdmitFunc func(tenant signal.TenantID, b *metric.Batch) bool

AdmitFunc is the origin-side ingest valve: it reports whether a projected batch is admitted, and a false sheds the whole batch before it is framed. Nil admits everything.

It is called once per projected batch in projection order, so an implementation may cache the state it resolves per tenant across a tenant-contiguous run.

type AggregateFunc added in v0.8.0

type AggregateFunc func(ctx context.Context, tenant string, start, end, step int64, matchers []fetch.Matcher) ([]engine.NamedAgg, error)

AggregateFunc computes a node-local step-bucketed aggregate of a tenant's metric series matching the (pushed-down equality) matchers, returning each series' identity so a coordinator can re-check the full matcher set and union across shards. It is what AggregateHandler serves.

type AggregateWindowFunc added in v0.36.0

type AggregateWindowFunc func(
	ctx context.Context, tenant string, start, end int64, spec engine.WindowSpec, matchers []fetch.Matcher,
) ([]engine.NamedWindowAgg, error)

AggregateWindowFunc computes a node-local overlapping-window aggregate of a tenant's metric series matching the (pushed-down equality) matchers: one aggregate per step-aligned evaluation timestamp over the half-open window (t-window, t]. It is what AggregateWindowHandler serves.

type Config

type Config struct {
	// Etcd is the etcd endpoint list for membership coordination.
	Etcd []string
	// Self is this node's identity: ID (ring identity), Zone (failure domain), and Addr
	// (host:port the node listens on for replication and reaches peers at).
	Self etcd.Member
	// RF is the replication factor (replicas per write). Zero ⇒ 3.
	RF int
	// ShardsPerTenant splits each tenant's metric series into this many independently-placed
	// shards (series → shard = hash(seriesID) % N), so a single large tenant spreads its ingest,
	// storage, and compaction across up to N nodes instead of being pinned to one owner set. Zero
	// or one ⇒ a single shard (the tenant is the shard; on-disk layout and placement are identical
	// to the unsharded path). Applies to metrics only; the record signals are a single shard.
	ShardsPerTenant int
	// Root is the etcd key prefix for this cluster's state. Empty ⇒ "/oteldb".
	Root string
	// MemberTTL is the TTL of the etcd lease this node's membership registration hangs off:
	// how long the node may be unable to reach etcd before its peers evict it from the ring.
	// Lowering it detects a dead node sooner at the cost of evicting a live but stalled one
	// (a GC pause, a starved CPU, an etcd blip). An evicted node re-registers on its own, so
	// this sets how often that happens, not whether the cluster recovers. Zero ⇒
	// [etcd.DefaultTTL].
	MemberTTL time.Duration
	// PrivateBackend declares that this node's backend is private to it (a local disk, not a
	// shared object store): peers cannot read the parts this node flushes. The cluster then
	// replicates flushed parts node-to-node — replicas mirror their owner's backend objects
	// over the parts endpoints (cluster/partsync) instead of loading them from a shared store,
	// and an owner backfills from its peers before compacting. False (the default) keeps the
	// shared-store model: flushed parts are exchanged through the backend, never over the
	// cluster transport.
	PrivateBackend bool
}

Config is the cluster configuration. It is optional: a nil [storage.Options].Cluster means single-node mode (the cluster layer is absent). When set, the storage facade joins the etcd-coordinated cluster, runs the replica server on Config.Self.Addr, and routes writes to their ring-owners at replication factor Config.RF.

type FetchFunc

type FetchFunc func(ctx context.Context, tenant string, start, end int64, matchers []fetch.Matcher) ([]*fetch.Batch, error)

FetchFunc fetches a tenant's series within [start, end] from the local store, applying the pushed-down matchers. It is what ReadHandler serves.

type KeyInfo added in v0.10.0

type KeyInfo struct {
	Key   []byte
	Scope uint8
}

KeyInfo is one distinct attribute key and the scope(s) it was observed in, as carried over the keys-enumeration RPC. Scope mirrors the record engine's KeyScope bitset (resource/scope/record).

func DecodeKeyList added in v0.10.0

func DecodeKeyList(data []byte) ([]KeyInfo, error)

DecodeKeyList parses EncodeKeyList output, bounds-checking every length so a malformed or truncated peer response is rejected rather than panicking.

func FetchKeys added in v0.10.0

func FetchKeys(
	ctx context.Context, client *http.Client, addr string, sig signal.Signal, tenant string, start, end int64,
) ([]KeyInfo, error)

FetchKeys returns a peer's distinct record-attribute keys for the signal+tenant+window.

type KeysFunc added in v0.10.0

type KeysFunc func(ctx context.Context, sig signal.Signal, tenant string, start, end int64) ([]KeyInfo, error)

KeysFunc returns the distinct record-attribute keys (with their scope bitset) present in a signal+tenant's records within the window.

type MetricFrames added in v0.38.0

type MetricFrames struct {
	// Shards maps a shard key to its WAL-encoded run of records.
	Shards map[signal.TenantID][]byte
	// Emitted is how many points projection produced, admitted or not.
	Emitted int
	// Shed is how many points the admit valve dropped before framing.
	Shed int
}

MetricFrames is what FrameMetrics produced: one WAL-encoded payload per shard key, ready to be routed to that shard's primary, plus what projection saw.

func FrameMetrics added in v0.38.0

func FrameMetrics(md metric.Metrics, shards int, tenantOf TenantFunc, admit AdmitFunc) MetricFrames

FrameMetrics projects md and groups every point by the shard key it routes to, framing each shard's records as a WAL payload.

Grouping by shard rather than by tenant is what spreads one large tenant's ingest across the ring: each shard routes to its own primary independently. With a single shard the key is the tenant, identical to the unsharded path.

Both the node and a standalone ingester frame writes through here, so the two cannot disagree about which shard a series belongs to — a divergence that would otherwise be silent, writing to a shard nobody reads.

type PrimaryWriteFunc added in v0.38.0

type PrimaryWriteFunc func(ctx context.Context, sig signal.Signal, shardKey string, walBytes []byte) (Reject, error)

PrimaryWriteFunc applies a write as the addressed shard's primary and returns what it rejected. walBytes is the WAL-encoded run of records for the shard, framed by EncodeWrite.

type RecordAdmitFunc added in v0.38.0

type RecordAdmitFunc func(tenant signal.TenantID, b *recordengine.Batch) bool

RecordAdmitFunc is the origin-side ingest valve for records: false sheds the whole stream batch before it is framed. Nil admits everything. Batches arrive in projection order, so an implementation may cache per-tenant state across a contiguous run.

type RecordFrames added in v0.38.0

type RecordFrames struct {
	// Shards maps a shard key to its WAL-encoded run of records.
	Shards map[signal.TenantID][]byte
	// Emitted is how many records projection produced, admitted or not.
	Emitted int
	// Shed is how many records the admit valve dropped before framing.
	Shed int
}

RecordFrames is what FrameRecords produced: one WAL-encoded payload per shard key.

func FrameRecords added in v0.38.0

func FrameRecords(project RecordProjector, shards int, tenantOf TenantFunc, admit RecordAdmitFunc) RecordFrames

FrameRecords groups a record signal's streams by shard key and frames each shard's records as a WAL payload — the record-signal twin of FrameMetrics.

A stream is the unit here, not a record: a stream's identity is registered once and its records follow, so the whole stream routes to one shard. That is what keeps a log stream's records together on one primary rather than scattered across the ring.

type RecordProjector added in v0.38.0

type RecordProjector func(emit func(*recordengine.Batch)) int

RecordProjector projects a record signal's ingest batch, calling emit once per stream and returning the total record count. It is what log.Project, trace.Project and profile.Project present, so the three signals share one framing path.

type Reject added in v0.38.0

type Reject struct {
	OOO         int
	Cardinality int
	InFlight    int
}

Reject is the per-reason rejection breakdown a primary reports back to the write's origin, so ingest can attribute OTLP partial-success exactly like the single-node path. The rate valve is applied at the origin, so it is not carried here.

func SendPrimaryWrite added in v0.38.0

func SendPrimaryWrite(ctx context.Context, client *http.Client, addr string, payload []byte) (Reject, error)

SendPrimaryWrite posts one already-framed write (EncodeWrite) to the primary at addr and returns the breakdown it reports. A nil client uses http.DefaultClient.

It makes exactly one attempt and never retries: a write is not idempotent, so re-sending one the primary may have applied is the caller's decision, not this function's. Callers that can prove the request never reached the server (a connection failure) may retry it themselves.

func (Reject) Total added in v0.38.0

func (r Reject) Total() int

Total is how many records the primary rejected, for all reasons it reports.

type RemoteAggregator added in v0.8.0

type RemoteAggregator struct {
	// contains filtered or unexported fields
}

RemoteAggregator runs an aggregate over a peer node's AggregateHandler.

func NewRemoteAggregator added in v0.8.0

func NewRemoteAggregator(addr string, client *http.Client) *RemoteAggregator

NewRemoteAggregator returns an aggregator over the peer at addr. A nil client uses http.DefaultClient.

func (*RemoteAggregator) Aggregate added in v0.8.0

func (a *RemoteAggregator) Aggregate(
	ctx context.Context, tenant string, start, end, step int64, eq []fetch.EqualMatcher,
) ([]engine.NamedAgg, error)

Aggregate pushes the tenant, window, step, and equality matchers to the peer and returns its per-series aggregates.

func (*RemoteAggregator) AggregateWindow added in v0.36.0

func (a *RemoteAggregator) AggregateWindow(
	ctx context.Context, tenant string, start, end int64, spec engine.WindowSpec, eq []fetch.EqualMatcher,
) ([]engine.NamedWindowAgg, error)

AggregateWindow pushes the tenant, range, evaluation grid and equality matchers to the peer and returns its per-series evaluation windows.

type RemoteFetcher

type RemoteFetcher struct {
	// contains filtered or unexported fields
}

RemoteFetcher is a fetch.Fetcher over a peer node's ReadHandler. It forwards only the request's tenant and window (matchers are re-applied by the caller), so it returns the peer's full window — a superset the fetch contract permits.

func NewRemoteFetcher

func NewRemoteFetcher(sig signal.Signal, addr string, client *http.Client) *RemoteFetcher

NewRemoteFetcher returns a fetcher that reads the given signal from the peer at addr. A nil client uses http.DefaultClient. The zero signal value reads metrics.

func (*RemoteFetcher) Fetch

Fetch forwards r's tenant, window, and serializable (equality) matchers to the peer and returns the decoded batches. Non-equality matchers (and columnar conditions) are not forwarded — the requester re-applies them to the (possibly superset) result.

type SeriesFunc added in v0.2.0

type SeriesFunc func(
	ctx context.Context, sig signal.Signal, tenant string, start, end int64, matchers []fetch.Matcher,
) ([]signal.Series, error)

SeriesFunc lists the local store's stream identities for a signal+tenant matching matchers within the window (a zero window disables the time filter). The signal selects the engine (logs / traces / profiles share one enumeration RPC, dispatched by the request's signal byte).

type SideFunc added in v0.2.0

type SideFunc func(ctx context.Context, tenant string) (map[string][]byte, error)

SideFunc returns the local store's side-store tables (name → encoded payload) for a tenant.

type TenantFunc added in v0.38.0

type TenantFunc func(signal.Resource, signal.Scope) signal.TenantID

TenantFunc derives a batch's tenant from its resource and scope, so one OTLP batch may fan out to many tenants. A nil func, or one returning "", routes everything to DefaultTenant.

Directories

Path Synopsis
Package ec erasure-codes flushed-part backend objects for shared-nothing durability at sub-replica storage cost: an object split into Data shards plus Parity parity shards (systematic Reed-Solomon) survives the loss of any Parity shards while storing only (Data+Parity)/Data of the logical bytes — e.g.
Package ec erasure-codes flushed-part backend objects for shared-nothing durability at sub-replica storage cost: an object split into Data shards plus Parity parity shards (systematic Reed-Solomon) survives the loss of any Parity shards while storing only (Data+Parity)/Data of the logical bytes — e.g.
Package etcd backs the L0 cluster ring with etcd: a node registers itself under a lease and watches the member set, so membership is live and self-healing — a crashed node's lease expires and it drops out of every other node's ring within the TTL, with no manual deregistration.
Package etcd backs the L0 cluster ring with etcd: a node registers itself under a lease and watches the member set, so membership is live and self-healing — a crashed node's lease expires and it drops out of every other node's ring within the TTL, with no manual deregistration.
Package partsync replicates flushed, immutable parts between nodes whose backends are per-node private (shared-nothing cluster mode).
Package partsync replicates flushed, immutable parts between nodes whose backends are per-node private (shared-nothing cluster mode).
Package rebalance computes the minimal ownership changes to apply a cluster membership change (DESIGN.md §11).
Package rebalance computes the minimal ownership changes to apply a cluster membership change (DESIGN.md §11).
Package replica is the L0 write-replication layer: it fans an opaque write payload out to the ring-owners of a key and returns once a write **quorum** has durably applied it, so the unflushed head survives the loss of a minority of replicas (DESIGN.md §11; RF=3, quorum (RF/2)+1=2).
Package replica is the L0 write-replication layer: it fans an opaque write payload out to the ring-owners of a key and returns once a write **quorum** has durably applied it, so the unflushed head survives the loss of a minority of replicas (DESIGN.md §11; RF=3, quorum (RF/2)+1=2).
Package ring implements rendezvous (highest-random-weight, HRW) hashing — the L0 sharding primitive (DESIGN.md §11).
Package ring implements rendezvous (highest-random-weight, HRW) hashing — the L0 sharding primitive (DESIGN.md §11).
Package router routes reads and writes by the cluster ring without joining it.
Package router routes reads and writes by the cluster ring without joining it.

Jump to

Keyboard shortcuts

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