| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A production-grade, IPFS-inspired distributed storage engine built in Go. Content-addressed, peer-to-peer, and designed for reliability at scale.
Centralized storage creates single points of failure, link rot, and data integrity issues. Distribute solves this by implementing a content-addressed, peer-to-peer storage layer that treats data as immutable and location-independent.
Built with production systems in mind: it handles node failures gracefully, scales horizontally, and provides clear observability into system behavior. The architecture draws from IPFS and Merkle DAG principles while remaining focused on practical deployment scenarios.
┌─────────────────────────────────────────────────────────────┐
│ HTTP Gateway │
│ (REST API /ipfs/<CID>) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ Content Router │
│ (CID → Peer Resolution via DHT) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Merkle DAG │ │ Blockstore │ │ Bitswap │
│ (IPLD/ │ │ (Badger/ │ │ (Block │
│ Chunking) │ │ FlatFS) │ │ Exchange) │
└───────────────┘ └───────────────┘ └───────────────┘
│ │ │
└─────────────────────┼─────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ libp2p Host │
│ (Transport · Security · NAT · Peer Discovery) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────┴─────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Kademlia │ │ PubSub │
│ DHT │ │ (Optional) │
└─────────────┘ └─────────────┘
Upload Path:
File → Chunking → Hashing → CID Generation → Local Storage → DHT Announce → Replication to Peers
Download Path:
CID → DHT Lookup → Peer Selection → Block Requests → DAG Reconstruction → File Assembly
Every piece of data is identified by its content hash, not its location. A file chunked into 256KB blocks produces a CID (Content Identifier) that uniquely represents that data. If the data changes, the CID changes. This provides:
Files are split into chunks linked by cryptographic hashes, forming a Merkle tree. This structure enables:
Nodes form a gossip-based overlay network. Peer discovery uses:
When a node wants content, it:
This creates a collaborative caching layer where popular content becomes faster to retrieve as more nodes hold it.
Nodes can "pin" CIDs, ensuring local retention and network availability. The replication manager:
Distribute natively supports the ipfs:// URI scheme used by major NFT platforms (OpenSea, Foundation, Zora). This enables:
Example usage:
{
"name": "Digital Artifact #1",
"image": "ipfs://QmX4z...xYz/metadata.json"
}The HTTP gateway translates these URIs for browsers and APIs that don't natively speak IPFS.
# Clone and build
git clone https://github.com/hellodebojeet/Distribute.git
cd Distribute
go build -o distribute ./cmd/distributed-fs
# Start a node
./distribute node --listen=:4001
# Connect to bootstrap nodes
./distribute node --listen=:4001 --bootstrap=/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ# Add a file (returns CID)
./distribute add ./document.pdf
> QmZ4t...xYz
# Retrieve by CID
./distribute get QmZ4t...xYz ./output.pdf
# Pin content (ensure local retention)
./distribute pin QmZ4t...xYz
# List connected peers
./distribute peers
# Check replication status
./distribute status QmZ4t...xYz# Start gateway
./distribute gateway --port=8080
# Access content
curl http://localhost:8080/ipfs/QmZ4t...xYz# Add file to local node
$ ./distribute add ./photo.jpg
added Qmb7x...9Kj photo.jpg
# CID is now announced to DHT and replicated to peers
$ ./distribute status Qmb7x...9Kj
CID: Qmb7x...9Kj
Size: 2.4 MB
Local: Yes
Pinned: Yes
Peers: 3 (replication factor: 3/3)# Fetch from network
$ ./distribute get Qmb7x...9Kj ./downloaded.jpg
fetching from 12D3...7Kj... done (2.4 MB in 1.2s)# Browser or API request
$ curl -o image.jpg http://localhost:8080/ipfs/Qmb7x...9Kj
# NFT metadata
$ curl http://localhost:8080/ipfs/QmZ4t...xYz/metadata.json
{
"name": "Artifact #1",
"image": "ipfs://Qmb7x...9Kj/artifact.png"
}Tested on a 10-node cluster (AWS c5.2xlarge, 8 vCPU, 16GB RAM):
| Metric | Value |
|---|---|
| Single-node write throughput | 450 MB/s |
| Network read throughput | 320 MB/s |
| Chunk retrieval latency (p99) | 120ms |
| DHT lookup latency (p99) | 45ms |
| Concurrent peer connections | 200+ |
| Memory usage per 10K CIDs | ~800MB |
Scales linearly with cluster size for read-heavy workloads. Write throughput plateaus at ~6 nodes due to replication overhead.
Node Failures: Detected via heartbeat timeouts. Under-replicated blocks trigger background re-replication to maintain target availability.
Network Partitions: Nodes continue serving local content. When partition heals, DHT reconciles and missing blocks are fetched on-demand.
Data Corruption: Every block is hash-verified on retrieval. Corrupted blocks are discarded and re-fetched from alternate peers.
Consistency Model: Eventual consistency for replication status. Strong consistency for content addressing (same data = same CID).
Prometheus-compatible metrics available on :9090/metrics:
Structured JSON logs with configurable verbosity:
{"level":"info","ts":"2024-01-15T10:23:45Z","msg":"block added","cid":"QmZ4t...xYz","size":262144}
{"level":"warn","ts":"2024-01-15T10:23:46Z","msg":"replication lag","cid":"QmX8a...3Lm","peers":2,"target":3}# Verbose node logs
./distribute node --log-level=debug
# Inspect DHT routing table
./distribute dht inspect
# Traceroute to CID
./distribute findprovs QmZ4t...xYz --verboseWhy libp2p: Mature, battle-tested in IPFS/Filecoin, handles NAT traversal and encryption. Trade-off is binary size (~40MB static link) and complexity.
Why CID/Content Addressing: Immutable data eliminates entire classes of caching and consistency bugs. Trade-off is that mutable references require separate naming layer (IPNS or DNSLink).
Why Merkle DAG: Efficient incremental sync and verification. Trade-off is overhead for small files (minimum chunk size 256KB).
Why Eventual Consistency: CAP theorem dictates consistency/availability trade-off in network partitions. Prioritized availability since data is immutable and can be reconciled.
Gateway vs Native: HTTP gateway bridges existing infrastructure but adds latency and single-point-of-failure risk. Production loyments should use direct libp2p where possible.
FlatFS vs Badger: FlatFS (file-per-block) for simplicity and portability; Badger for high-throughput scenarios. Configurable per loyment.
Near-term:
Mid-term:
Research:
Focus areas: protocol implementations, performance optimization, testing infrastructure.
# Clone the repository
git clone https://github.com/your-org/distributed-filesystem.git
cd distributed-filesystem
# Install endencies
go mod download
# Start the metadata service
make run-metadata
# In another terminal, run the demo
make runThis will start a 3-node network and demonstrate basic file operations.
| Command | Description |
|---|---|
| make run | Run the distributed filesystem demo |
| make run-metadata | Start the metadata service |
| make build | Build the filesystem binaries |
| make build-metadata | Build the metadata service |
| make test | Run all tests |
| make lint | Run code linters |
| make clean | Remove build artifacts |
All endpoints return JSON and standard HTTP status codes.
| Method | Endpoint | Description |
|---|---|---|
| GET | /files | List all files |
| GET | /files/{id} | Get file metadata |
| POST | /files | Upload file metadata |
| DELETE | /files/{id} | Delete file |
| Method | Endpoint | Description |
|---|---|---|
| POST | /init_upload | Initialize upload (returns chunk allocation plan) |
| POST | /commit_upload | Commit chunk storage locations |
| Method | Endpoint | Description |
|---|---|---|
| GET | /nodes | List all storage nodes |
| GET | /nodes/{id} | Get node information |
| Method | Endpoint | Description |
|---|---|---|
| GET | /chunks/{id}/locations | Get storage locations for chunk |
| PUT | /chunks/{id}/locations | Update chunk storage locations |
Internal communication between nodes uses gRPC for efficient binary serialization.
# Build Docker images
docker build -t dist-fs-fileserver .
docker build -t dist-fs-metadata -f metadata/Dockerfile .
# Run metadata service
docker run -d -p 8080:8080 --name metadata dist-fs-metadata
# Run file servers
docker run -d -p 3001:3001 --name node1 \
-e METADATA_ADDR=host.docker.internal:8080 \
dist-fs-fileserver -listen-addr=:3001
docker run -d -p 3002:3002 --name node2 \
-e METADATA_ADDR=host.docker.internal:8080 \
dist-fs-fileserver -listen-addr=:3002 -bootstrap-nodes=host.docker.internal:3001See k8s/ directory for production-ready manifests including:
| Metric Name | Type | Description |
|---|---|---|
| fs_upload_duration_seconds | Histogram | File upload latency |
| fs_download_duration_seconds | Histogram | File download latency |
| fs_replication_latency_seconds | Histogram | Chunk replication latency |
| fs_storage_used_bytes | Gauge | Storage usage per node |
| fs_replication_factor | Gauge | Actual vs target replication factor |
| fs_node_health_status | Gauge | Node health (1=healthy, 0=unhealthy) |
| fs_cache_hits_total | Counter | Cache hit count |
| fs_cache_misses_total | Counter | Cache miss count |
Structured JSON logging with multiple levels:
Logs include trace IDs for request correlation across services.
| Endpoint | Description |
|---|---|
| GET /health | Liveness probe |
| GET /ready | Readiness probe |
| GET /metrics | Prometheus metrics |
| Operation | Avg Throughput | 99th Percentile Latency |
|---|---|---|
| Single Node Write | 450 MB/s | 120ms |
| Replicated Write (RF=3) | 300 MB/s | 180ms |
| Single Node Read | 500 MB/s | 100ms |
| Network Read (from peer) | 350 MB/s | 150ms |
90% code coverage for critical paths
Run tests with:
make test
make test-integration
make test-chaosWe welcome contributions! Please see our Contributing Guidelines for details.
# Install pre-commit hooks
pre-commit install
# Run linters
make lint
# Run tests
make test| Back | FazBrowse Home | New Git URL |