Skip to main content

Chapter 3: Master Operations

The master is the brain of GFS, orchestrating all metadata operations and coordinating the distributed system. What makes GFS’s master design remarkable is how much sophistication is packed into a single process without it becoming the bottleneck critics predicted. The namespace locking strategy alone — using fine-grained, per-path read-write locks instead of traditional directory-level locks — was a significant innovation that enabled thousands of concurrent file creations in the same directory. This chapter explores how the master manages the namespace, allocates chunks, grants leases, places replicas, and maintains system health through garbage collection. These mechanisms are directly relevant to modern system design: lease-based coordination appears in etcd and ZooKeeper, replica placement strategies inform Kafka broker assignment, and lazy garbage collection is the standard approach in systems from Go’s runtime to distributed databases.
Chapter Goals:
  • Understand namespace management with coarse-grained locking
  • Learn chunk lease mechanism for consistency
  • Explore replica placement strategies
  • Master garbage collection techniques
  • Grasp master fault tolerance mechanisms

Namespace Management

Unlike traditional file systems with per-directory data structures (where each directory is essentially an inode pointing to a list of child entries), GFS uses a flat namespace with efficient path-to-metadata lookups. This design choice eliminated the “directory inode bottleneck” that plagued concurrent access in POSIX file systems. In a traditional file system, creating a file requires locking the parent directory’s inode, which serializes all operations in the same directory. GFS’s approach of locking individual path components independently enabled massive parallelism — a property that was essential for supporting thousands of MapReduce tasks writing output simultaneously.

Namespace Structure

Coarse-Grained Locking

GFS uses namespace locks to allow concurrent operations:
Read-Write Locks on Paths:

Metadata Storage

The master keeps three types of metadata, all in memory:

File Namespace

Directory and File Names
  • Full pathname → metadata
  • Persistent (operation log)
  • Modification times
  • Owner/permissions
  • List of chunk handles

Chunk Metadata

Chunk Handle → Info
  • Chunk version number
  • List of replica locations
  • Primary (if leased)
  • Lease expiration
  • Partially persistent

Server State

Chunkserver Info
  • Available disk space
  • Current load (CPU, I/O)
  • Chunks stored
  • Last heartbeat time
  • Not persistent

Chunk Lease Mechanism

Leases are central to GFS’s consistency model, enabling mutations without the overhead of distributed consensus. The lease mechanism is one of GFS’s most elegant design decisions and one of the most frequently asked-about concepts in system design interviews. The core insight is this: instead of running an expensive consensus protocol (like Paxos) for every single write operation, the master delegates authority to a “primary” chunkserver for a bounded time period. During that lease window, the primary makes all serialization decisions unilaterally. This converts the cost of distributed coordination from per-operation to per-lease-grant — a dramatic reduction. Today, this pattern is ubiquitous: Kafka uses leader epochs, Spanner uses leader leases, and even distributed lock services like etcd use lease-based TTLs for the same reason.

How Leases Work

1

Master Grants Lease

2

Primary Orders Mutations

3

Lease Renewal

Lease Benefits

Snapshot Mechanics (Copy-on-Write)

Snapshots in GFS are nearly instantaneous and allow users to create a copy of a file or a directory tree without copying data. This capability was critical for production operations: teams could snapshot an entire dataset before running a risky MapReduce job, providing a cheap rollback mechanism. The technique GFS uses — Copy-on-Write (CoW) at the chunk level — is the same fundamental mechanism used by Linux’s fork() system call, by ZFS and Btrfs file system snapshots, and by container image layers in Docker. Understanding CoW in GFS gives you the mental model for all of these systems.

How it Works (The Metadata-Only Copy)

GFS uses Copy-on-Write (CoW) at the chunk level to implement snapshots efficiently.
  1. Lease Revocation: When the master receives a snapshot request, it first revokes any outstanding leases on the chunks of the files to be snapshotted. This ensures that any subsequent writes will require a new lease, giving the master a chance to intercept and create a copy.
  2. Log & Copy Metadata: The master logs the snapshot operation to disk. It then applies the operation to its in-memory state by duplicating the metadata for the file or directory. The new “snapshot” file points to the same chunk handles as the original.
  3. Reference Counting: Each chunk handle now has a reference count > 1.

The First Write After Snapshot

When a client wants to write to a chunk that has been snapshotted:
Key Benefit: The initial snapshot is just a metadata operation (copying pointers). The actual data copying is deferred until a write occurs, and only for the specific chunks being modified.

Replica Placement

The master decides where to place chunk replicas, optimizing for reliability, bandwidth, and load balancing.

Placement Goals

Survive Multiple Failures:
Network Topology Awareness:
Distribute Storage and I/O:

Chunk Creation

Re-replication

When replicas fall below target count (e.g., server failure), master re-replicates:

Garbage Collection

GFS uses lazy garbage collection instead of immediate deletion.

Why Lazy Deletion?

Benefits

Advantages of Lazy GC:
  • Simple implementation
  • Batched operations
  • No complex distributed deletion
  • Can recover from accidental deletes
  • Spreads I/O load over time
  • Handles failures gracefully

Trade-offs

Considerations:
  • Storage not freed immediately
  • May need manual cleanup for urgent cases
  • Requires background process
  • Deleted files visible briefly
  • Not suitable for quota systems

Garbage Collection Process


Master Fault Tolerance

The master is replicated to ensure system availability:

Replication Strategy

Fast Recovery

1

Checkpoint Loading

2

Log Replay

3

Chunk Location Discovery

4

Resume Operations


Interview Questions

Expected Answer:GFS uses lazy garbage collection instead of immediate deletion for several reasons:
  1. Simplicity: No complex distributed deletion protocol needed
  2. Recovery: Accidental deletions can be recovered during grace period (e.g., 3 days)
  3. Batch Operations: Deletions batched together, reducing overhead
  4. Failure Handling: If deletion message lost, chunk collected eventually anyway
  5. Spread Load: I/O spread over time, not sudden burst
  6. Piggybacking: Uses existing heartbeat mechanism
The trade-off is that storage isn’t freed immediately, but for Google’s workload this was acceptable since storage was relatively cheap and safety was more important.Process: File deletion → rename to hidden → wait grace period → background GC removes → heartbeat informs chunkservers → chunkservers delete local chunks
Expected Answer:GFS uses fine-grained read-write locks on full pathnames to enable concurrent operations:How it works:
  • Each path (file or directory) has a read-write lock
  • Operations acquire locks on full paths, not just the target
  • Example: Creating /home/user1/file requires:
    • Read lock on /home
    • Read lock on /home/user1
    • Write lock on /home/user1/file
Benefits:
  • Multiple operations in same directory can proceed in parallel
  • Example: Creating /data/file1 and /data/file2 concurrently
  • Both acquire read lock on /data (shared)
  • Each acquires write lock on different file (no conflict)
Deadlock prevention:
  • Locks acquired in lexicographic order
  • Example: Operation needs /a/x and /b/y
  • Always acquire in sorted order: /a/x then /b/y
This design enables linear scaling with concurrent operations, unlike directory-level locking which serializes all operations in the same directory.
Expected Answer:The lease mechanism provides consistency without distributed consensus:Setup:
  1. Master grants 60-second lease to one replica (primary)
  2. Only primary can order mutations during lease period
  3. Primary identity cached by clients
Write Process:
  1. Data pushed to all replicas (in memory, not applied)
  2. Client sends write request to primary
  3. Primary assigns serial number (ordering)
  4. Primary applies to local disk
  5. Primary sends order to secondaries
  6. Secondaries apply in same order
  7. All ACK to primary
  8. Primary ACKs to client
Consistency Guarantee:
  • All replicas apply mutations in same order (serialized by primary)
  • Same serial numbers → same state
  • No distributed consensus needed
  • Primary has authority during lease
Failure Handling:
  • Lease timeout (60 sec) ensures master can regain control
  • If primary fails, lease expires naturally
  • Master can grant new lease to different replica
  • No need for perfect failure detection
Why it works:
  • Single authority (primary) during lease
  • Time-bounded authority (60 sec)
  • Master retains ultimate control
  • Simple protocol, high performance
Expected Answer:Several approaches to scale beyond single master:1. Metadata Sharding (like Colossus):
  • Partition namespace by path prefix
  • Multiple master shards, each handles subset
  • Example: Master1 handles /data/*, Master2 handles /logs/*
  • Benefits: Scales metadata capacity and throughput
  • Challenges: Cross-shard operations, rebalancing
2. Hierarchical Masters:
  • Root master coordinates multiple sub-masters
  • Each sub-master handles subset of chunkservers
  • Root handles namespace, sub-masters handle chunks
  • Benefits: Scales chunk management
  • Challenges: Two-level hierarchy complexity
3. Client-Side Metadata Caching:
  • Aggressive client caching with long timeouts
  • Lease-based cache consistency
  • Master only for cache misses
  • Benefits: Reduces master load dramatically
  • Challenges: Consistency protocol more complex
4. Metadata Distribution:
  • Distribute master state using consensus (Paxos/Raft)
  • Read from any replica, write to leader
  • Benefits: High availability, read scalability
  • Challenges: Write latency, consistency overhead
Real-world Evolution:
  • Colossus (GFS successor) uses metadata sharding
  • HDFS Federation uses multiple namenodes
  • Both prove that single master can be overcome while maintaining simplicity where possible

Stale Replica Detection (Version Numbers)

In a distributed system, some replicas may miss updates (e.g., if a chunkserver crashes during a write). GFS uses Chunk Version Numbers to distinguish between up-to-date and stale replicas.

The Versioning Protocol

  1. Lease Granting: Before granting a lease, the master increments the chunk’s version number in its persistent metadata.
  2. Propagation: The master notifies the primary and all secondaries of the new version number.
  3. Persisting: Both the master and the chunkservers record the new version number on their respective persistent disks before the mutation starts.
  4. Stale Check: If a chunkserver was down during the update, it will still have the old version number.

How the Master Uses Versions

  • During Heartbeats: Chunkservers report their (handle, version) pairs. If the master sees a version V<VcurrentV < V_{current}, it knows the replica is stale.
  • Garbage Collection: Stale replicas are immediately scheduled for garbage collection.
  • Client Requests: When a client asks for chunk locations, the master never returns a stale replica, ensuring the client only sees current data.

Key Takeaways

Master Operations Summary:
  1. Namespace Locking: Fine-grained path-based locks enable parallel operations
  2. Leases for Consistency: Time-bounded primary authority avoids distributed consensus
  3. Replica Placement: Rack-aware placement balances reliability and performance
  4. Lazy Garbage Collection: Simple, safe deletion with recovery window
  5. In-Memory Metadata: Fast operations, simple consistency, small memory footprint
  6. Master Replication: Operation log replication ensures durability and fast recovery
  7. Background Processes: GC, re-replication, balancing happen asynchronously
  8. Version Numbers: Detect stale replicas reliably without complex protocols

Up Next

In Chapter 4: Chunkservers & Data Flow, we’ll explore:
  • How chunkservers store and manage chunks
  • Detailed read, write, and record append flows
  • Data integrity mechanisms with checksums
  • Replication pipeline and optimization
  • Handling chunkserver failures
The master orchestrates the system—now we’ll see how chunkservers execute the actual data operations.

Interview Deep-Dive

Strong Answer:When a file is deleted in GFS, the master does not immediately reclaim the chunks. Instead, it renames the file to a hidden name with a deletion timestamp. A background process periodically scans for hidden files older than a configurable threshold (default three days) and removes their metadata. Orphaned chunks (chunks with no file reference) are discovered during regular chunk report exchanges with chunkservers and reclaimed.Lazy deletion is better than immediate deletion for three reasons. First, safety: accidental deletions can be undone within the grace period by simply renaming the hidden file back. This is enormously valuable in production — at Google scale, operator error is a constant risk. Second, simplicity: the garbage collector runs as a single background sweep, which is far simpler than coordinating immediate deletion across three replicas on different chunkservers. If one replica is temporarily unreachable during an immediate delete, you need complex retry logic. With lazy GC, the unreachable chunkserver simply reports the orphaned chunk on its next heartbeat, and the master tells it to delete. Third, batching: the GC can coalesce many deletions into efficient batch operations, reducing the metadata operation rate on the master.The trade-off is storage reclamation latency. Deleted files continue to consume disk space for up to three days. For clusters with tight storage budgets, this delay can be problematic. GFS allows tuning the grace period down for specific namespaces.Follow-up: How does this compare to garbage collection in modern object stores like S3?S3 uses a similar lazy approach internally, though the semantics exposed to users are different. When you delete an S3 object, the metadata is removed immediately from the API perspective, but the underlying storage blocks may not be reclaimed instantly. S3 also offers versioning, which is conceptually similar to GFS hidden-file grace period — deleted objects are retained as non-current versions until a lifecycle policy removes them. The key insight that carries across both systems is that in distributed storage, lazy reclamation is almost always the right default because it decouples the fast path (metadata update) from the slow path (physical storage reclamation).
Strong Answer:In a traditional POSIX file system, creating a file requires locking the parent directory inode. If you have 1,000 MapReduce tasks all writing output files to the same directory simultaneously, they serialize on that directory lock. This creates a bottleneck that limits parallelism.GFS uses a flat namespace with per-path read-write locks. To create /data/logs/file1, the master acquires read locks on /data and /data/logs (to prevent them from being deleted), and a write lock only on /data/logs/file1 itself. Creating /data/logs/file2 simultaneously requires read locks on the same parents (which are shared with file1) and a write lock on /data/logs/file2. Since the write locks are on different paths, both operations proceed in parallel.This enables massive concurrency. In a MapReduce job with 10,000 map tasks writing output to the same directory, all 10,000 file creations can proceed concurrently because they only contend on shared read locks for the parent paths. Deadlocks are prevented by always acquiring locks in lexicographic order of the full pathname.Follow-up: Can you think of a scenario where this locking scheme could cause problems?Yes — directory-level operations like rename or snapshot. If you snapshot /data/logs, you need a write lock on /data/logs to prevent any modifications during the snapshot. This blocks all concurrent file creations in that directory. In practice, GFS handles this by making snapshots a rare, operator-initiated operation, not something that happens during normal workload processing. The design is optimized for the common case (file creation and deletion) at the expense of rare operations (snapshots, directory renames). This is a classic engineering trade-off: optimize for the 99% case and accept higher cost for the 1% case.
Strong Answer:GFS places the first replica on the same machine as the writer (or a machine with below-average disk utilization if the writer is not a chunkserver). The second replica goes on a different rack. The third replica goes on a different machine in the same rack as the second. This strategy balances three concerns.Fault tolerance: by placing replicas across at least two racks, GFS survives an entire rack failure (power outage, top-of-rack switch failure) with at least one surviving replica. This is critical because rack-level failures are correlated — a single switch failure takes out every machine on the rack.Write performance: the pipelined replication sends data from the writer to the nearest replica first, which forwards it to the next nearest. Having two replicas on the same rack means the second-to-third hop is a fast intra-rack transfer rather than a slower cross-rack transfer. This reduces the total write latency.Read performance: for read-heavy files, having replicas on two different racks means clients in either rack can read locally, distributing read load across the network.The trade-off is that with two replicas on one rack, a rack failure leaves you with only one surviving replica. At that point, re-replication becomes urgent and is prioritized above all other chunk operations. The master tracks under-replicated chunks and prioritizes them by severity (1 replica remaining is more urgent than 2 replicas remaining).Follow-up: How would you change this placement strategy for a cluster spanning multiple data centers?I would add a fourth replica in a different data center for disaster recovery. The cross-datacenter replica would be asynchronously replicated (to avoid the latency penalty of synchronous cross-WAN writes) and used only for reads in the remote datacenter or for recovery after a datacenter-level failure. This is essentially what Google did when evolving toward Colossus and what modern systems like Spanner do with their multi-region configurations. The key design question is whether the cross-datacenter replica participates in the write quorum (stronger consistency, higher latency) or is replicated asynchronously (lower latency, risk of data loss during datacenter failure).