Skip to content

Concepts

The KV plane

marekvs's convergent key-value design, ported to Go on WavesDB - partitions, hybrid logical clocks, CRDT merges, replication, anti-entropy, gossip, and the Raft groups that grant leases.


What it is

The KV plane is an eventually consistent, coordination-free, replicated key-value store. It is marekvs's design, ported to Go and stored in WavesDB. marekvs is the design specification and the matcher prototype's sidecar, not a dependency. The port diverges from it on purpose where marekvs has merge defects: its element join keeps no live-dot cap, so it is a true lattice. A differential test harness against marekvs is deferred.

It holds the documents with their fields, per-article traffic in specialised convergent structures, campaigns and reach dials, locators, and the hot and provisional match rows. Data lives on SSD, replicated three ways.

Taken from marekvs

Mechanism Summary
Partitioning pid = (crc16(userkey) % 16384) >> 2: 4,096 partitions, Redis {hash tags} honoured
Envelope a 19-byte header: flags, hlc, origin, TTL deadline; written once at the origin and shipped byte for byte
Hybrid logical clock 48-bit milliseconds and a 16-bit counter; remote clocks more than 5 s ahead are clamped
Merge families LWW register, observed-remove element set (ORSWOT), lattice value, structural decomposition
Placement highest random weight: owners are the top-N alive nodes by xxh3_64(node ‖ pid), spread over zones
Replication commit, acknowledge, fan out to the owners on a ring, with a bounded unacknowledged window
Anti-entropy per partition, 256 buckets of XOR digests compared with a random co-owner every few seconds
Membership joining, active, leaving, down, left; a restart fast path, a join gate, planned leave

The partition's highest-ranked active owner is its H1. H1 is not a consistency primary: any owner accepts writes. It is where the indexer, the fresh tail, and provisional matching run.

What ysearch adds

  • Record tags for its data: documents with per-field merges, the unique-key index, traffic slots, visitor sketches, campaigns, dials, locators, takedowns, hot match rows m, and provisional match rows n. Every tag is a lattice, so replicas converge, and every tag is capability-gated.
  • A local column family outside anti-entropy, for the changelog, derived indexes, and indexer cursors. data bytes must converge; local bytes are node-specific.
  • The changelog is written in the same WavesDB transaction as every apply, whether the write came from a client, the replication ring, anti-entropy, or bootstrap. That is what lets the indexer trust it, and it needs WavesDB's unified-memtable mode for crash atomicity across column families.
  • Takedowns never expire. A takedown is its own record without a TTL, so a resurrected copy of a deleted article stays suppressed.
  • gRPC streams for the ring, anti-entropy, bootstrap, and gossip push-pull. Gossip digests use UDP.

Gossip

Every pod of every role runs ysearch's own SWIM-style gossip, shaped like chitchat but with a larger payload. It carries node state and capabilities, catalog and epoch heads (including G_chk), serving lag, load and hot-key signals, and small replicated state. Gossip is a hint channel except for membership: authoritative state stays in KV records, Raft logs, and S3.

A capability is a format or feature a binary implements. It is advertised in gossip and usable only after the control role has enabled it cluster-wide, once every kv member advertises it. An older binary fails closed.

Leases from Raft

Jobs that must have exactly one holder get a lease from an embedded Raft group in the control role, a three-replica StatefulSet:

  • the meta group holds the namespace registry, enabled capabilities, origin allocation, cluster settings, and the cluster-wide maintenance lease;
  • one group per namespace holds that namespace's publisher, planner, table writer, and dial-controller leases and their fencing counters.

The fencing epoch is a Raft-committed counter per lease, incremented when the holder changes. It appears in the names of the objects a holder writes, and readers reject a lower one. Per-partition consensus for opt-in ACID keyspaces is reserved for after v1.

Protocols

The RESP server and command families of marekvs stay, without Lua (EVAL, EVALSHA, and SCRIPT are not implemented; write scripts are WASM apps). ysearch adds the DOC.*, TRAFFIC.*, and MATCH.* command families, and gRPC services for the same operations.