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
- Variables
- func AggregateHandler(fn AggregateFunc) http.Handler
- func AggregateWindowHandler(fn AggregateWindowFunc) http.Handler
- func DecodeAggregateRequest(data []byte) (tenant string, start, end, step int64, eq []fetch.EqualMatcher, err error)
- func DecodeAggregateWindowRequest(data []byte) (tenant string, start, end int64, spec engine.WindowSpec, ...)
- func DecodeAggregates(data []byte) ([]engine.NamedAgg, error)
- func DecodeBatches(data []byte) ([]*fetch.Batch, error)
- func DecodeFetchRequest(data []byte) (sig signal.Signal, tenant string, start, end int64, eq []fetch.EqualMatcher, ...)
- func DecodeLogBatches(data []byte) ([]*fetch.Batch, error)
- func DecodeSeriesList(data []byte) ([]signal.Series, error)
- func DecodeSideTables(data []byte) (map[string][]byte, error)
- func DecodeWindowAggregates(data []byte) ([]engine.NamedWindowAgg, error)
- func DecodeWrite(data []byte) (sig signal.Signal, tenant string, walBytes []byte, err error)
- func EncodeAggregateRequest(tenant string, start, end, step int64, eq []fetch.EqualMatcher) []byte
- func EncodeAggregateWindowRequest(tenant string, start, end int64, spec engine.WindowSpec, ...) []byte
- func EncodeAggregates(aggs []engine.NamedAgg) []byte
- func EncodeBatches(batches []*fetch.Batch) []byte
- func EncodeFetchRequest(sig signal.Signal, tenant string, start, end int64, eq []fetch.EqualMatcher) []byte
- func EncodeKeyList(keys []KeyInfo) []byte
- func EncodeLogBatches(batches []*fetch.Batch) []byte
- func EncodeSeriesList(series []signal.Series) []byte
- func EncodeSideTables(tables map[string][]byte) []byte
- func EncodeWindowAggregates(aggs []engine.NamedWindowAgg) []byte
- func EncodeWrite(sig signal.Signal, tenant string, walBytes []byte) []byte
- func FetchSeries(ctx context.Context, client *http.Client, addr string, sig signal.Signal, ...) ([]signal.Series, error)
- func FetchSide(ctx context.Context, client *http.Client, addr string, sig signal.Signal, ...) (map[string][]byte, error)
- func KeysHandler(fn KeysFunc) http.Handler
- func PrimaryWriteHandler(fn PrimaryWriteFunc) http.Handler
- func ReadHandler(metricFn, logFn, traceFn, profileFn FetchFunc) http.Handler
- func SeriesHandler(fn SeriesFunc) http.Handler
- func ShardCount(shardsPerTenant int) int
- func ShardKeyOf(tenant signal.TenantID, idx, n int) signal.TenantID
- func ShardKeys(tenant signal.TenantID, n int) []signal.TenantID
- func ShardOf(id signal.SeriesID, n int) int
- func SideHandler(fn SideFunc) http.Handler
- func TenantOfShard(shardKey signal.TenantID) signal.TenantID
- type AdmitFunc
- type AggregateFunc
- type AggregateWindowFunc
- type Config
- type FetchFunc
- type KeyInfo
- type KeysFunc
- type MetricFrames
- type PrimaryWriteFunc
- type RecordAdmitFunc
- type RecordFrames
- type RecordProjector
- type Reject
- type RemoteAggregator
- type RemoteFetcher
- type SeriesFunc
- type SideFunc
- type TenantFunc
Constants ¶
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.
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.
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.
const DefaultRF = 3
DefaultRF is the replication factor used when Config.RF is unset.
const DefaultRoot = "/oteldb"
DefaultRoot is the etcd key prefix used when Config.Root is empty.
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.
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.
const (
ReadPath = "/internal/fetch"
)
ReadPath is the HTTP path the cluster read (fetch fan-out) server serves.
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 ¶
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.
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
DecodeAggregates parses an EncodeAggregates payload. It bounds-checks every length before slicing, so it never panics on a malformed or truncated response.
func DecodeBatches ¶
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
DecodeLogBatches parses EncodeLogBatches output, recomputing each batch's id from its identity.
func DecodeSeriesList ¶ added in v0.2.0
DecodeSeriesList parses EncodeSeriesList output.
func DecodeSideTables ¶ added in v0.2.0
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 ¶
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
EncodeAggregates serializes per-series aggregates: a count, then per series the identity (the reversible hash pre-image) and its step buckets.
func EncodeBatches ¶
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
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
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
EncodeSeriesList serializes stream identities as length-prefixed reversible hash pre-images.
func EncodeSideTables ¶ added in v0.2.0
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 ¶
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
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 ¶
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
ShardCount clamps a configured Config.ShardsPerTenant to the usable range: anything below one means a single shard.
func ShardKeyOf ¶ added in v0.38.0
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
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
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
SideHandler serves SidePath: it returns the tenant's side-store tables via fn.
func TenantOfShard ¶ added in v0.38.0
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
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
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
DecodeKeyList parses EncodeKeyList output, bounds-checking every length so a malformed or truncated peer response is rejected rather than panicking.
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
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.
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 ¶
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.
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
SideFunc returns the local store's side-store tables (name → encoded payload) for a tenant.
type TenantFunc ¶ added in v0.38.0
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.
Source Files
¶
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. |