Why architecture matters here
Secondary indexes on HBase are subtle. Sync indexes ensure consistency at the cost of write latency. Async indexes are cheap but may lag. Rebuild is expensive but sometimes necessary.
The architecture matters because you must choose sync vs async, global vs local, and manage lifecycle intentionally.
The architecture: every piece explained
The top strip is the mechanism. Write to base table triggers coprocessor hook that maintains the Index table (a separate HBase table indexed on the chosen columns). Phoenix optimizer chooses index at query time.
The middle row is choices. Sync vs async: sync updates the index in the same write path — strong consistency, higher latency; async lags but is cheaper. Global vs local: global index is a cluster-wide table (good for equality scans); local is co-located with the base region (good for range scans). Rebuild + repair restores consistency after failure. Covered indexes include additional columns so queries can be answered from the index alone.
The lower rows are ops. TTL + salting must match base table. Observability tracks index hit rate + freshness. Ops handles evolution, compaction, and monitoring.
End-to-end flow
End-to-end: a users table indexed on email via global covered index containing name. Write inserts a user; coprocessor writes to the index table in the same transaction (sync). Query "SELECT name FROM users WHERE email = 'x@y.com'" uses the index; single row read; base table not touched. Async index example: activity log with a lagging analytics index — writes fast; queries can tolerate seconds of lag. Rebuild after a coprocessor bug fixes drift.