Skip to content

HBASE-30348 Throttles should work for system tables (excluding quotas, meta, namespace) - #8774

Draft
rmdmattingly wants to merge 1 commit into
apache:masterfrom
HubSpot:HBASE-30348-v2-best-effort
Draft

rmdmattingly wants to merge 1 commit into
apache:masterfrom
HubSpot:HBASE-30348-v2-best-effort

Conversation

@rmdmattingly

Copy link
Copy Markdown
Contributor

https://issues.apache.org/jira/browse/HBASE-30348

Draft to get CI on the direction discussed in #8617: throttling is best effort, so no request ever waits for the quota cache, and a request that arrives before quota data is available is simply not throttled.

Changes from #8617

The initial quota cache load never blocks a request. #8617 bounded the wait with a timeout, but every request still serialized on the initializer lock and waited out that timeout while the master was initializing. Now the first lookup starts the load in the background and returns default quota state immediately. That removes the deadlock regardless of which tables are read during master initialization, so the timeout config is gone.

The cache is only ready once a load fully succeeds. Failed loads are retried every second. Otherwise a load that ran before hbase:quota existed, which is the branch-2 startup case, would mark the cache ready with nothing in it and leave quotas unenforced until the next periodic refresh, 12 hours by default.

Quota factors for newly limited tables. Making the load asynchronous exposed an existing bug that TestClusterScopeQuotaThrottle had only been passing because of the extra synchronous load. Cluster scope table quotas are converted to machine scope using factors computed from the quotas cached before the fetch, so a table that just got a quota was given factor 1, the full cluster limit on every RegionServer, until the next refresh. A refresh that finds tables with new quotas now recomputes factors and fetches again. Per-user table quotas now get factors too; previously only tables with a table quota did.

The hbase:meta, hbase:quota and hbase:namespace exemptions are unchanged here. With the load no longer blocking, they are no longer what prevents the startup deadlock, so whether to keep them is a separate question.

Testing

TestQuotaCache2 adds two tests: a lookup returns within a bounded time while the hbase:quota read hangs, and a failed initial load is retried until it succeeds. TestQuotaCache now waits for the initial load before asserting.

Locally on master with JDK 17, org.apache.hadoop.hbase.quotas: 303 tests, 0 failures, 0 errors, 18 skipped (TestQuotaThrottle is disabled by HBASE-27243).

🤖 Generated with Claude Code

…, meta, namespace)

System tables outside the hbase namespace, such as the backup tables, can
generate a lot of IO but could never be throttled. Only hbase:meta,
hbase:quota and hbase:namespace remain exempt, because they are read while
the master is still initializing.

Throttling is now best effort: no request waits for the quota cache to load.
Until a load fully succeeds, requests get default quota state, which does not
throttle, and failed loads are retried. Waiting on the load inline is what
deadlocked master startup on branch-2 in the first attempt at this change,
since the load needs hbase:quota and the master.

Each refresh also reloads once more when it finds tables with new quotas.
Cluster scope table quotas are converted to machine scope using factors
computed before the fetch, so a newly limited table previously got the full
cluster limit on every RegionServer until the next refresh. Per-user table
quotas now get factors as well; before, only tables with a table quota did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant