Open-Source Wikis

/

etcd

/

Systems

/

Raft integration

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 Ready loop: 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 store

Key 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()
    end

The 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 to server/etcdserver/api/snap/ + server/storage/mvcc/.
  • Apply: hands toApply to EtcdServer.run, which routes through apply/uberApplier.
  • Transport: rafthttp listens 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

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Raft integration – etcd wiki | Factory