Dynomite
Dynomite turns a single-node key/value store -- Valkey, Memcached, or the embedded Noxu engine -- into a shared-nothing, multi-datacenter, highly available cluster, without asking that store to know anything about replication, sharding, or consensus.
This is the reference manual and getting-started guide for the Rust implementation of Dynomite. It is written to be read two ways: front to back, as a guided tour that takes you from "what is this and why would I use it" to a running, replicated cluster and an embedded engine in your own program; and as a reference, dipped into by section when you need the exact semantics of a consistency level, a wire frame, or a configuration knob.
Read Why Dynomite? and Concepts in Ten Minutes, then stand up Your First Cluster. If you are embedding the engine in a Rust program instead of running the server, jump to Your First Embedded Engine.
What it is
Dynomite is available as two things from one codebase:
-
dynomited-- a standalone server binary. You point it at a backend (a local Valkey or Memcached, or its own embedded store) and a list of peers, and it presents the backend's own wire protocol to clients while replicating writes across the cluster behind the scenes. Existing Redis and Memcached clients talk to it unmodified. -
dynomite-engine-- a library crate (imported asdynomite), published on crates.io, that embeds the same distribution layer directly in your Rust program through a stable, documented API. You supply a backend by implementing one trait; Dynomite supplies the ring, gossip, quorum, hinted handoff, and repair.
On top of the engine sits Dyniak, a Riak-compatible layer backed by the transactional Noxu storage engine. Dyniak adds buckets and objects, convergent data types (CRDTs), cross-node XA transactions, links, secondary indexes, MapReduce, and full-text / vector / regex search. It has its own set of chapters.
How a request flows
flowchart LR
C[Redis / Memcache / Riak client] -->|native wire protocol| P(dynomited node)
P -->|owns this key| L[(local backend)]
P -->|replica lives elsewhere| G{{ring lookup}}
G -->|DNODE peer frame| R1(peer node)
G -->|DNODE peer frame| R2(peer node)
R1 --> LB1[(backend)]
R2 --> LB2[(backend)]
A client speaks its backend's protocol to any node. That node routes the key over the ring, serving it locally or forwarding it to the owning peers over the DNODE peer plane.
The client never learns the topology. It connects to any node, speaks the protocol it already knows, and Dynomite does the routing, replication, and reconciliation.
What the engine gives you
- Sharding
- Consistent-hash partitioning over a token ring, shared-nothing, no single point of failure.
- Replication
- Multi-datacenter, rack-aware, with tunable quorum reads and writes.
- Membership
- Gossip-based discovery and failure detection; auto-eject and auto-rejoin.
- Durability under failure
- Hinted handoff for writes to briefly-absent peers; read repair and Merkle-tree anti-entropy for divergent replicas.
- Transports
- TCP (the default, matching upstream) or QUIC, both over IPv4 and IPv6.
- Dyniak extras
- CRDTs, XA transactions, links, 2i, MapReduce (optional WASM phases),
and durable
FT.*search.
The philosophy: distribution as a layer, not a rewrite
The central bet of Dynomite -- inherited from the Amazon Dynamo paper and Netflix's original C implementation -- is that availability and cross-datacenter replication can be added as a thin layer in front of a storage engine, rather than baked into it. A single-node store stays simple and fast; Dynomite wraps it with the distributed-systems machinery, and the two concerns stay separate.
This manual is explicit about the trade-offs that bet implies, and about the designs we considered and deliberately did not choose. Those are collected in Design Decisions (Roads Not Taken) and called out inline wherever a choice matters.
This is a from-scratch Rust implementation of
Netflix Dynomite, which itself
extended Twitter's twemproxy. It aims to be functionally identical to
the C original; the live symbol-level mapping is in
docs/parity.md.
Where the Rust port deliberately diverges, that divergence is recorded
as a parity deviation and explained in this manual.
Conventions used in this manual
- Shell commands assume you have run
nix developfirst, which pins every tool the project uses. - Rust snippets that appear inline are illustrative teaching examples.
Complete, compilable programs live under
crates/*/examples/and each has its own walk-through in the Examples part. - Links written like
ServerBuilderpoint into this manual; API links point at the generated rustdoc; and manual-page references such asdynomited(8)point at the shipped man pages.