Coordinator Architecture
Overview
Redis Stream Coordinator separates the control plane from the data plane. The coordinator decides which member should own each Redis Stream shard. Consumer applications still perform message reads, business handling, retry, DLQ, and acknowledgement.
Responsibilities
Coordinator Server
- Own group metadata and shard metadata.
- Track member liveness from heartbeats.
- Fence stale or expired owners.
- Calculate sticky target assignment.
- Validate member-reported current assignment.
- Enforce revoke-before-assign.
- Start, monitor, and roll back shard count migrations.
- Serve producer routing metadata.
- Expose monitoring APIs and Micrometer metrics.
- Serialize state changes through the Redis mutex and store revision checks.
Consumer Module
- Generate or load a member identity.
- Send heartbeat requests.
- Apply assigned shard changes.
- Stop reads for revoked shards.
- Report owned shards, revoking shards, capacity, and progress.
- Handle fencing responses by stopping local work and rejoining.
- Optionally run a Redis Stream polling adapter.
Producer Module
- Fetch routing metadata from the coordinator.
- Cache routing metadata until
metadataVersionchanges or a stale publish result is observed. - Route a partition key to a shard.
- Publish records to Redis Stream with configured max length and approximate trim policy.
- Refresh routing metadata when needed.
Redis Metadata Store
- Store group metadata, shard count, assignments, member state, resharding state, audit pointers, and derived monitoring columns.
- Keep the canonical
GroupMetadataaggregate as JSON in a single Redis hash key per{streamPrefix, consumerGroup}. - Use Redis mutex and
storeRevisioncompare-and-set updates to reject stale writers.
Control-Plane Flow
sequenceDiagram
participant M as Consumer Member
participant C as Coordinator
participant S as State Store
participant R as Redis Stream
M->>C: Heartbeat(memberId, ownedShards, revokingShards, capacity)
C->>S: Acquire Redis mutex
C->>S: Read latest group metadata hash
C->>C: Validate ownership report
C->>C: Expire stale members if needed
C->>C: Recalculate target assignment if metadata changed
C->>S: Save with storeRevision check
C->>S: Release Redis mutex
C-->>M: HeartbeatResponse(assignment, epochs, fencing status)
M->>R: Start/stop reads according to assigned shards
Event Loop
The coordinator event loop runs periodically and performs operational reconciliation:
- expire members whose heartbeat lease has timed out,
- continue rebalance when revocations finish,
- evaluate resharding drain progress,
- update monitoring projections,
- record invariant violations.
The event loop uses the same Redis mutex and store revision boundary as heartbeat and admin requests. If another coordinator instance updates the same group first, the losing instance reloads or skips that group and the next tick continues reconciliation.
State Serialization
Metadata state changes are serialized by the Redis mutex and store revision CAS for the group. Users should not need to perfectly enforce replicas=1, Kubernetes Recreate, or blue/green active-passive behavior before trying the project.
State-changing requests follow this order:
- acquire Redis mutex,
- read the latest group metadata hash,
- validate and process the request,
- save with store revision compare-and-set,
- release mutex,
- return a response derived from the written metadata.
Store revision checks remain as a final stale-write guard.
Rebalance Model
Rebalance is target-assignment driven:
- Coordinator computes the desired owner for each shard.
- Members receive target assignment through heartbeat responses.
- Members stop work for shards that are no longer assigned.
- Members report revoke acknowledgement.
- Coordinator makes the shard assignable to the next target member.
- The next member starts work and reports ownership.
This avoids a global stop-the-world barrier and keeps unaffected members consuming.
Failure Handling
| Failure | Coordinator Behavior | Member Behavior |
|---|---|---|
| Member heartbeat timeout | Mark member EXPIRED, fence its ownership, recalculate assignment |
Rejoin with full heartbeat if it comes back |
| Stale ownership report | Reject or fence the member depending on severity | Stop reads and rejoin |
| Coordinator restart | Reload state from the Redis metadata key and continue from stored epochs | Continue heartbeating |
| Redis metadata outage | Fail control-plane writes and report degraded health | Keep local policy or stop based on application risk policy |
| Resharding provisioning failure | Keep migration in failed/preparing state and expose it through monitoring | Continue reading existing readable shard set |
Consistency Boundaries
- Coordinator metadata updates are serialized by Redis mutex and protected by store revision checks.
- Redis Stream data-plane messages are not part of the coordinator metadata transaction.
- Producer publish and consumer business processing remain at-least-once.
- Monitoring projections are derived from persisted Redis coordinator state and can be rebuilt.
Deployment Shape
The recommended deployment is:
- one coordinator service behind a stable HTTP endpoint,
- Redis metadata store reachable from coordinator instances,
- optional multiple coordinator replicas using Redis state mutex,
- consumer and producer applications using the Spring Boot starter,
- external dashboards consuming actuator metrics and monitoring APIs.