ARCHITECTURES

Different assemblies of the same interfaces produce different storage systems.

In most distributed storage systems, the architecture is fixed. The topology, where metadata lives, how replication works, how nodes discover each other, is a decision made once at design time.

In Sandstore, topology is a variable. The system is built around two orchestration interfaces: a ControlPlaneOrchestrator and a DataPlaneOrchestrator. Implement new versions of those interfaces, write a wiring file, and you have a new architecture. The server layer, the client, and the deploy tooling stay the same.

Available Now

HYPERCONVERGED NODE

Converged Architecture

What it is

Every node runs both the control plane and the data plane. There are no separate metadata servers. Cluster membership is handled by etcd. This is similar in spirit to CockroachDB.

When to use it

High read/write locality. Simpler operations. No single metadata bottleneck. Good for clusters where every node should be equal.

Current component stack

ClusterServiceetcd
CommunicatorgRPC
MetadataServiceBoltDB
MetadataReplicatorDurable Raft (WAL + CRC)
ChunkServiceLocal disk

How to run it

git clone https://github.com/AnishMulay/sandstore cd sandstore docker compose -f deploy/docker/etcd/docker-compose.yaml up -d ./scripts/dev/run-smoke.sh

This starts a 3-node cluster on localhost, waits for leader election, and runs a full smoke test. The cluster stays up after the script finishes.

PLANNED

Coming Soon

GFS-STYLE SEPARATED METADATA

Disaggregated Architecture

What it will be

Dedicated metadata servers handle all namespace and placement operations. Separate data nodes handle chunk storage and retrieval. This follows the architecture described in the Google File System paper.

How it differs

Unlike the converged topology, metadata and data live on different nodes. This enables independent scaling of the metadata and storage layers at the cost of additional network hops.

What needs to be implemented

PlacementStrategynew
DataPlaneOrchestratornew
TransactionCoordinatornew
MetadataServiceoptional new
MetadataReplicatoroptional new

Build Your Own

To build a new topology, implement the interfaces that matter for your design and write a wiring file that assembles them. You do not need to modify the server layer, the client, or the deploy tooling.

The extension points

ControlPlaneOrchestrator
DataPlaneOrchestrator
PlacementStrategy
TransactionCoordinator
MetadataService
MetadataReplicator
ClusterService
Communicator
ChunkService

The assembly pattern

// wire_your_topology.go clusterSvc := NewYourClusterService(...) metaSvc := NewYourMetadataService(...) metaRepl := NewYourMetadataReplicator(metaSvc, ...) chunkSvc := NewYourChunkService(...) placement := NewYourPlacementStrategy(clusterSvc) txCoord := NewYourTransactionCoordinator(...) cpo := NewYourControlPlane(metaSvc, metaRepl, placement, ...) dpo := NewYourDataPlane(chunkSvc, txCoord, ...) server := NewSimpleServer(comm, cpo, dpo, logSvc, metaRepl)

The canonical reference is servers/node/wire_grpc_etcd.go. It assembles the current topology in dependency order and is the clearest expression of how the system is meant to be extended.

Have a topology idea?

New topology implementations are the most valuable contribution to Sandstore. If you have an idea for a new architecture, open an issue to discuss it or submit an implementation directly.