HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-server / src / main / java / org / apache / hadoop / hbase / quotas / TimeBasedLimiter.java
blob6b5349fc295b96fb06f0ee8bae0765bcfc3cf7f5
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;
22 import org.apache.hadoop.conf.Configuration;
23 import org.apache.hadoop.hbase.HBaseConfiguration;
24 import org.apache.yetus.audience.InterfaceAudience;
25 import org.apache.yetus.audience.InterfaceStability;
26 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
27 import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Throttle;
28 import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.TimedQuota;
30 /**
31 * Simple time based limiter that checks the quota Throttle
33 @InterfaceAudience.Private
34 @InterfaceStability.Evolving
35 public class TimeBasedLimiter implements QuotaLimiter {
36 private static final Configuration conf = HBaseConfiguration.create();
37 private RateLimiter reqsLimiter = null;
38 private RateLimiter reqSizeLimiter = null;
39 private RateLimiter writeReqsLimiter = null;
40 private RateLimiter writeSizeLimiter = null;
41 private RateLimiter readReqsLimiter = null;
42 private RateLimiter readSizeLimiter = null;
43 private RateLimiter reqCapacityUnitLimiter = null;
44 private RateLimiter writeCapacityUnitLimiter = null;
45 private RateLimiter readCapacityUnitLimiter = null;
47 private TimeBasedLimiter() {
48 if (FixedIntervalRateLimiter.class.getName().equals(
49 conf.getClass(RateLimiter.QUOTA_RATE_LIMITER_CONF_KEY, AverageIntervalRateLimiter.class)
50 .getName())) {
51 reqsLimiter = new FixedIntervalRateLimiter();
52 reqSizeLimiter = new FixedIntervalRateLimiter();
53 writeReqsLimiter = new FixedIntervalRateLimiter();
54 writeSizeLimiter = new FixedIntervalRateLimiter();
55 readReqsLimiter = new FixedIntervalRateLimiter();
56 readSizeLimiter = new FixedIntervalRateLimiter();
57 reqCapacityUnitLimiter = new FixedIntervalRateLimiter();
58 writeCapacityUnitLimiter = new FixedIntervalRateLimiter();
59 readCapacityUnitLimiter = new FixedIntervalRateLimiter();
60 } else {
61 reqsLimiter = new AverageIntervalRateLimiter();
62 reqSizeLimiter = new AverageIntervalRateLimiter();
63 writeReqsLimiter = new AverageIntervalRateLimiter();
64 writeSizeLimiter = new AverageIntervalRateLimiter();
65 readReqsLimiter = new AverageIntervalRateLimiter();
66 readSizeLimiter = new AverageIntervalRateLimiter();
67 reqCapacityUnitLimiter = new AverageIntervalRateLimiter();
68 writeCapacityUnitLimiter = new AverageIntervalRateLimiter();
69 readCapacityUnitLimiter = new AverageIntervalRateLimiter();
73 static QuotaLimiter fromThrottle(final Throttle throttle) {
74 TimeBasedLimiter limiter = new TimeBasedLimiter();
75 boolean isBypass = true;
76 if (throttle.hasReqNum()) {
77 setFromTimedQuota(limiter.reqsLimiter, throttle.getReqNum());
78 isBypass = false;
81 if (throttle.hasReqSize()) {
82 setFromTimedQuota(limiter.reqSizeLimiter, throttle.getReqSize());
83 isBypass = false;
86 if (throttle.hasWriteNum()) {
87 setFromTimedQuota(limiter.writeReqsLimiter, throttle.getWriteNum());
88 isBypass = false;
91 if (throttle.hasWriteSize()) {
92 setFromTimedQuota(limiter.writeSizeLimiter, throttle.getWriteSize());
93 isBypass = false;
96 if (throttle.hasReadNum()) {
97 setFromTimedQuota(limiter.readReqsLimiter, throttle.getReadNum());
98 isBypass = false;
101 if (throttle.hasReadSize()) {
102 setFromTimedQuota(limiter.readSizeLimiter, throttle.getReadSize());
103 isBypass = false;
106 if (throttle.hasReqCapacityUnit()) {
107 setFromTimedQuota(limiter.reqCapacityUnitLimiter, throttle.getReqCapacityUnit());
108 isBypass = false;
111 if (throttle.hasWriteCapacityUnit()) {
112 setFromTimedQuota(limiter.writeCapacityUnitLimiter, throttle.getWriteCapacityUnit());
113 isBypass = false;
116 if (throttle.hasReadCapacityUnit()) {
117 setFromTimedQuota(limiter.readCapacityUnitLimiter, throttle.getReadCapacityUnit());
118 isBypass = false;
120 return isBypass ? NoopQuotaLimiter.get() : limiter;
123 public void update(final TimeBasedLimiter other) {
124 reqsLimiter.update(other.reqsLimiter);
125 reqSizeLimiter.update(other.reqSizeLimiter);
126 writeReqsLimiter.update(other.writeReqsLimiter);
127 writeSizeLimiter.update(other.writeSizeLimiter);
128 readReqsLimiter.update(other.readReqsLimiter);
129 readSizeLimiter.update(other.readSizeLimiter);
130 reqCapacityUnitLimiter.update(other.reqCapacityUnitLimiter);
131 writeCapacityUnitLimiter.update(other.writeCapacityUnitLimiter);
132 readCapacityUnitLimiter.update(other.readCapacityUnitLimiter);
135 private static void setFromTimedQuota(final RateLimiter limiter, final TimedQuota timedQuota) {
136 limiter.set(timedQuota.getSoftLimit(), ProtobufUtil.toTimeUnit(timedQuota.getTimeUnit()));
139 @Override
140 public void checkQuota(long writeReqs, long estimateWriteSize, long readReqs,
141 long estimateReadSize, long estimateWriteCapacityUnit, long estimateReadCapacityUnit)
142 throws RpcThrottlingException {
143 if (!reqsLimiter.canExecute(writeReqs + readReqs)) {
144 RpcThrottlingException.throwNumRequestsExceeded(reqsLimiter.waitInterval());
146 if (!reqSizeLimiter.canExecute(estimateWriteSize + estimateReadSize)) {
147 RpcThrottlingException.throwRequestSizeExceeded(
148 reqSizeLimiter.waitInterval(estimateWriteSize + estimateReadSize));
150 if (!reqCapacityUnitLimiter.canExecute(estimateWriteCapacityUnit + estimateReadCapacityUnit)) {
151 RpcThrottlingException.throwRequestCapacityUnitExceeded(
152 reqCapacityUnitLimiter.waitInterval(estimateWriteCapacityUnit + estimateReadCapacityUnit));
155 if (estimateWriteSize > 0) {
156 if (!writeReqsLimiter.canExecute(writeReqs)) {
157 RpcThrottlingException.throwNumWriteRequestsExceeded(writeReqsLimiter.waitInterval());
159 if (!writeSizeLimiter.canExecute(estimateWriteSize)) {
160 RpcThrottlingException.throwWriteSizeExceeded(
161 writeSizeLimiter.waitInterval(estimateWriteSize));
163 if (!writeCapacityUnitLimiter.canExecute(estimateWriteCapacityUnit)) {
164 RpcThrottlingException.throwWriteCapacityUnitExceeded(
165 writeCapacityUnitLimiter.waitInterval(estimateWriteCapacityUnit));
169 if (estimateReadSize > 0) {
170 if (!readReqsLimiter.canExecute(readReqs)) {
171 RpcThrottlingException.throwNumReadRequestsExceeded(readReqsLimiter.waitInterval());
173 if (!readSizeLimiter.canExecute(estimateReadSize)) {
174 RpcThrottlingException.throwReadSizeExceeded(
175 readSizeLimiter.waitInterval(estimateReadSize));
177 if (!readCapacityUnitLimiter.canExecute(estimateReadCapacityUnit)) {
178 RpcThrottlingException.throwReadCapacityUnitExceeded(
179 readCapacityUnitLimiter.waitInterval(estimateReadCapacityUnit));
184 @Override
185 public void grabQuota(long writeReqs, long writeSize, long readReqs, long readSize,
186 long writeCapacityUnit, long readCapacityUnit) {
187 assert writeSize != 0 || readSize != 0;
189 reqsLimiter.consume(writeReqs + readReqs);
190 reqSizeLimiter.consume(writeSize + readSize);
192 if (writeSize > 0) {
193 writeReqsLimiter.consume(writeReqs);
194 writeSizeLimiter.consume(writeSize);
196 if (readSize > 0) {
197 readReqsLimiter.consume(readReqs);
198 readSizeLimiter.consume(readSize);
200 if (writeCapacityUnit > 0) {
201 reqCapacityUnitLimiter.consume(writeCapacityUnit);
202 writeCapacityUnitLimiter.consume(writeCapacityUnit);
204 if (readCapacityUnit > 0) {
205 reqCapacityUnitLimiter.consume(readCapacityUnit);
206 readCapacityUnitLimiter.consume(readCapacityUnit);
210 @Override
211 public void consumeWrite(final long size, long capacityUnit) {
212 reqSizeLimiter.consume(size);
213 writeSizeLimiter.consume(size);
214 reqCapacityUnitLimiter.consume(capacityUnit);
215 writeCapacityUnitLimiter.consume(capacityUnit);
218 @Override
219 public void consumeRead(final long size, long capacityUnit) {
220 reqSizeLimiter.consume(size);
221 readSizeLimiter.consume(size);
222 reqCapacityUnitLimiter.consume(capacityUnit);
223 readCapacityUnitLimiter.consume(capacityUnit);
226 @Override
227 public boolean isBypass() {
228 return false;
231 @Override
232 public long getWriteAvailable() {
233 return writeSizeLimiter.getAvailable();
236 @Override
237 public long getReadAvailable() {
238 return readSizeLimiter.getAvailable();
241 @Override
242 public String toString() {
243 StringBuilder builder = new StringBuilder();
244 builder.append("TimeBasedLimiter(");
245 if (!reqsLimiter.isBypass()) {
246 builder.append("reqs=" + reqsLimiter);
248 if (!reqSizeLimiter.isBypass()) {
249 builder.append(" resSize=" + reqSizeLimiter);
251 if (!writeReqsLimiter.isBypass()) {
252 builder.append(" writeReqs=" + writeReqsLimiter);
254 if (!writeSizeLimiter.isBypass()) {
255 builder.append(" writeSize=" + writeSizeLimiter);
257 if (!readReqsLimiter.isBypass()) {
258 builder.append(" readReqs=" + readReqsLimiter);
260 if (!readSizeLimiter.isBypass()) {
261 builder.append(" readSize=" + readSizeLimiter);
263 if (!reqCapacityUnitLimiter.isBypass()) {
264 builder.append(" reqCapacityUnit=" + reqCapacityUnitLimiter);
266 if (!writeCapacityUnitLimiter.isBypass()) {
267 builder.append(" writeCapacityUnit=" + writeCapacityUnitLimiter);
269 if (!readCapacityUnitLimiter.isBypass()) {
270 builder.append(" readCapacityUnit=" + readCapacityUnitLimiter);
272 builder.append(')');
273 return builder.toString();