001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.quotas; 019 020import java.util.List; 021import org.apache.hadoop.hbase.Cell; 022import org.apache.hadoop.hbase.client.Mutation; 023import org.apache.hadoop.hbase.client.Result; 024import org.apache.yetus.audience.InterfaceAudience; 025import org.apache.yetus.audience.InterfaceStability; 026 027import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 028 029/** 030 * Interface that allows to check the quota available for an operation. 031 */ 032@InterfaceAudience.Private 033@InterfaceStability.Evolving 034public interface OperationQuota { 035 public enum OperationType { 036 MUTATE, 037 GET, 038 SCAN, 039 CHECK_AND_MUTATE 040 } 041 042 /** 043 * If false, the default, then IO based throttles will consume read availability based on the 044 * block bytes scanned by the given request. If true then IO based throttles will use result size 045 * rather than block bytes scanned. Using block bytes scanned should be preferable to using result 046 * size, because otherwise access patterns like heavily filtered scans may be able to produce a 047 * significant and effectively un-throttled workload. 048 */ 049 String USE_RESULT_SIZE_BYTES = "hbase.quota.use.result.size.bytes"; 050 boolean USE_RESULT_SIZE_BYTES_DEFAULT = false; 051 052 /** 053 * Checks if it is possible to execute the specified operation. The quota will be estimated based 054 * on the number of operations to perform and the average size accumulated during time. 055 * @param numWrites number of write operation that will be performed 056 * @param numReads number of small-read operation that will be performed 057 * @throws RpcThrottlingException if the operation cannot be performed because RPC quota is 058 * exceeded. 059 */ 060 void checkBatchQuota(int numWrites, int numReads) throws RpcThrottlingException; 061 062 /** 063 * Checks if it is possible to execute the scan. The quota will be estimated based on the 064 * composition of the scan. 065 * @param scanRequest the given scan operation 066 * @param maxScannerResultSize the maximum bytes to be returned by the scanner 067 * @param maxBlockBytesScanned the maximum bytes scanned in a single RPC call by the 068 * scanner 069 * @param prevBlockBytesScannedDifference the difference between BBS of the previous two next 070 * calls 071 * @throws RpcThrottlingException if the operation cannot be performed because RPC quota is 072 * exceeded. 073 */ 074 void checkScanQuota(ClientProtos.ScanRequest scanRequest, long maxScannerResultSize, 075 long maxBlockBytesScanned, long prevBlockBytesScannedDifference) throws RpcThrottlingException; 076 077 /** Cleanup method on operation completion */ 078 void close(); 079 080 /** 081 * Add a get result. This will be used to calculate the exact quota and have a better short-read 082 * average size for the next time. 083 */ 084 void addGetResult(Result result); 085 086 /** 087 * Add a scan result. This will be used to calculate the exact quota and have a better long-read 088 * average size for the next time. 089 */ 090 void addScanResult(List<Result> results); 091 092 /** 093 * Add a scan result in the form of cells. This will be used to calculate the exact quota and have 094 * a better long-read average size for the next time. 095 */ 096 void addScanResultCells(List<Cell> cells); 097 098 /** 099 * Add a mutation result. This will be used to calculate the exact quota and have a better 100 * mutation average size for the next time. 101 */ 102 void addMutation(Mutation mutation); 103 104 /** Returns the number of bytes available to read to avoid exceeding the quota */ 105 long getReadAvailable(); 106 107 /** Returns the number of bytes consumed from the quota by the operation */ 108 long getReadConsumed(); 109 110 /** 111 * Returns the maximum result size to be returned by the given operation. This is the greater of 112 * two numbers: the bytes available, or the bytes already consumed 113 */ 114 default long getMaxResultSize() { 115 return Math.max(getReadAvailable(), getReadConsumed()); 116 } 117}