Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Replicated Key-Value Store

A small distributed key-value store implemented in Go to explore replication, consistency trade-offs, failure handling, and deterministic conflict resolution. Three independently configured HTTP replicas can run in either eventual-consistency or majority-acknowledged strong-consistency mode.

This repository is a cleaned, portfolio-ready version of a Distributed Systems course project. The implementation and recorded experiments were completed as a two-student assignment; no claim about an individual division of work is made here.

What It Demonstrates

  • Three peer-to-peer replica processes with independent in-memory state
  • Eventual consistency through delayed asynchronous replication
  • A strong mode that accepts a write after a majority of replicas acknowledge it
  • Versioned records and deterministic Last-Write-Wins conflict resolution
  • Configurable replication delay and request timeout
  • Failure, stale-read, concurrent-write, and network-delay experiments
  • A command-line client for writes, reads, state inspection, conflict inspection, and health checks

Architecture

flowchart LR
    C["CLI client"] -->|HTTP| R1["Replica 1 :8001"]
    C -->|HTTP| R2["Replica 2 :8002"]
    C -->|HTTP| R3["Replica 3 :8003"]
    R1 <-->|POST /replicate| R2
    R2 <-->|POST /replicate| R3
    R3 <-->|POST /replicate| R1
Loading

Each replica exposes the same API and stores records with a value, version, writer identifier, and nanosecond timestamp. A higher version wins. Equal-version conflicts use the timestamp and then the replica identifier as a deterministic tie-breaker.

API

Method Endpoint Purpose
POST /put Write a key/value pair
GET /get?key=<key> Read a key from one replica
POST /replicate Apply a record received from a peer
GET /dump Inspect the local store
GET /conflicts Inspect detected conflicts
GET /health Check replica identity and mode

Project Structure

.
|-- client/        # Command-line HTTP client
|-- configs/       # Eventual, strong, and delay experiment configurations
|-- docs/          # Original course report
|-- replica/       # Replica server and focused unit tests
|-- results/       # Recorded outputs for four experiment scenarios
|-- go.mod
`-- README.md

Requirements

  • Go 1.22 or newer
  • Three terminal sessions for the full local cluster

The implementation uses only the Go standard library.

Run the Cluster

From the repository root, start one replica in each terminal:

go run ./replica -config configs/replica1.json
go run ./replica -config configs/replica2.json
go run ./replica -config configs/replica3.json

The default configuration runs eventual consistency with a five-second replication delay. Replace the files with replica1_strong.json, replica2_strong.json, and replica3_strong.json to run the majority-acknowledged mode.

Use the Client

go run ./client -op health -replica 127.0.0.1:8001
go run ./client -op put -replica 127.0.0.1:8001 -key course -value distributed-systems
go run ./client -op get -replica 127.0.0.1:8002 -key course
go run ./client -op dump -replica 127.0.0.1:8003
go run ./client -op conflicts -replica 127.0.0.1:8001

Experiments and Recorded Results

The results/ directory preserves the original scenario observations:

  1. Temporary inconsistency: an immediate read missed a newly written key; all three replicas converged after the configured five-second delay.
  2. Replica failure: eventual mode remained available with a peer offline. Strong mode could commit with one failed replica because two acknowledgements formed a majority.
  3. Concurrent conflict: two version-1 writes were detected as a conflict and all replicas converged to the deterministic Last-Write-Wins result.
  4. Replication delay: experiments used delays of 0, 500, and 2,000 ms to observe stale reads and convergence behavior.

These are recorded course experiments, not production benchmarks. Hardware, scheduling, and request timing can change measured latency when the scenarios are repeated.

Validation

go test ./...
go vet ./...

The included tests cover version ordering and equal-version conflict resolution.

Limitations

  • State is in memory and is lost when a replica stops.
  • Membership is static and configured through JSON files.
  • Peer communication is unauthenticated HTTP intended for local experiments.
  • The strong mode is an educational majority-acknowledgement protocol, not a consensus algorithm such as Raft. A peer may apply a replicated record before the initiating replica knows whether a majority will be reached.
  • There is no automatic recovery or catch-up protocol for a replica that was offline.

Documentation

The original technical report is available at docs/report.pdf. This README is self-contained; the report provides the full experiment narrative and terminal evidence.

About

Replicated Go key-value store exploring eventual and strong consistency under configurable network delays.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages