Why architecture matters here

The architecture matters because it targets two specific, common pain points of the single-owner model without throwing away the model's simplicity. The first is read availability during failure. In vanilla HBase, when a RegionServer dies, its regions are offline until the master reassigns them and the new server replays their WALs — a mean-time-to-recovery that, for a large server hosting many regions, can be minutes. For a serving path behind a user request, minutes of unavailability for a slice of the keyspace is an outage. With a secondary replica on a different server, reads for that region can be served — stale but available — from the secondary the instant the primary is gone, collapsing the read-availability gap from minutes to essentially zero for clients willing to accept timeline consistency.

The second pain point is tail read latency. Even when nothing has failed, a single primary occasionally stalls — a GC pause, a compaction, a slow disk — and every read routed to it waits. Region replicas enable hedged reads: the client can send the read to the primary and, if no answer arrives within a short threshold, also send it to a secondary and take whichever responds first. Because it is unlikely that both the primary and a secondary stall simultaneously, hedging dramatically cuts the p99 and p999 latency that a single server's occasional hiccups would otherwise impose.

Crucially, the architecture preserves optionality per read. The default remains STRONG consistency through the primary, so nothing about existing correctness-sensitive reads changes. Timeline consistency is something a client requests for a specific read when it knows staleness is acceptable — a product listing, a cached-style lookup, a dashboard. This per-request choice is what makes the feature safe to enable: it does not weaken the guarantees of code that did not ask for weaker guarantees, and it lets a single table serve both strong reads and cheap available reads depending on the caller's needs.

It is equally important to understand what region replicas are not. They do not scale writes — all writes still go through the single primary, so a write-hot region gets no relief. They do not provide their own durability — the durable copies are the HDFS-replicated HFiles, and a secondary's in-memory state is disposable. And they are not a replacement for cross-cluster replication for disaster recovery, since all replicas live in the same cluster. The feature is a precise instrument for read availability and read tail latency on read-heavy, staleness-tolerant workloads, and using it for anything else disappoints.

Advertisement

The architecture: every piece explained

Replicas and replica IDs are the core abstraction. A region is configured with a replication count via REGION_REPLICATION on the table. Replica id 0 is the primary — the only one that accepts writes and the one that serves STRONG reads. Replicas id 1, 2, ... are read-only secondaries. The master's balancer treats them as distinct assignable units and, guided by a replica-aware placement policy, tries to host a region's replicas on different RegionServers and racks so a single failure cannot take out both primary and secondary.

Shared HFiles on HDFS are the persisted substrate all replicas read. When the primary flushes its MemStore or runs a compaction, it writes HFiles to HDFS; secondaries do not write data files at all. They open and read the same HFiles the primary produced. This is why a replica costs almost no extra disk: HDFS already stores the data with its own replication factor, and the region replicas are additional readers of that one persisted copy, not additional copies.

Asynchronous WAL replication to secondaries is what keeps them reasonably current between flushes. The most recent edits live only in the primary's MemStore and its WAL, not yet in any HFile. An internal replication endpoint ships those edits from the primary to each secondary, which replays them into its own MemStore. This stream is asynchronous and best-effort, which is precisely the source of staleness: a secondary is caught up to the HFiles instantly (they are shared) but lags the primary by however far behind the replication stream is on the in-memory edits.

The TIMELINE consistency contract defines what a secondary read promises. A client sets Consistency.TIMELINE on a Get or Scan. HBase first tries the primary; if it is slow or unavailable (per a configurable delay), it also asks a secondary and returns whichever answers, marking the result stale if it came from a secondary. The guarantee is that reads observe writes in the order they were applied (no going backwards in time) but may not observe the very latest write — a monotonic, possibly-lagging view rather than a strictly-current one. Hedged reads are the latency-optimizing use of the same machinery. And memory is the real cost center: each secondary maintains its own MemStore of replayed edits and its own block-cache footprint, so a replication factor of 3 roughly triples a region's memory demand across the cluster even though its disk demand barely moves. These pieces — replica IDs, shared HFiles, async WAL replication, the TIMELINE contract, hedged reads, and the memory cost — are the complete architecture.

Region replicas — read-only standby copies of a region for low-latency, high-availability readsone primary serves writes + strong reads; secondaries serve stale, timeline-consistent readsPrimary replicareplica_id 0, read+writeSecondary Areplica_id 1, read-onlySecondary Breplica_id 2, read-onlyShared HFiles (HDFS)one copy of persisted dataAsync WAL replicationregion-replica endpointClientTIMELINE consistencyPrimary MemStoreunflushed editsSecondary MemStorereplayed, may lagHedged readprimary + backup, first winsOps — placement across RS/racks, extra memory for replica MemStores, staleness monitoringreplicatereplicateread HFilesship editsintoreplayroutehedgegovern
Each region can have several replicas: one primary (replica_id 0) that serves writes and strong reads, and read-only secondaries. Secondaries read the same persisted HFiles from HDFS and receive the primary's unflushed edits asynchronously via WAL replication into their own MemStore, so they lag slightly. A TIMELINE-consistency client may read from a secondary — or hedge across primary and secondary — accepting possibly-stale data for lower latency and availability.
Advertisement

End-to-end flow

Trace a default read first. A client issues a Get with the default Consistency.STRONG. HBase routes it to the primary replica of the region owning that row. The primary merges what it finds in its MemStore (recent writes) with what it reads from the shared HFiles (older, flushed data) and returns the result. Because the primary is the sole writer, this result is guaranteed to reflect every write that has been acknowledged — the strong-consistency contract HBase has always offered, unchanged.

Now a TIMELINE read. The client issues a Get with Consistency.TIMELINE. HBase sends it to the primary but starts a timer; if the primary responds within the threshold, that fresh answer is returned and marked not-stale. If the primary is slow — GC pause, hot server — or unreachable, HBase also dispatches the read to a secondary replica. The secondary answers from the same shared HFiles plus whatever edits its replication stream has replayed into its MemStore. Whichever replica responds first wins; if the winner is a secondary, the result carries a stale=true flag so the application knows it may be missing the newest writes. The client sees a fast answer even though the primary hiccupped.

Consider the failure case explicitly. The RegionServer hosting the primary crashes. For STRONG reads, the region is unavailable until the master reassigns it and replays its WAL — the familiar gap. But a client reading with TIMELINE consistency immediately gets answers from a secondary: the secondary already has the shared HFiles open and has replayed most recent edits, so it can serve reads (marked stale) throughout the primary's outage. When the primary is reassigned and recovers, its reads resume and stale reads stop. Read availability was preserved across a server failure, at the cost of a bounded window of possible staleness.

Follow the write and replication path that keeps secondaries current. A write lands on the primary, which appends to its WAL and puts the edit in its MemStore, acknowledging the client — secondaries are not on the write's critical path, so writes are as fast as ever. Asynchronously, the region-replica replication endpoint ships that edit to each secondary, which replays it into its MemStore; now a TIMELINE read from that secondary would see the write. Periodically the primary flushes its MemStore to an HFile on HDFS; the secondaries, reading the same HDFS files, pick up the flushed data and can drop the corresponding replayed edits from their own MemStores. The steady state is: HFiles shared and always consistent, in-memory edits flowing primary→secondary with a small lag, and clients choosing per-read between the primary's freshness and a secondary's availability and speed.