HBASE-26286: Add support for specifying store file tracker when restoring or cloning...
[hbase.git] / hbase-server / src / main / java / org / apache / hadoop / hbase / quotas / ExceedOperationQuota.java
blob6745d3eeb15018f96986c8fb4cbf6dca14443a71
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package org.apache.hadoop.hbase.quotas;
21 import org.apache.hadoop.conf.Configuration;
22 import org.apache.yetus.audience.InterfaceAudience;
23 import org.apache.yetus.audience.InterfaceStability;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Internal class used to check and consume quota if exceed throttle quota is enabled. Exceed
29 * throttle quota means, user can over consume user/namespace/table quota if region server has
30 * additional available quota because other users don't consume at the same time.
32 * There are some limits when enable exceed throttle quota:
33 * 1. Must set at least one read and one write region server throttle quota;
34 * 2. All region server throttle quotas must be in seconds time unit. Because once previous requests
35 * exceed their quota and consume region server quota, quota in other time units may be refilled in
36 * a long time, this may affect later requests.
38 @InterfaceAudience.Private
39 @InterfaceStability.Evolving
40 public class ExceedOperationQuota extends DefaultOperationQuota {
41 private static final Logger LOG = LoggerFactory.getLogger(ExceedOperationQuota.class);
42 private QuotaLimiter regionServerLimiter;
44 public ExceedOperationQuota(final Configuration conf, QuotaLimiter regionServerLimiter,
45 final QuotaLimiter... limiters) {
46 super(conf, limiters);
47 this.regionServerLimiter = regionServerLimiter;
50 @Override
51 public void checkQuota(int numWrites, int numReads, int numScans) throws RpcThrottlingException {
52 if (regionServerLimiter.isBypass()) {
53 // If region server limiter is bypass, which means no region server quota is set, check and
54 // throttle by all other quotas. In this condition, exceed throttle quota will not work.
55 LOG.warn("Exceed throttle quota is enabled but no region server quotas found");
56 super.checkQuota(numWrites, numReads, numScans);
57 } else {
58 // 1. Update estimate quota which will be consumed
59 updateEstimateConsumeQuota(numWrites, numReads, numScans);
60 // 2. Check if region server limiter is enough. If not, throw RpcThrottlingException.
61 regionServerLimiter.checkQuota(numWrites, writeConsumed, numReads + numScans, readConsumed,
62 writeCapacityUnitConsumed, readCapacityUnitConsumed);
63 // 3. Check if other limiters are enough. If not, exceed other limiters because region server
64 // limiter is enough.
65 boolean exceed = false;
66 try {
67 super.checkQuota(numWrites, numReads, numScans);
68 } catch (RpcThrottlingException e) {
69 exceed = true;
70 if (LOG.isDebugEnabled()) {
71 LOG.debug("Read/Write requests num exceeds quota: writes:{} reads:{} scan:{}, "
72 + "try use region server quota",
73 numWrites, numReads, numScans);
76 // 4. Region server limiter is enough and grab estimated consume quota.
77 readAvailable = Math.max(readAvailable, regionServerLimiter.getReadAvailable());
78 regionServerLimiter.grabQuota(numWrites, writeConsumed, numReads + numScans, readConsumed,
79 writeCapacityUnitConsumed, writeCapacityUnitConsumed);
80 if (exceed) {
81 // 5. Other quota limiter is exceeded and has not been grabbed (because throw
82 // RpcThrottlingException in Step 3), so grab it.
83 for (final QuotaLimiter limiter : limiters) {
84 limiter.grabQuota(numWrites, writeConsumed, numReads + numScans, readConsumed,
85 writeCapacityUnitConsumed, writeCapacityUnitConsumed);
91 @Override
92 public void close() {
93 super.close();
94 if (writeDiff != 0) {
95 regionServerLimiter.consumeWrite(writeDiff, writeCapacityUnitDiff);
97 if (readDiff != 0) {
98 regionServerLimiter.consumeRead(readDiff, readCapacityUnitDiff);