Why it matters

Read latency debugging in HBase is impossible without understanding this path. Slow reads can be caused by cold block cache, oversized HFile counts (compaction lag), disabled bloom filters, or slow HDFS. Knowing which stage to blame is what makes ops fast.

Read path knowledge also drives configuration: block cache size, bloom filter tuning, and compaction schedule are all read-path optimizations.

Advertisement

The architecture

Client issues get(row=X) via the Java client library. The client consults its cached meta table to find which RegionServer owns the row's region and sends the get RPC directly.

RegionServer receives the get, finds the target region, and creates a StoreScanner for each column family. Each StoreScanner in turn creates one scanner per storage layer: memstore, and one per HFile.

HBase read path — get(row=X)MemStorecheck latest writesBlock cachehot HFile blocksHFiles on HDFScold fallbackBloom filters skip HFiles proven empty; scanner merges results from all sources
Read path: memstore + block cache + HFiles, merged by store scanner with bloom filter skips.
Advertisement

How it works end to end

The store scanner checks memstore first for the target row. If the row exists in memstore with a live version, that value is included in the merged result.

For each HFile, the scanner first consults the bloom filter (if enabled). If the bloom filter says the row is definitely absent, the HFile is skipped entirely — no HDFS I/O. Otherwise the scanner consults the HFile index to find the block containing the row.

The block is loaded either from block cache (hit, fast) or from HDFS (miss, slower). Once loaded, the scanner iterates within the block to find the target row and any matching cells.

Results from memstore and all HFiles are merged by the store scanner, deduplicated (same row+column+timestamp wins latest write), and returned to the client. The client can iterate the results or apply local processing.