File Operations
Post /v1/files
Body: {path, replication_factor, block_size_mb}
Response: {file_id, created_at}
GET /v1/files/{file_id}/read?offset=0&length=blah
Response:
POST /v1/files/{file_id}/append
Body:
Response: {bytes_appended, new_size}
DELETE /v1/files/{file_id}
Response: 204 No Content
Metadata Operations
GET /v1/files/{file_id}/metadata
Response: {
path
size
block_size
replication factor
blocks:
permissions:
created_at
modified at
}
Locking (for conc access)
POST /v1/locks
Body: {file_id, type, ttl_seconds
Response: {lock_id, expires_at}
DELETE /v1/locks/{lock_id}
Response: 204 No Content
The architecture follows the GFS/HDFS model: separate metadata management from data storage
Core Insight:
Files are split into fixed-size chunks (64-128mb). Metadata (namespace, chunk locations) is managed by a centralized master. Data flows directly between clients and chunk servers - the master is never in the data path.
Components:
Master Node (Metadata Management)
What it store (all in RAM f or speed)
Scaling math: 1 bill files x 100 bytes = 100GB metadata. Fits in RAM on a large machine. Each file averages 2 chunks -> 2B chunk mappings x 48 bytes = ~96 GB. Total 200GB RAM - achievable on modern hardware
Persistence:
High availability:
Why centralized master works: The master handles only metadata operations (open, stat, ls) - never data. At 10k metadata operations per sec with <1ms per op, a single master handles most workloads. For extreme scale (10B+files), shard the namespace across multiple masters by directory subtree (as HDFS federation does)
2. Chunk Storage and Replication Pipeline
Chunk structure on disk:
/data/chunks
blk1.dat (64mb data)
blk1.meta (checksum per 64kb block, version)
Write path (pipeline replication):
Client wants to write chunk to replicas (DN1, DN3, DNS)
Why pipeline, not fan-out?
Consistency via leases:
Read path:
Fault tolerance and re-replication:
Failure detection:
Rereplication:
Master detects: chunk blk1 has 2 replicas (target: 3)
Rack-aware placement: Replicas are placed across failure domains:
Data integrity:
Garbage collection
Key Tradeoffs
Large chunk size (64mb) -> wastes space for smll files vs fewer chunks to track, higher throughput for large sequntial IO
Centralized master -> single metadta bottleneck vs simple consistency, no distributed consensus for evey op
Pipeline replication vs fanout -> higher latency vs lower client bandwidth, streming starts immediately
Lease based consistency vs distributed locks: Lease expiry delay on failure vs simplier protocol, no deadlocks
In-memory metadata (RAM cost) vs microsecond metadata lookups
Rack-aware placement - constrains placement choices vs survives full rack failure
Lazy garbage collection - disk not reclaimed immediately vs accidental delete recovery -> simpler deletion path