NFS: Stateless, and Brittle Over the WAN
Sun’s Network File System makes the filesystem a client/server protocol. Its central design goal is simple, fast crash recovery, achieved by making the server stateless — it keeps no per-client state, so every request carries everything needed to service it (aREAD sends the explicit offset; the client, not the server, tracks position). Most operations are idempotent, so the failure handler collapses to a single rule: set a timer, and if no reply arrives, retry. Elegant — but it has costs that bite hard over a wide-area network:
- Weak cache consistency. Clients cache and buffer writes for performance, which introduces the update-visibility problem. NFS papers over it with flush-on-close and an attribute cache with a timeout (~3 seconds), so whether a client sees the latest version of a file “depends on whether the cache entry has timed out” — the source of NFS’s notorious occasional stale reads.
- The hang. Because the client simply retries until the server answers, an unresponsive or partitioned server makes the client block indefinitely. A
read()that never returns takes the calling process — and often a whole pipeline — down with it. A network partition is indistinguishable from a crash. - Small files are easy; large files are not. Over a LAN with small files NFS is fine. Over a WAN, file seeks and mid-file updates on large files get ugly, and rapid writes suffer under lost packets.
fileserver crashes or the network partitions, any process that so much as stats a path under /mnt/shared blocks in uninterruptible sleep — ls /mnt/shared hangs, shrugs off Ctrl-C, and the console fills with NFS server fileserver not responding, still trying. The mount doesn’t return an error; it waits, and takes the caller down with it. That is tolerable on a quiet LAN with a reliable server; for agents scattered across the internet — where partitions are routine and every mount is one flaky link from a hung process — it is the wrong default.
AFS: Whole-File Caching, and Stateful Bookkeeping
The Andrew File System was built for scale. Onopen() it fetches the whole file to the client’s local disk and serves subsequent reads and writes locally; on close() it ships the whole file back. To avoid clients constantly polling “has this changed?”, AFS added callbacks — a promise from the server to notify a client when a cached file changes — giving close-to-open consistency. It scales better than NFS, but the design fights our use case:
- Callback state is awkward for clients that come and go. A client that was offline may have missed an invalidation and must revalidate its whole cache on return; a rebooted server does not know which clients cache what and must have everyone re-validate. Ephemeral agents — containers that appear, work, and vanish — are exactly the clients this bookkeeping handles worst.
- Whole-file caching punishes the workload we care about. Fetching and rewriting an entire file just to append one line to a shared worklog, or to touch a small region of a large file, is precisely what AFS does poorly. AFS itself notes that its baseline consistency is not enough for concurrent updates to something like a shared code repository — you still need explicit file-level locking.
Separating Metadata From Data
By the early 2000s a different design had emerged — built for a fleet of cheap, failure-prone machines from the start, rather than making a single server’s disk look remote.Google File System
Google File System (GFS, 2003) split the problem cleanly in two:- a single master holds all the metadata — the namespace and the map from each file to its chunks — in memory, and
- a fleet of chunkservers holds the file data as large chunks (64 MB), replicated for durability.
HDFS and MooseFS
HDFS is the open-source realization of that design: a NameNode holds the namespace and the file→block map — “user data never flows through the NameNode” — while DataNodes store the blocks (128 MB) and serve reads and writes directly to clients. MooseFS applied the same master-plus-chunkservers split but exposed a full POSIX filesystem you mount, closing the gap back to the local-filesystem interface. These systems fixed what NFS and AFS could not: they stopped pretending one server owns a disk, and instead let an authoritative metadata service coordinate a scalable pool of data storage. What they still asked of you was to run that metadata master and that fleet of data servers yourself — which is exactly the operational burden CloudFS removes.Further Reading
- Sun’s Network File System (NFS) and The Andrew File System (AFS), from OSTEP.
- The Google File System (Ghemawat, Gobioff, Leung), Apache Hadoop / HDFS, and MooseFS.