etcd-io/etcd
Raft integration
Source: server/etcdserver/raft.go, server/etcdserver/api/rafthttp/. The Raft library itself lives in a separate repo at go.etcd.io/raft/v3.
Purpose
This subsystem is the bridge between the Raft library and the rest of etcd:
- Drives the Raft
Readyloop: persists entries, sends messages, hands committed entries to the apply pipeline. - Implements the HTTP-based peer transport (
rafthttp) — etcd does not use gRPC for peer traffic. - Maintains snapshot install/delivery to slow followers.
Directory layout
server/etcdserver/
├── raft.go # raftNode struct, Ready loop, helpers
├── server.go # EtcdServer.run drives the loop
└── api/
├── rafthttp/ # HTTP transport (peer.go, stream.go, pipeline.go, ...)
└── snap/ # On-disk snapshot storeKey abstractions
| Symbol | File | Description |
|---|---|---|
raftNode |
server/etcdserver/raft.go |
Wraps raft.Node with persistence, transport, and apply hooks |
toApply |
server/etcdserver/raft.go |
Bundle of entries + snapshot delivered to EtcdServer.run |
rafthttp.Transport |
server/etcdserver/api/rafthttp/transport.go |
Peer-to-peer transport, owns per-peer stream/pipeline workers |
rafthttp.peer |
server/etcdserver/api/rafthttp/peer.go |
Per-remote-member sender/receiver |
rafthttp.streamWriter / streamReader |
server/etcdserver/api/rafthttp/stream.go |
Long-lived HTTP streams for normal Raft messages |
rafthttp.pipeline |
server/etcdserver/api/rafthttp/pipeline.go |
Burst-friendly fallback channel for large messages |
snap.Snapshotter |
server/etcdserver/api/snap/snapshotter.go |
Reads/writes Raft snapshot files |
How it works
sequenceDiagram
participant Server as EtcdServer
participant RNode as raftNode
participant Lib as raft.Node
participant WAL
participant Trans as rafthttp.Transport
participant Peers
Server->>RNode: start()
loop Each tick
Lib-->>RNode: Ready{entries, hardstate, snapshot, messages, committed}
RNode->>WAL: Save(hardstate, entries)
alt has snapshot
RNode->>RNode: SaveSnap, ApplySnap
end
RNode->>Trans: Send(messages)
Trans->>Peers: HTTP POST /raft (stream or pipeline)
RNode->>Server: toApply{committed entries, snapshot, notifyc}
RNode->>Lib: Advance()
endThe leader's path is the same except messages flow outwards from this node; followers receive messages via rafthttp -> raft.Node.Step (in transport.go).
Configuration knobs
| Flag | Default | Effect |
|---|---|---|
--heartbeat-interval |
100 ms | Raft heartbeat period |
--election-timeout |
1000 ms | Election timeout (must be 5–10× heartbeat) |
--snapshot-count |
10000 | Trigger a Raft snapshot every N committed entries |
--max-request-bytes |
1.5 MiB | Per-request size cap (server-side) |
--initial-cluster / --initial-advertise-peer-urls |
— | Bootstrap topology |
Integration points
- Storage: persists log entries to
server/storage/wal/, and snapshots toserver/etcdserver/api/snap/+server/storage/mvcc/. - Apply: hands
toApplytoEtcdServer.run, which routes throughapply/uberApplier. - Transport:
rafthttplistens on--listen-peer-urls. TLS, keepalive, and stream-vs-pipeline routing are all configured here.
Entry points for modification
- New peer-transport behavior →
server/etcdserver/api/rafthttp/peer.go,stream.go,pipeline.go. Watch out: the transport is HTTP/1.1 by design; it does not multiplex. - New apply-side reaction to a snapshot install →
server/etcdserver/server.go::applySnapshot. - Tuning Raft constants →
server/etcdserver/raft.go(maxSizePerMsg,maxInflightMsgs).
Cross-references
- WAL for the on-disk log format.
- Apply pipeline for what happens to committed entries.
- Membership for conf-change handling.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.