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.
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.
| 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.
- 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 rowsn. Every tag is a lattice, so replicas converge, and every tag is capability-gated. - A
localcolumn family outside anti-entropy, for the changelog, derived indexes, and indexer cursors.databytes must converge;localbytes 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.
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.
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
maintenancelease; - 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.
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.